├── .github ├── .codecov.yml ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── android-build.yml │ ├── coverage.yml │ ├── ios-build.yml │ ├── linux-build.yml │ ├── macos-build.yml │ ├── msys2-build.yml │ ├── wasm-build.yml │ └── windows-build.yml ├── .gitignore ├── LICENSE ├── README.md ├── bin └── resources │ ├── Shader.glsl.binding.json │ ├── Shader.nzsl │ └── modules │ ├── Archive │ ├── InstanceData.nzslb │ ├── LightData.nzslb │ ├── SkeletalData.nzslb │ ├── SkinningData.nzslb │ └── ViewerData.nzslb │ ├── Color.nzsl │ └── Data │ ├── DataStruct.nzsl.original │ ├── DataStruct.nzslb │ └── OutputStruct.nzsl ├── examples ├── sfml-mandelbrot │ ├── main.cpp │ ├── mandelbrot.nzsl │ ├── palette.png │ └── xmake.lua └── xmake.lua ├── include ├── CNZSL │ ├── CNZSL.h │ ├── Config.h │ ├── DebugLevel.h │ ├── FilesystemModuleResolver.h │ ├── GlslWriter.h │ ├── LangWriter.h │ ├── Module.h │ ├── Parser.h │ ├── Serializer.h │ ├── ShaderStageType.h │ ├── SpirvWriter.h │ └── WriterStates.h └── NZSL │ ├── Archive.hpp │ ├── Archive.inl │ ├── Ast │ ├── AstSerializer.hpp │ ├── AstSerializer.inl │ ├── Cloner.hpp │ ├── Cloner.inl │ ├── Compare.hpp │ ├── Compare.inl │ ├── ConstantPropagationVisitor.hpp │ ├── ConstantPropagationVisitor.inl │ ├── ConstantValue.hpp │ ├── ConstantValue.inl │ ├── DependencyCheckerVisitor.hpp │ ├── DependencyCheckerVisitor.inl │ ├── EliminateUnusedPassVisitor.hpp │ ├── EliminateUnusedPassVisitor.inl │ ├── Enums.hpp │ ├── ExportVisitor.hpp │ ├── ExportVisitor.inl │ ├── ExpressionType.hpp │ ├── ExpressionType.inl │ ├── ExpressionValue.hpp │ ├── ExpressionValue.inl │ ├── ExpressionVisitor.hpp │ ├── ExpressionVisitorExcept.hpp │ ├── IndexRemapperVisitor.hpp │ ├── IndexRemapperVisitor.inl │ ├── Module.hpp │ ├── Module.inl │ ├── NodeList.hpp │ ├── Nodes.hpp │ ├── Nodes.inl │ ├── Option.hpp │ ├── Option.inl │ ├── RecursiveVisitor.hpp │ ├── RecursiveVisitor.inl │ ├── ReflectVisitor.hpp │ ├── ReflectVisitor.inl │ ├── SanitizeVisitor.hpp │ ├── SanitizeVisitor.inl │ ├── StatementVisitor.hpp │ ├── StatementVisitorExcept.hpp │ ├── Types.hpp │ ├── Utils.hpp │ └── Utils.inl │ ├── Config.hpp │ ├── Enums.hpp │ ├── FilesystemModuleResolver.hpp │ ├── FilesystemModuleResolver.inl │ ├── GlslWriter.hpp │ ├── GlslWriter.inl │ ├── Lang │ ├── ErrorList.hpp │ ├── Errors.hpp │ ├── Errors.inl │ ├── SourceLocation.hpp │ ├── SourceLocation.inl │ └── TokenList.hpp │ ├── LangWriter.hpp │ ├── LangWriter.inl │ ├── Lexer.hpp │ ├── Lexer.inl │ ├── Math │ ├── FieldOffsets.hpp │ ├── FieldOffsets.inl │ ├── Vector.hpp │ └── Vector.inl │ ├── ModuleResolver.hpp │ ├── ModuleResolver.inl │ ├── Parser.hpp │ ├── Parser.inl │ ├── Serializer.hpp │ ├── Serializer.inl │ ├── ShaderBuilder.hpp │ ├── ShaderBuilder.inl │ ├── ShaderWriter.hpp │ ├── SpirV │ ├── SpirvAstVisitor.hpp │ ├── SpirvAstVisitor.inl │ ├── SpirvBlock.hpp │ ├── SpirvBlock.inl │ ├── SpirvConstantCache.hpp │ ├── SpirvConstantCache.inl │ ├── SpirvData.hpp │ ├── SpirvDecoder.hpp │ ├── SpirvDecoder.inl │ ├── SpirvExpressionLoad.hpp │ ├── SpirvExpressionLoad.inl │ ├── SpirvExpressionStore.hpp │ ├── SpirvExpressionStore.inl │ ├── SpirvPrinter.hpp │ ├── SpirvPrinter.inl │ ├── SpirvSection.hpp │ ├── SpirvSection.inl │ ├── SpirvSectionBase.hpp │ ├── SpirvSectionBase.inl │ └── SpirvVariable.hpp │ ├── SpirvWriter.hpp │ └── SpirvWriter.inl ├── src ├── CNZSL │ ├── FilesystemModuleResolver.cpp │ ├── GlslWriter.cpp │ ├── LangWriter.cpp │ ├── Module.cpp │ ├── Parser.cpp │ ├── Serializer.cpp │ ├── SpirvWriter.cpp │ ├── Structs │ │ ├── FilesystemModuleResolver.hpp │ │ ├── GlslOutput.hpp │ │ ├── GlslWriter.hpp │ │ ├── GlslWriterParameters.hpp │ │ ├── LangOutput.hpp │ │ ├── LangWriter.hpp │ │ ├── Module.hpp │ │ ├── Serializer.hpp │ │ ├── SpirvOutput.hpp │ │ ├── SpirvWriter.hpp │ │ └── WriterStates.hpp │ └── WriterStates.cpp ├── NZSL │ ├── Archive.cpp │ ├── Ast │ │ ├── AstSerializer.cpp │ │ ├── Cloner.cpp │ │ ├── ConstantPropagationVisitor.cpp │ │ ├── ConstantPropagationVisitor_BinaryArithmetics.cpp │ │ ├── ConstantPropagationVisitor_BinaryComparison.cpp │ │ ├── ConstantValue.cpp │ │ ├── DependencyCheckerVisitor.cpp │ │ ├── EliminateUnusedPassVisitor.cpp │ │ ├── ExportVisitor.cpp │ │ ├── ExpressionType.cpp │ │ ├── ExpressionVisitor.cpp │ │ ├── ExpressionVisitorExcept.cpp │ │ ├── IndexRemapperVisitor.cpp │ │ ├── Nodes.cpp │ │ ├── RecursiveVisitor.cpp │ │ ├── ReflectVisitor.cpp │ │ ├── SanitizeVisitor.cpp │ │ ├── StatementVisitor.cpp │ │ ├── StatementVisitorExcept.cpp │ │ └── Utils.cpp │ ├── FilesystemModuleResolver.cpp │ ├── GlslWriter.cpp │ ├── Lang │ │ ├── Errors.cpp │ │ └── LangData.hpp │ ├── LangWriter.cpp │ ├── Lexer.cpp │ ├── ModuleResolver.cpp │ ├── Parser.cpp │ ├── Serializer.cpp │ ├── ShaderWriter.cpp │ ├── SpirV │ │ ├── SpirvAstVisitor.cpp │ │ ├── SpirvConstantCache.cpp │ │ ├── SpirvData.cpp │ │ ├── SpirvDecoder.cpp │ │ ├── SpirvExpressionLoad.cpp │ │ ├── SpirvExpressionStore.cpp │ │ ├── SpirvGenData.hpp │ │ ├── SpirvPrinter.cpp │ │ └── SpirvSectionBase.cpp │ └── SpirvWriter.cpp ├── ShaderArchiver │ ├── Archiver.cpp │ ├── Archiver.hpp │ ├── Archiver.inl │ └── main.cpp └── ShaderCompiler │ ├── Compiler.cpp │ ├── Compiler.hpp │ ├── Compiler.inl │ └── main.cpp ├── tests ├── src │ ├── Tests │ │ ├── AccessMemberTests.cpp │ │ ├── AliasTests.cpp │ │ ├── ArithmeticTests.cpp │ │ ├── ArrayTests.cpp │ │ ├── BranchTests.cpp │ │ ├── BuiltinAttributeTests.cpp │ │ ├── CastTests.cpp │ │ ├── ComparisonTests.cpp │ │ ├── ComputeTests.cpp │ │ ├── ConstTests.cpp │ │ ├── DebugInfoTests.cpp │ │ ├── EntryFunctionTests.cpp │ │ ├── ErrorsTests.cpp │ │ ├── ExternalTests.cpp │ │ ├── FieldOffsetsTests.cpp │ │ ├── FilesystemResolverTests.cpp │ │ ├── FunctionsTests.cpp │ │ ├── IdentifierTests.cpp │ │ ├── InputOutputTests.cpp │ │ ├── IntrinsicTests.cpp │ │ ├── LayoutTests.cpp │ │ ├── LexerTests.cpp │ │ ├── LoopTests.cpp │ │ ├── ModuleTests.cpp │ │ ├── NzslaTests.cpp │ │ ├── NzslcTests.cpp │ │ ├── OptimizationTests.cpp │ │ ├── SanitizationsTests.cpp │ │ ├── SerializationsTests.cpp │ │ ├── ShaderUtils.cpp │ │ ├── ShaderUtils.hpp │ │ ├── SwizzleTests.cpp │ │ ├── ToolUtils.cpp │ │ ├── ToolUtils.hpp │ │ └── VectorTests.cpp │ └── main.cpp └── xmake.lua ├── xmake.lua └── xmake ├── actions ├── checkfiles.lua └── spirv.lua └── rules ├── debug_suffix.lua └── wasm_files.lua /.github/.codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: yes 3 | 4 | coverage: 5 | precision: 2 6 | round: down 7 | range: "70...100" 8 | status: 9 | project: 10 | default: 11 | target: auto 12 | threshold: 100% 13 | base: auto 14 | patch: 15 | default: 16 | target: auto 17 | threshold: 100% 18 | base: auto 19 | if_ci_failed: success 20 | informational: true 21 | 22 | parsers: 23 | gcov: 24 | branch_detection: 25 | conditional: yes 26 | loop: yes 27 | method: no 28 | macro: no 29 | 30 | comment: 31 | layout: "reach,diff,flags,files,footer" 32 | behavior: default 33 | require_changes: no 34 | require_head: no 35 | require_base: no 36 | 37 | github_checks: 38 | annotations: true 39 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [SirLynix] 2 | custom: ['https://paypal.me/sirlynixvanfrietjes'] 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/workflows/android-build.yml: -------------------------------------------------------------------------------- 1 | name: Android build 2 | 3 | on: 4 | pull_request: 5 | push: 6 | paths-ignore: 7 | - '.github/workflows/coverage.yml' 8 | - '.github/workflows/ios-build.yml' 9 | - '.github/workflows/linux-build.yml' 10 | - '.github/workflows/macos-build.yml' 11 | - '.github/workflows/msys2-build.yml' 12 | - '.github/workflows/wasm-build.yml' 13 | - '.github/workflows/windows-build.yml' 14 | - '.gitignore' 15 | - 'LICENSE' 16 | - 'CHANGELOG.md' 17 | - 'README.md' 18 | 19 | jobs: 20 | build: 21 | strategy: 22 | matrix: 23 | os: [ubuntu-latest] 24 | arch: [armeabi-v7a, arm64-v8a] 25 | mode: [debug, releasedbg] 26 | ndk_sdkver: ["28"] 27 | 28 | runs-on: ${{ matrix.os }} 29 | if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} 30 | 31 | steps: 32 | - name: Get current date as package key 33 | id: cache_key 34 | run: echo "key=$(date +'%W')" >> $GITHUB_OUTPUT 35 | 36 | - name: Checkout repository 37 | uses: actions/checkout@v4 38 | 39 | # Force xmake to a specific folder (for cache) 40 | - name: Set xmake env 41 | run: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/xmake-global" >> $GITHUB_ENV 42 | 43 | # Install xmake 44 | - name: Setup xmake 45 | uses: xmake-io/github-action-setup-xmake@v1 46 | with: 47 | actions-cache-folder: .xmake-cache-W${{ steps.cache_key.outputs.key }} 48 | 49 | # Setup NDK 50 | - name: Download NDK 51 | run: | 52 | wget -q https://dl.google.com/android/repository/android-ndk-r25c-linux.zip 53 | unzip -q -o ./android-ndk-r25c-linux.zip 54 | 55 | # Update xmake repository (in order to have the file that will be cached) 56 | - name: Update xmake repository 57 | run: xmake repo --update 58 | 59 | # Fetch xmake dephash 60 | - name: Retrieve dependencies hash 61 | id: dephash 62 | run: echo "hash=$(xmake l utils.ci.packageskey)" >> $GITHUB_OUTPUT 63 | shell: bash 64 | 65 | # Cache xmake dependencies 66 | - name: Retrieve cached xmake dependencies 67 | id: restore-depcache 68 | uses: actions/cache/restore@v4 69 | with: 70 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 71 | key: Android-${{ matrix.ndk_sdkver }}-${{ matrix.arch }}-${{ matrix.mode }}-${{ steps.dephash.outputs.hash }}-W${{ steps.cache_key.outputs.key }} 72 | 73 | # Setup compilation mode and install project dependencies 74 | - name: Configure xmake and install dependencies 75 | run: xmake config --plat=android --ndk=`pwd`/android-ndk-r25c --ndk_sdkver=${{ matrix.ndk_sdkver }} --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --tests=y --ccache=n --fs_watcher=n --tests=n --yes 76 | 77 | # Save dependencies 78 | - name: Save cached xmake dependencies 79 | if: ${{ !steps.restore-depcache.outputs.cache-hit }} 80 | uses: actions/cache/save@v4 81 | with: 82 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 83 | key: ${{ steps.restore-depcache.outputs.cache-primary-key }} 84 | 85 | # Build library 86 | - name: Build library 87 | run: xmake 88 | 89 | # Install the result files 90 | - name: Install NazaraUtils 91 | run: xmake install -vo package 92 | 93 | # Upload artifacts 94 | - uses: actions/upload-artifact@v4 95 | with: 96 | name: nazarautils-Android-${{ matrix.ndk_sdkver }}-${{ matrix.arch }}-${{ matrix.mode }} 97 | path: package -------------------------------------------------------------------------------- /.github/workflows/ios-build.yml: -------------------------------------------------------------------------------- 1 | name: iOS build 2 | 3 | on: 4 | pull_request: 5 | push: 6 | paths-ignore: 7 | - '.github/workflows/android-build.yml' 8 | - '.github/workflows/coverage.yml' 9 | - '.github/workflows/linux-build.yml' 10 | - '.github/workflows/macos-build.yml' 11 | - '.github/workflows/msys2-build.yml' 12 | - '.github/workflows/windows-build.yml' 13 | - '.github/workflows/wasm-build.yml' 14 | - '.gitignore' 15 | - 'LICENSE' 16 | - 'CHANGELOG.md' 17 | - 'README.md' 18 | 19 | jobs: 20 | build: 21 | strategy: 22 | matrix: 23 | os: [macOS-latest] 24 | mode: [debug, releasedbg] 25 | 26 | runs-on: ${{ matrix.os }} 27 | if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} 28 | 29 | steps: 30 | - name: Get current date as package key 31 | id: cache_key 32 | run: echo "key=$(date +'%W')" >> $GITHUB_OUTPUT 33 | 34 | - name: Checkout repository 35 | uses: actions/checkout@v4 36 | 37 | # Force xmake to a specific folder (for cache) 38 | - name: Set xmake env 39 | run: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/xmake-global" >> $GITHUB_ENV 40 | 41 | # Install xmake 42 | - name: Setup xmake 43 | uses: xmake-io/github-action-setup-xmake@v1 44 | with: 45 | actions-cache-folder: .xmake-cache-W${{ steps.cache_key.outputs.key }} 46 | 47 | # Update xmake repository (in order to have the file that will be cached) 48 | - name: Update xmake repository 49 | run: xmake repo --update 50 | 51 | # Fetch xmake dephash 52 | - name: Retrieve dependencies hash 53 | id: dephash 54 | run: echo "hash=$(xmake l utils.ci.packageskey)" >> $GITHUB_OUTPUT 55 | 56 | # Cache xmake dependencies 57 | - name: Retrieve cached xmake dependencies 58 | id: restore-depcache 59 | uses: actions/cache/restore@v4 60 | with: 61 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 62 | key: iOS-${{ matrix.mode }}-${{ steps.dephash.outputs.hash }}-W${{ steps.cache_key.outputs.key }} 63 | 64 | # Setup compilation mode and install project dependencies 65 | - name: Configure xmake and install dependencies 66 | run: xmake config --plat=iphoneos --tests=y --mode=${{ matrix.mode }} --ccache=n --tests=n --yes 67 | 68 | # Save dependencies 69 | - name: Save cached xmake dependencies 70 | if: ${{ !steps.restore-depcache.outputs.cache-hit }} 71 | uses: actions/cache/save@v4 72 | with: 73 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 74 | key: ${{ steps.restore-depcache.outputs.cache-primary-key }} 75 | 76 | # Build library and tests 77 | - name: Build library 78 | run: xmake 79 | 80 | # Install the result files 81 | - name: Install NazaraUtils 82 | run: xmake install -vo package 83 | 84 | # Upload artifacts 85 | - uses: actions/upload-artifact@v4 86 | with: 87 | name: nazarautils-iOS-${{ matrix.mode }} 88 | path: package -------------------------------------------------------------------------------- /.github/workflows/macos-build.yml: -------------------------------------------------------------------------------- 1 | name: macOS build 2 | 3 | on: 4 | pull_request: 5 | push: 6 | paths-ignore: 7 | - '.github/workflows/android-build.yml' 8 | - '.github/workflows/coverage.yml' 9 | - '.github/workflows/ios-build.yml' 10 | - '.github/workflows/linux-build.yml' 11 | - '.github/workflows/msys2-build.yml' 12 | - '.github/workflows/wasm-build.yml' 13 | - '.github/workflows/windows-build.yml' 14 | - '.gitignore' 15 | - 'LICENSE' 16 | - 'CHANGELOG.md' 17 | - 'README.md' 18 | 19 | jobs: 20 | build: 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | os: [macOS-latest] 25 | mode: [debug, releasedbg] 26 | kind: [static, shared] 27 | arch: [x86_64, arm64] 28 | 29 | runs-on: ${{ matrix.os }} 30 | if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} 31 | 32 | steps: 33 | - name: Get current date as package key 34 | id: cache_key 35 | run: echo "key=$(date +'%W')" >> $GITHUB_OUTPUT 36 | 37 | - name: Checkout repository 38 | uses: actions/checkout@v4 39 | 40 | # Force xmake to a specific folder (for cache) 41 | - name: Set xmake env 42 | run: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/xmake-global" >> $GITHUB_ENV 43 | 44 | # Install xmake 45 | - name: Setup xmake 46 | uses: xmake-io/github-action-setup-xmake@v1 47 | with: 48 | actions-cache-folder: .xmake-cache-W${{ steps.cache_key.outputs.key }} 49 | 50 | # Update xmake repository (in order to have the file that will be cached) 51 | - name: Update xmake repository 52 | run: xmake repo --update 53 | 54 | # Fetch xmake dephash 55 | - name: Retrieve dependencies hash 56 | id: dephash 57 | run: echo "hash=$(xmake l utils.ci.packageskey)" >> $GITHUB_OUTPUT 58 | 59 | # Cache xmake dependencies 60 | - name: Retrieve cached xmake dependencies 61 | id: restore-depcache 62 | uses: actions/cache/restore@v4 63 | with: 64 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 65 | key: macOS-${{ matrix.arch }}-${{ matrix.mode }}-${{ steps.dephash.outputs.hash }}-W${{ steps.cache_key.outputs.key }} 66 | 67 | # Setup compilation mode and install project dependencies 68 | - name: Configure xmake and install dependencies 69 | run: xmake config --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --kind=${{ matrix.kind }} --ccache=n --examples=y --tests=y --unitybuild=y --yes 70 | 71 | # Save dependencies 72 | - name: Save cached xmake dependencies 73 | if: ${{ !steps.restore-depcache.outputs.cache-hit }} 74 | uses: actions/cache/save@v4 75 | with: 76 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 77 | key: ${{ steps.restore-depcache.outputs.cache-primary-key }} 78 | 79 | # Build library and tests 80 | - name: Build library 81 | run: xmake 82 | 83 | # Run unit tests 84 | - name: Run unit tests 85 | run: xmake run UnitTests 86 | 87 | # Install the result files 88 | - name: Install NZSL 89 | run: xmake install -vo package 90 | 91 | # Upload artifacts 92 | - uses: actions/upload-artifact@v4 93 | with: 94 | name: nzsl-macOS-${{ matrix.arch }}-${{ matrix.kind }}-${{ matrix.mode }} 95 | path: package 96 | -------------------------------------------------------------------------------- /.github/workflows/msys2-build.yml: -------------------------------------------------------------------------------- 1 | name: MSYS2 build (MinGW-w64) 2 | 3 | on: 4 | pull_request: 5 | push: 6 | paths-ignore: 7 | - '.github/workflows/android-build.yml' 8 | - '.github/workflows/coverage.yml' 9 | - '.github/workflows/ios-build.yml' 10 | - '.github/workflows/linux-build.yml' 11 | - '.github/workflows/macos-build.yml' 12 | - '.github/workflows/wasm-build.yml' 13 | - '.github/workflows/windows-build.yml' 14 | - '.gitignore' 15 | - 'LICENSE' 16 | - 'CHANGELOG.md' 17 | - 'README.md' 18 | 19 | jobs: 20 | build: 21 | strategy: 22 | matrix: 23 | msystem: [mingw64] 24 | os: [windows-latest] 25 | arch: [x86_64] 26 | mode: [debug, release] 27 | kind: [static, shared] 28 | 29 | runs-on: ${{ matrix.os }} 30 | if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} 31 | 32 | defaults: 33 | run: 34 | shell: msys2 {0} 35 | 36 | steps: 37 | - name: Get current date as package key 38 | id: cache_key 39 | shell: bash 40 | run: echo "key=$(date +'%W')" >> $GITHUB_OUTPUT 41 | 42 | - name: Avoid line ending issues on Windows 43 | shell: bash 44 | run: git config --global core.autocrlf false 45 | 46 | - name: Checkout repository 47 | uses: actions/checkout@v4 48 | 49 | # Setup MSYS2 50 | - uses: msys2/setup-msys2@v2 51 | with: 52 | msystem: ${{ matrix.msystem }} 53 | install: base-devel git unzip p7zip mingw-w64-${{ matrix.arch }}-toolchain mingw-w64-${{ matrix.arch }}-xmake 54 | update: true 55 | 56 | # Force xmake to a specific folder (for cache) 57 | - name: Set xmake env 58 | run: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/xmake-global" >> $GITHUB_ENV 59 | 60 | # Update xmake repository (in order to have the file that will be cached) 61 | - name: Update xmake repository 62 | run: xmake repo --update 63 | 64 | # Fetch xmake dephash 65 | - name: Retrieve dependencies hash 66 | id: dephash 67 | run: echo "hash=$(xmake l utils.ci.packageskey)" >> $GITHUB_OUTPUT 68 | shell: bash 69 | 70 | # Cache xmake dependencies 71 | - name: Retrieve cached xmake dependencies 72 | id: restore-depcache 73 | uses: actions/cache/restore@v4 74 | with: 75 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 76 | key: MinGW-${{ matrix.arch }}-${{ matrix.mode }}-${{ steps.dephash.outputs.hash }}-W${{ steps.cache_key.outputs.key }} 77 | 78 | # Setup compilation mode and install project dependencies 79 | - name: Configure xmake and install dependencies 80 | run: xmake config --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --kind=${{ matrix.kind }} --ccache=n --examples=y --tests=y --unitybuild=n --yes 81 | 82 | # Save dependencies 83 | - name: Save cached xmake dependencies 84 | if: ${{ !steps.restore-depcache.outputs.cache-hit }} 85 | uses: actions/cache/save@v4 86 | with: 87 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 88 | key: ${{ steps.restore-depcache.outputs.cache-primary-key }} 89 | 90 | # Build library and tests 91 | - name: Build library 92 | run: xmake 93 | 94 | # Run unit tests 95 | - name: Run unit tests 96 | run: xmake run UnitTests 97 | 98 | # Install the result files 99 | - name: Install NZSL 100 | run: xmake install -vo package 101 | 102 | # Upload artifacts 103 | - uses: actions/upload-artifact@v4 104 | with: 105 | name: nzsl-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.kind }}-${{ matrix.mode }} 106 | path: package 107 | -------------------------------------------------------------------------------- /.github/workflows/wasm-build.yml: -------------------------------------------------------------------------------- 1 | name: Emscripten (wasm) build 2 | 3 | on: 4 | pull_request: 5 | push: 6 | paths-ignore: 7 | - '.github/workflows/android-build.yml' 8 | - '.github/workflows/coverage.yml' 9 | - '.github/workflows/ios-build.yml' 10 | - '.github/workflows/linux-build.yml' 11 | - '.github/workflows/macos-build.yml' 12 | - '.github/workflows/msys2-build.yml' 13 | - '.github/workflows/windows-build.yml' 14 | - '.gitignore' 15 | - 'LICENSE' 16 | - 'CHANGELOG.md' 17 | - 'README.md' 18 | 19 | jobs: 20 | build: 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | os: [ubuntu-latest] 25 | arch: [x86_64] 26 | mode: [debug, release] 27 | kind: [static] 28 | 29 | runs-on: ${{ matrix.os }} 30 | if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} 31 | 32 | steps: 33 | - name: Get current date as package key 34 | id: cache_key 35 | run: echo "key=$(date +'%W')" >> $GITHUB_OUTPUT 36 | 37 | - name: Checkout repository 38 | uses: actions/checkout@v4 39 | 40 | # Force xmake to a specific folder (for cache) 41 | - name: Set xmake env 42 | run: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/xmake-global" >> $GITHUB_ENV 43 | 44 | # Install xmake 45 | - name: Setup xmake 46 | uses: xmake-io/github-action-setup-xmake@v1 47 | with: 48 | actions-cache-folder: .xmake-cache-W${{ steps.cache_key.outputs.key }} 49 | 50 | # Update xmake repository (in order to have the file that will be cached) 51 | - name: Update xmake repository 52 | run: xmake repo --update 53 | 54 | # Fetch xmake dephash 55 | - name: Retrieve dependencies hash 56 | id: dephash 57 | run: echo "hash=$(xmake l utils.ci.packageskey)" >> $GITHUB_OUTPUT 58 | shell: bash 59 | 60 | # Setup emsdk 61 | - name: Setup emscripten 62 | uses: mymindstorm/setup-emsdk@v14 63 | with: 64 | version: 3.1.31 65 | actions-cache-folder: emsdk-cache-${{ matrix.mode }}-${{ matrix.kind }} 66 | 67 | # Cache xmake dependencies 68 | - name: Retrieve cached xmake dependencies 69 | id: restore-depcache 70 | uses: actions/cache/restore@v4 71 | with: 72 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 73 | key: Wasm-${{ matrix.arch }}-${{ matrix.mode }}-${{ steps.dephash.outputs.hash }}-W${{ steps.cache_key.outputs.key }} 74 | 75 | # Setup compilation mode and install project dependencies 76 | - name: Configure xmake and install dependencies 77 | run: xmake config --plat=wasm --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --kind=${{ matrix.kind }} --ccache=n --fs_watcher=n --tests=n --unitybuild=y --yes 78 | 79 | # Save dependencies 80 | - name: Save cached xmake dependencies 81 | if: ${{ !steps.restore-depcache.outputs.cache-hit }} 82 | uses: actions/cache/save@v4 83 | with: 84 | path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages 85 | key: ${{ steps.restore-depcache.outputs.cache-primary-key }} 86 | 87 | # Build library and tests 88 | - name: Build library 89 | run: xmake 90 | 91 | # Install the result files 92 | - name: Install NZSL 93 | run: xmake install -vo package 94 | 95 | # Upload artifacts 96 | - uses: actions/upload-artifact@v4 97 | with: 98 | name: nzsl-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.mode }} 99 | path: package 100 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # XMake 2 | .xmake 3 | bin/* 4 | !bin/resources 5 | !bin/resources/* 6 | build 7 | vs* 8 | vsxmake* 9 | *.user 10 | .idea/ 11 | cmake*/ 12 | CMakeLists.txt 13 | .luarc.json 14 | 15 | # vscode 16 | .vscode 17 | 18 | # clangd 19 | .cache 20 | compile_commands.json 21 | 22 | # Prerequisites 23 | *.d 24 | 25 | # Compiled Object files 26 | *.slo 27 | *.lo 28 | *.o 29 | *.obj 30 | 31 | # Precompiled Headers 32 | *.gch 33 | *.pch 34 | 35 | # Compiled Dynamic libraries 36 | *.so 37 | *.dylib 38 | *.dll 39 | 40 | # Fortran module files 41 | *.mod 42 | *.smod 43 | 44 | # Compiled Static libraries 45 | *.lai 46 | *.la 47 | *.a 48 | *.lib 49 | 50 | # Executables 51 | *.exe 52 | *.out 53 | *.app 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/resources/Shader.glsl.binding.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": [ 3 | { 4 | "set": 0, 5 | "binding": 0, 6 | "glsl_binding": 0 7 | } 8 | ], 9 | "push_constant_binding": 1 10 | } -------------------------------------------------------------------------------- /bin/resources/Shader.nzsl: -------------------------------------------------------------------------------- 1 | [nzsl_version("1.0")] 2 | [author("SirLynix")] 3 | [desc("Test module")] 4 | [license("MIT")] 5 | module Shader; 6 | 7 | import GetColor as Color from Color; 8 | import * from DataStruct; 9 | import * from OutputStruct; 10 | 11 | [layout(std140)] 12 | struct PushConstants 13 | { 14 | color: vec4[f32] 15 | } 16 | 17 | external ExternalResources 18 | { 19 | constants: push_constant[PushConstants] 20 | } 21 | 22 | [entry(frag)] 23 | fn main() -> Output 24 | { 25 | let data: Data; 26 | data.color = Color(); 27 | 28 | let output: Output; 29 | output.color = GetColorFromData(data) * ExternalResources.constants.color; 30 | 31 | return output; 32 | } 33 | -------------------------------------------------------------------------------- /bin/resources/modules/Archive/InstanceData.nzslb: -------------------------------------------------------------------------------- 1 | RHSN Engine.InstanceDatad InstanceData worldMatrix*../resources/archivetest/InstanceData.nzsl  worldMatrixinvWorldMatrix  invWorldMatrix 2 |  3 |  -------------------------------------------------------------------------------- /bin/resources/modules/Archive/LightData.nzslb: -------------------------------------------------------------------------------- 1 | RHSN Engine.LightDatadMaxLightCascadeCount '../resources/archivetest/LightData.nzsl(()$* MaxLightCount !!"#DirectionalLightcolor  color direction 2 |  directioninvShadowMapSize  invShadowMapSize ambientFactor ambientFactor diffuseFactor diffuseFactor cascadeCount  cascadeCountcascadeDistancescascadeDistancesviewProjMatricesviewProjMatrices  3 | PointLightcolorcolorposition positioninvShadowMapSizeinvShadowMapSize ambientFactor ambientFactor diffuseFactor diffuseFactorradiusradius invRadius 4 |  invRadius  SpotLight color&&color direction 5 | '' directionposition ((positioninvShadowMapSize))invShadowMapSize ambientFactor** ambientFactor diffuseFactor++ diffuseFactor 6 | innerAngle ,, 7 | innerAngle 8 | outerAngle -- 9 | outerAngle invRadius 10 | .. invRadiusviewProjMatrix//viewProjMatrix worldMatrix 00 worldMatrix1$ LightDatadirectionalLights77directionalLights pointLights 88 pointLights 11 | spotLights 99 12 | spotLightsdirectionalLightCount;;directionalLightCountpointLightCount<<pointLightCountspotLightCount==spotLightCount>5> -------------------------------------------------------------------------------- /bin/resources/modules/Archive/SkeletalData.nzslb: -------------------------------------------------------------------------------- 1 | RHSN Engine.SkeletalDatad MaxJointCount *../resources/archivetest/SkeletalData.nzsl" #$ SkeletalData jointMatrices  jointMatrices  2 |   -------------------------------------------------------------------------------- /bin/resources/modules/Archive/SkinningData.nzslb: -------------------------------------------------------------------------------- 1 | RHSN Engine.SkinningDatadSkinPositionOutputposition*../resources/archivetest/SkinningData.nzsl positionSkinPositionNormalOutputposition  positionnormal 2 | normal SkinPositionNormalTangentOutputposition positionnormal 3 | normaltangent tangent -------------------------------------------------------------------------------- /bin/resources/modules/Archive/ViewerData.nzslb: -------------------------------------------------------------------------------- 1 | RHSN Engine.ViewerDatad 2 | ViewerData projectionMatrix(../resources/archivetest/ViewerData.nzslprojectionMatrixinvProjectionMatrix  invProjectionMatrix 3 | viewMatrix 4 |  5 | 6 | viewMatrix invViewMatrix  invViewMatrixviewProjMatrix  viewProjMatrixinvViewProjMatrix  invViewProjMatrixrenderTargetSizerenderTargetSizeinvRenderTargetSizeinvRenderTargetSize eyePosition  eyePosition nearPlane 7 |  nearPlanefarPlane farPlane -------------------------------------------------------------------------------- /bin/resources/modules/Color.nzsl: -------------------------------------------------------------------------------- 1 | [nzsl_version("1.0")] 2 | [author("SirLynix")] 3 | [desc("Test color module")] 4 | [license("MIT")] 5 | module Color; 6 | 7 | [set(0)] 8 | external 9 | { 10 | [binding(0)] tex1: sampler2D[f32] 11 | } 12 | 13 | fn GenerateColor() -> vec4[f32] 14 | { 15 | return tex1.Sample(0.0.xx); 16 | } 17 | 18 | alias GenColor = GenerateColor; 19 | 20 | [set(1)] 21 | external 22 | { 23 | [binding(0)] tex2: sampler2D[f32] 24 | } 25 | 26 | fn GenerateAnotherColor() -> vec4[f32] 27 | { 28 | return tex2.Sample(0.5.xx); 29 | } 30 | 31 | [export] 32 | fn GetColor() -> vec4[f32] 33 | { 34 | return GenColor(); 35 | } 36 | 37 | [export] 38 | fn GetAnotherColor() -> vec4[f32] 39 | { 40 | return GenerateAnotherColor(); 41 | } 42 | -------------------------------------------------------------------------------- /bin/resources/modules/Data/DataStruct.nzsl.original: -------------------------------------------------------------------------------- 1 | [nzsl_version("1.0")] 2 | module DataStruct; 3 | 4 | [export] 5 | struct Data 6 | { 7 | color: vec4[f32] 8 | } 9 | -------------------------------------------------------------------------------- /bin/resources/modules/Data/DataStruct.nzslb: -------------------------------------------------------------------------------- 1 | RHSN 2 | DataStructdDatacolor)../resources/modules/Data/DataStruct.nzsl  -------------------------------------------------------------------------------- /bin/resources/modules/Data/OutputStruct.nzsl: -------------------------------------------------------------------------------- 1 | [nzsl_version("1.0")] 2 | module OutputStruct; 3 | 4 | import * from DataStruct; 5 | 6 | option ColorMultiplier: vec4[f32] = vec4[f32](0.5, 0.5, 0.5, 1.0); 7 | 8 | [export] 9 | fn GetColorFromData(data: Data) -> vec4[f32] 10 | { 11 | return data.color * ColorMultiplier; 12 | } 13 | 14 | [export] 15 | struct Output 16 | { 17 | [location(0)] color: vec4[f32] 18 | } 19 | -------------------------------------------------------------------------------- /examples/sfml-mandelbrot/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | sf::RenderWindow window(sf::VideoMode(sf::Vector2u(1280, 720)), "SFML + NZSL Shader", sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize); 10 | window.setVerticalSyncEnabled(true); 11 | 12 | auto mandelbrotShader = nzsl::ParseFromFile("mandelbrot.nzsl"); 13 | 14 | nzsl::GlslWriter glslWriter; 15 | auto glslShader = glslWriter.Generate(*mandelbrotShader); 16 | 17 | sf::Shader shader; 18 | if (!shader.loadFromMemory(glslShader.code, sf::Shader::Type::Fragment)) 19 | { 20 | std::cerr << "failed to load fragment shader" << std::endl; 21 | return 0; 22 | } 23 | 24 | sf::Texture palette; 25 | if (!palette.loadFromFile("palette.png")) 26 | { 27 | std::cerr << "failed to load palette" << std::endl; 28 | return 0; 29 | } 30 | 31 | float scale = 2.2f; 32 | float targetScale = scale; 33 | int iterCount = 120; 34 | sf::Vector2f center = sf::Vector2f(window.getSize()) / 2.f; 35 | 36 | shader.setUniform("palette", palette); 37 | shader.setUniform("screen_size", sf::Vector2f(window.getSize())); 38 | shader.setUniform("center", center); 39 | shader.setUniform("scale", scale); 40 | shader.setUniform("iteration_count", iterCount); 41 | 42 | // use a fullscreen shape to apply shader on screen 43 | sf::RectangleShape fullscreenShape; 44 | fullscreenShape.setSize(sf::Vector2f(window.getSize())); 45 | fullscreenShape.setFillColor(sf::Color::Yellow); 46 | 47 | sf::Vector2i mousePos = sf::Mouse::getPosition(window); 48 | 49 | sf::Clock updateClock; 50 | while (window.isOpen()) 51 | { 52 | while (std::optional event = window.pollEvent()) 53 | { 54 | if (event->is()) 55 | { 56 | window.close(); 57 | break; 58 | } 59 | else if (const auto* keyPressed = event->getIf()) 60 | { 61 | if (keyPressed->code == sf::Keyboard::Key::Escape) 62 | window.close(); 63 | } 64 | else if (const auto* mouseMoved = event->getIf()) 65 | { 66 | sf::Vector2i delta = mouseMoved->position - mousePos; 67 | mousePos = mouseMoved->position; 68 | 69 | if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) 70 | { 71 | center += scale * sf::Vector2f(sf::Vector2i(delta.x, -delta.y)); 72 | shader.setUniform("center", center); 73 | } 74 | } 75 | else if (const auto* mouseWheelScrolled = event->getIf()) 76 | targetScale = std::clamp(targetScale - targetScale * 0.1f * mouseWheelScrolled->delta, 0.000001f, 3.f); 77 | else if (const auto* resized = event->getIf()) 78 | { 79 | sf::Vector2f newSize(float(resized->size.x), float(resized->size.y)); 80 | 81 | shader.setUniform("screen_size", newSize); 82 | fullscreenShape.setSize(newSize); 83 | 84 | sf::FloatRect visibleArea(sf::Vector2f(0.f, 0.f), sf::Vector2f(newSize.x, newSize.y)); 85 | window.setView(sf::View(visibleArea)); 86 | } 87 | } 88 | 89 | // Smooth zoom a bit 90 | if (targetScale != scale) 91 | { 92 | float diff = targetScale - scale; 93 | if (targetScale < scale) 94 | scale = std::max(scale + diff * 0.02f * updateClock.getElapsedTime().asSeconds(), targetScale); 95 | else if (targetScale > scale) 96 | scale = std::min(scale + diff * 0.02f * updateClock.getElapsedTime().asSeconds(), targetScale); 97 | 98 | shader.setUniform("scale", scale); 99 | } 100 | 101 | window.draw(fullscreenShape, &shader); 102 | 103 | window.display(); 104 | } 105 | 106 | return EXIT_SUCCESS; 107 | } 108 | -------------------------------------------------------------------------------- /examples/sfml-mandelbrot/mandelbrot.nzsl: -------------------------------------------------------------------------------- 1 | [nzsl_version("1.0")] 2 | [desc("Mandelbrot shader from http://nuclear.mutantstargoat.com/articles/sdr_fract")] 3 | [feature(primitive_externals)] //< Required since SFML doesn't use UBO 4 | module; 5 | 6 | external 7 | { 8 | [binding(0)] palette: sampler2D[f32], 9 | [binding(1)] screen_size: vec2[f32], 10 | [binding(2)] center: vec2[f32], 11 | [binding(3)] scale: f32, 12 | [binding(4)] iteration_count: i32 13 | } 14 | 15 | struct Input 16 | { 17 | [builtin(frag_coord)] fragcoord: vec4[f32] 18 | } 19 | 20 | struct Output 21 | { 22 | [location(0)] color: vec4[f32] 23 | } 24 | 25 | [entry(frag)] 26 | fn main(input: Input) -> Output 27 | { 28 | let coords = input.fragcoord.xy / screen_size; 29 | 30 | let c: vec2[f32]; 31 | c.x = (screen_size.x / screen_size.y) * (coords.x - 0.5) * scale - center.x / screen_size.y; 32 | c.y = (coords.y - 0.5) * scale - center.y / screen_size.y; 33 | 34 | let z = c; 35 | let i = 0; 36 | while (i < iteration_count) 37 | { 38 | let x = (z.x * z.x - z.y * z.y) + c.x; 39 | let y = (z.y * z.x + z.x * z.y) + c.y; 40 | 41 | if ((x * x + y * y) > 4.0) 42 | break; 43 | 44 | z.x = x; 45 | z.y = y; 46 | 47 | i += 1; 48 | } 49 | 50 | let u: f32; 51 | if (i < iteration_count) 52 | u = f32(i) / 100.0; 53 | else 54 | u = 0.0; 55 | 56 | let output: Output; 57 | output.color = palette.Sample(vec2[f32](u, 0.0)); 58 | 59 | return output; 60 | } 61 | -------------------------------------------------------------------------------- /examples/sfml-mandelbrot/palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NazaraEngine/ShaderLang/e95f7b8be6bb33f45f299e44990d878de858ae77/examples/sfml-mandelbrot/palette.png -------------------------------------------------------------------------------- /examples/sfml-mandelbrot/xmake.lua: -------------------------------------------------------------------------------- 1 | if is_plat("android", "iphoneos", "wasm") then 2 | -- the sfml does not support emscripten nor mobile for now 3 | return 4 | end 5 | 6 | add_requires("sfml 3.0", { configs = { audio = false, network = false }}) 7 | 8 | target("sfml-mandelbrot") 9 | set_group("Examples") 10 | add_packages("sfml") 11 | add_deps("nzsl") 12 | set_rundir(".") 13 | 14 | add_files("main.cpp") 15 | add_headerfiles("mandelbrot.nzsl", { install = false }) 16 | add_installfiles("mandelbrot.nzsl", {prefixdir = "bin"}) 17 | add_installfiles("palette.png", {prefixdir = "bin"}) 18 | -------------------------------------------------------------------------------- /examples/xmake.lua: -------------------------------------------------------------------------------- 1 | option("examples") 2 | set_default(true) 3 | set_showmenu(true) 4 | set_description("Build examples") 5 | option_end() 6 | 7 | if has_config("examples") then 8 | includes("*/xmake.lua") 9 | end 10 | -------------------------------------------------------------------------------- /include/CNZSL/CNZSL.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_CNZSL_H 10 | #define CNZSL_CNZSL_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #endif /* CNZSL_CNZSL_H */ 21 | -------------------------------------------------------------------------------- /include/CNZSL/Config.h: -------------------------------------------------------------------------------- 1 | /* 2 | Nazara Shading Language - C Binding (CNZSL) 3 | 4 | Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 5 | 2024 REMqb (remqb at remqb dot fr) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | #pragma once 27 | 28 | #ifndef CNZSL_CONFIG_H 29 | #define CNZSL_CONFIG_H 30 | 31 | /* CNZSL version macro */ 32 | #define CNZSL_VERSION_MAJOR 0 33 | #define CNZSL_VERSION_MINOR 1 34 | #define CNZSL_VERSION_PATCH 0 35 | 36 | #if !defined(CNZSL_STATIC) 37 | #ifdef _WIN32 38 | #ifdef CNZSL_BUILD 39 | #define CNZSL_API __declspec(dllexport) 40 | #else 41 | #define CNZSL_API __declspec(dllimport) 42 | #endif 43 | #else 44 | #define CNZSL_API __attribute__((visibility("default"))) 45 | #endif 46 | #else 47 | #define CNZSL_API extern 48 | #endif 49 | 50 | typedef int nzslBool; 51 | typedef float nzslFloat32; 52 | typedef double nzslFloat64; 53 | 54 | #endif /* CNZSL_CONFIG_H */ 55 | -------------------------------------------------------------------------------- /include/CNZSL/DebugLevel.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_DEBUGLEVEL_H 10 | #define CNZSL_DEBUGLEVEL_H 11 | 12 | typedef enum 13 | { 14 | NZSL_DEBUG_NONE, 15 | 16 | NZSL_DEBUG_FULL, 17 | NZSL_DEBUG_MINIMAL, 18 | NZSL_DEBUG_REGULAR, 19 | 20 | NZSL_DEBUG_MAX_ENUM = 0x7FFFFFFF 21 | } nzslDebugLevel; 22 | 23 | #endif /* CNZSL_DEBUGLEVEL_H */ 24 | -------------------------------------------------------------------------------- /include/CNZSL/FilesystemModuleResolver.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 kbz_8 ( contact@kbz8.me ) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_FILESYSTEM_MODULE_RESOLVER_H 10 | #define CNZSL_FILESYSTEM_MODULE_RESOLVER_H 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" 19 | { 20 | #endif 21 | 22 | typedef struct nzslFilesystemModuleResolver nzslFilesystemModuleResolver; 23 | 24 | CNZSL_API nzslFilesystemModuleResolver* nzslFilesystemModuleResolverCreate(void); 25 | CNZSL_API void nzslFilesystemModuleResolverDestroy(nzslFilesystemModuleResolver* resolverPtr); 26 | CNZSL_API const char* nzslFilesystemModuleResolverGetLastError(const nzslFilesystemModuleResolver* resolverPtr); 27 | 28 | CNZSL_API void nzslFilesystemModuleResolverRegisterDirectory(nzslFilesystemModuleResolver* resolverPtr, const char* sourcePath, size_t sourcePathLen); 29 | CNZSL_API void nzslFilesystemModuleResolverRegisterFile(nzslFilesystemModuleResolver* resolverPtr, const char* sourcePath, size_t sourcePathLen); 30 | CNZSL_API void nzslFilesystemModuleResolverRegisterModule(nzslFilesystemModuleResolver* resolverPtr, const nzslModule* module); 31 | CNZSL_API void nzslFilesystemModuleResolverRegisterModuleFromSource(nzslFilesystemModuleResolver* resolverPtr, const char* source, size_t sourceLen); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/CNZSL/GlslWriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Glsluage - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_GLSLWRITER_H 10 | #define CNZSL_GLSLWRITER_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #ifdef __cplusplus 19 | extern "C" 20 | { 21 | #endif 22 | 23 | typedef struct nzslGlslWriter nzslGlslWriter; 24 | typedef struct nzslGlslWriterParameters nzslGlslWriterParameters; 25 | typedef struct nzslGlslOutput nzslGlslOutput; 26 | 27 | typedef struct 28 | { 29 | unsigned int glMajorVersion; 30 | unsigned int glMinorVersion; 31 | nzslBool glES; 32 | nzslBool flipYPosition; 33 | nzslBool remapZPosition; 34 | int allowDrawParametersUniformsFallback; 35 | } nzslGlslWriterEnvironment; 36 | 37 | CNZSL_API nzslGlslWriterParameters* nzslGlslWriterParametersCreate(void); 38 | CNZSL_API void nzslGlslWriterParametersDestroy(nzslGlslWriterParameters* parameterPtr); 39 | 40 | CNZSL_API void nzslGlslWriterParametersSetBindingMapping(nzslGlslWriterParameters* parameterPtr, uint32_t setIndex, uint32_t bindingIndex, unsigned int glBinding); 41 | CNZSL_API void nzslGlslWriterParametersSetPushConstantBinding(nzslGlslWriterParameters* parameterPtr, unsigned int glBinding); 42 | 43 | CNZSL_API nzslGlslWriter* nzslGlslWriterCreate(void); 44 | CNZSL_API void nzslGlslWriterDestroy(nzslGlslWriter* writerPtr); 45 | 46 | CNZSL_API nzslGlslOutput* nzslGlslWriterGenerate(nzslGlslWriter* writerPtr, const nzslModule* modulePtr, const nzslGlslWriterParameters* parameterPtr, const nzslWriterStates* statesPtr); 47 | CNZSL_API nzslGlslOutput* nzslGlslWriterGenerateStage(nzslGlslWriter* writerPtr, nzslShaderStageType stage, const nzslModule* modulePtr, const nzslGlslWriterParameters* parameterPtr, const nzslWriterStates* statesPtr); 48 | 49 | /** 50 | ** Gets the last error message set by the last operation to this writer 51 | ** 52 | ** @param writerPtr 53 | ** @returns null-terminated error string 54 | **/ 55 | CNZSL_API const char* nzslGlslWriterGetLastError(const nzslGlslWriter* writerPtr); 56 | 57 | CNZSL_API void nzslGlslWriterSetEnv(nzslGlslWriter* writerPtr, const nzslGlslWriterEnvironment* env); 58 | 59 | CNZSL_API void nzslGlslOutputDestroy(nzslGlslOutput* outputPtr); 60 | CNZSL_API const char* nzslGlslOutputGetCode(const nzslGlslOutput* outputPtr, size_t* length); 61 | 62 | /** 63 | * Return texture binding in output or -1 if binding doesn't exists 64 | * 65 | * @param output 66 | * @param bindingName 67 | * @return 68 | */ 69 | CNZSL_API int nzslGlslOutputGetExplicitTextureBinding(const nzslGlslOutput* outputPtr, const char* bindingName); 70 | 71 | /** 72 | * Return uniform binding in output or -1 if binding doesn't exists 73 | * 74 | * @param output 75 | * @param bindingName 76 | * @return 77 | */ 78 | CNZSL_API int nzslGlslOutputGetExplicitUniformBlockBinding(const nzslGlslOutput* outputPtr, const char* bindingName); 79 | 80 | CNZSL_API int nzslGlslOutputGetUsesDrawParameterBaseInstanceUniform(const nzslGlslOutput* outputPtr); 81 | CNZSL_API int nzslGlslOutputGetUsesDrawParameterBaseVertexUniform(const nzslGlslOutput* outputPtr); 82 | CNZSL_API int nzslGlslOutputGetUsesDrawParameterDrawIndexUniform(const nzslGlslOutput* outputPtr); 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif /* CNZSL_GLSLWRITER_H */ 89 | -------------------------------------------------------------------------------- /include/CNZSL/LangWriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_LANGWRITER_H 10 | #define CNZSL_LANGWRITER_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" 19 | { 20 | #endif 21 | 22 | typedef struct nzslLangWriter nzslLangWriter; 23 | typedef struct nzslLangOutput nzslLangOutput; 24 | 25 | CNZSL_API nzslLangWriter* nzslLangWriterCreate(void); 26 | CNZSL_API void nzslLangWriterDestroy(nzslLangWriter* writerPtr); 27 | 28 | CNZSL_API nzslLangOutput* nzslLangWriterGenerate(nzslLangWriter* writerPtr, const nzslModule* modulePtr, const nzslWriterStates* statesPtr); 29 | 30 | /** 31 | ** Gets the last error message set by the last operation to this writer 32 | ** 33 | ** @param writerPtr 34 | ** @returns null-terminated error string 35 | **/ 36 | CNZSL_API const char* nzslLangWriterGetLastError(const nzslLangWriter* writerPtr); 37 | 38 | CNZSL_API void nzslLangOutputDestroy(nzslLangOutput* outputPtr); 39 | CNZSL_API const char* nzslLangOutputGetCode(const nzslLangOutput* outputPtr, size_t* length); 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif /* CNZSL_LANGWRITER_H */ 46 | -------------------------------------------------------------------------------- /include/CNZSL/Module.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_MODULE_H 10 | #define CNZSL_MODULE_H 11 | 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" 16 | { 17 | #endif 18 | 19 | typedef struct nzslModule nzslModule; 20 | 21 | /** 22 | ** Creates an empty nzslModule 23 | ** 24 | ** @param module 25 | */ 26 | CNZSL_API nzslModule* nzslModuleCreate(void); 27 | 28 | /** 29 | ** Free a nzslModule that was returned by one of the parsers functions 30 | ** 31 | ** @param module 32 | */ 33 | CNZSL_API void nzslModuleDestroy(nzslModule* module); 34 | 35 | /** 36 | ** Gets the last error message set by the last operation to this module 37 | ** 38 | ** @param module 39 | ** @returns null-terminated error string 40 | **/ 41 | CNZSL_API const char* nzslModuleGetLastError(const nzslModule* module); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif /* CNZSL_MODULE_H */ 48 | -------------------------------------------------------------------------------- /include/CNZSL/Parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_PARSER_H 10 | #define CNZSL_PARSER_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" 18 | { 19 | #endif 20 | 21 | CNZSL_API int nzslParserParseFromFile(nzslModule* module, const char* sourcePath, size_t sourcePathLen); 22 | 23 | CNZSL_API int nzslParserParseSource(nzslModule* module, const char* source, size_t sourceLen); 24 | 25 | /** 26 | * Parse a NZSL source code and stores it inside a nzslModule 27 | * In case of failure, a negative value is returned and an error code is set 28 | * 29 | * @param module pointer to a 30 | * @param source pointer to NZSL source 31 | * @param sourceLen length of source in characters 32 | * @param filePath used when reporting errors 33 | * @param filePathLen length of filePath in characters 34 | * @return 0 if parsing succeeded and a negative value in case of failure 35 | * 36 | * @see nzslModuleGetLastError 37 | */ 38 | CNZSL_API int nzslParserParseSourceWithFilePath(nzslModule* module, const char* source, size_t sourceLen, const char* filePath, size_t filePathLen); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | 45 | #endif /* CNZSL_PARSER_H */ 46 | -------------------------------------------------------------------------------- /include/CNZSL/Serializer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 kbz_8 ( contact@kbz8.me ) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_SERIALIZER_H 10 | #define CNZSL_SERIALIZER_H 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" 19 | { 20 | #endif 21 | 22 | typedef struct nzslSerializer nzslSerializer; 23 | typedef struct nzslDeserializer nzslDeserializer; 24 | 25 | CNZSL_API nzslSerializer* nzslSerializerCreate(void); 26 | CNZSL_API void nzslSerializerDestroy(nzslSerializer* serializerPtr); 27 | CNZSL_API nzslBool nzslSerializeShader(nzslSerializer* serializerPtr, const nzslModule* modulePtr); 28 | CNZSL_API const void* nzslSerializerGetData(const nzslSerializer* serializerPtr, size_t* outSize); 29 | CNZSL_API const char* nzslSerializerGetLastError(const nzslSerializer* serializerPtr); 30 | 31 | CNZSL_API nzslDeserializer* nzslDeserializerCreate(const void* data, size_t dataSize); 32 | CNZSL_API void nzslDeserializerDestroy(nzslDeserializer* deserializerPtr); 33 | CNZSL_API nzslModule* nzslDeserializeShader(nzslDeserializer* deserializerPtr); 34 | CNZSL_API const char* nzslDeserializerGetLastError(const nzslDeserializer* deserializerPtr); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* CNZSL_SERIALIZER_H */ 41 | -------------------------------------------------------------------------------- /include/CNZSL/ShaderStageType.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_SHADERSTAGETYPE_H 10 | #define CNZSL_SHADERSTAGETYPE_H 11 | 12 | typedef enum 13 | { 14 | NZSL_STAGE_COMPUTE, 15 | NZSL_STAGE_FRAGMENT, 16 | NZSL_STAGE_VERTEX, 17 | 18 | NZSL_STAGE_MAX_ENUM = 0x7FFFFFFF 19 | } nzslShaderStageType; 20 | 21 | #endif /* CNZSL_SHADERSTAGETYPE_H */ 22 | -------------------------------------------------------------------------------- /include/CNZSL/SpirvWriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_SPIRVWRITER_H 10 | #define CNZSL_SPIRVWRITER_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #ifdef __cplusplus 19 | extern "C" 20 | { 21 | #endif 22 | 23 | typedef struct nzslSpirvWriter nzslSpirvWriter; 24 | typedef struct nzslSpirvOutput nzslSpirvOutput; 25 | 26 | typedef struct 27 | { 28 | uint32_t spvMajorVersion; 29 | uint32_t spvMinorVersion; 30 | } nzslSpirvWriterEnvironment; 31 | 32 | CNZSL_API nzslSpirvWriter* nzslSpirvWriterCreate(void); 33 | CNZSL_API void nzslSpirvWriterDestroy(nzslSpirvWriter* writerPtr); 34 | 35 | CNZSL_API nzslSpirvOutput* nzslSpirvWriterGenerate(nzslSpirvWriter* writerPtr, const nzslModule* modulePtr, const nzslWriterStates* statesPtr); 36 | 37 | /** 38 | ** Gets the last error message set by the last operation to this writer 39 | ** 40 | ** @param writerPtr 41 | ** @returns null-terminated error string 42 | **/ 43 | CNZSL_API const char* nzslSpirvWriterGetLastError(const nzslSpirvWriter* writerPtr); 44 | 45 | CNZSL_API void nzslSpirvWriterSetEnv(nzslSpirvWriter* writerPtr, const nzslSpirvWriterEnvironment* env); 46 | 47 | CNZSL_API void nzslSpirvOutputDestroy(nzslSpirvOutput* outputPtr); 48 | CNZSL_API const uint32_t* nzslSpirvOutputGetSpirv(const nzslSpirvOutput* outputPtr, size_t* length); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif /* CNZSL_SPIRVWRITER_H */ 55 | -------------------------------------------------------------------------------- /include/CNZSL/WriterStates.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2024 REMqb (remqb at remqb dot fr) 3 | This file is part of the "Nazara Shading Language - C Binding" project 4 | For conditions of distribution and use, see copyright notice in Config.hpp 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifndef CNZSL_WRITERSTATES_H 10 | #define CNZSL_WRITERSTATES_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" 19 | { 20 | #endif 21 | 22 | typedef uint32_t nzslOptionHash; 23 | 24 | CNZSL_API nzslOptionHash nzslHashOption(const char* str); 25 | 26 | typedef struct nzslWriterStates nzslWriterStates; 27 | 28 | CNZSL_API nzslWriterStates* nzslWriterStatesCreate(void); 29 | CNZSL_API void nzslWriterStatesDestroy(nzslWriterStates* statesPtr); 30 | 31 | CNZSL_API void nzslWriterStatesEnableOptimization(nzslWriterStates* statesPtr, nzslBool enable); 32 | CNZSL_API void nzslWriterStatesEnableSanitization(nzslWriterStates* statesPtr, nzslBool enable); 33 | CNZSL_API void nzslWriterStatesSetDebugLevel(nzslWriterStates* statesPtr, nzslDebugLevel debugLevel); 34 | 35 | CNZSL_API void nzslWriterStatesSetModuleResolver_Filesystem(nzslWriterStates* statesPtr, const nzslFilesystemModuleResolver* resolverPtr); 36 | 37 | CNZSL_API void nzslWriterStatesSetOption_bool(nzslWriterStates* statesPtr, nzslOptionHash optionHash, nzslBool value); 38 | CNZSL_API void nzslWriterStatesSetOption_f32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, nzslFloat32 value); 39 | CNZSL_API void nzslWriterStatesSetOption_i32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, int32_t value); 40 | CNZSL_API void nzslWriterStatesSetOption_u32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, uint32_t value); 41 | CNZSL_API void nzslWriterStatesSetOption_vec2bool(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const nzslBool* values); 42 | CNZSL_API void nzslWriterStatesSetOption_vec3bool(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const nzslBool* values); 43 | CNZSL_API void nzslWriterStatesSetOption_vec4bool(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const nzslBool* values); 44 | CNZSL_API void nzslWriterStatesSetOption_vec2f32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const nzslFloat32* values); 45 | CNZSL_API void nzslWriterStatesSetOption_vec3f32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const nzslFloat32* values); 46 | CNZSL_API void nzslWriterStatesSetOption_vec4f32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const nzslFloat32* values); 47 | CNZSL_API void nzslWriterStatesSetOption_vec2i32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const int32_t* values); 48 | CNZSL_API void nzslWriterStatesSetOption_vec3i32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const int32_t* values); 49 | CNZSL_API void nzslWriterStatesSetOption_vec4i32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const int32_t* values); 50 | CNZSL_API void nzslWriterStatesSetOption_vec2u32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const uint32_t* values); 51 | CNZSL_API void nzslWriterStatesSetOption_vec3u32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const uint32_t* values); 52 | CNZSL_API void nzslWriterStatesSetOption_vec4u32(nzslWriterStates* statesPtr, nzslOptionHash optionHash, const uint32_t* values); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* CNZSL_WRITERSTATES_H */ 59 | -------------------------------------------------------------------------------- /include/NZSL/Archive.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_ARCHIVE_HPP 8 | #define NZSL_ARCHIVE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class AbstractDeserializer; 19 | class AbstractSerializer; 20 | class Serializer; 21 | 22 | namespace Ast 23 | { 24 | using ModulePtr = std::shared_ptr; 25 | } 26 | 27 | enum class ArchiveEntryFlag 28 | { 29 | CompressedLZ4HC = 0, 30 | 31 | Max = CompressedLZ4HC 32 | }; 33 | 34 | constexpr bool EnableEnumAsNzFlags(ArchiveEntryFlag) { return true; } 35 | 36 | using ArchiveEntryFlags = Nz::Flags; 37 | 38 | enum class ArchiveEntryKind 39 | { 40 | BinaryShaderModule = 0 41 | }; 42 | 43 | class NZSL_API Archive 44 | { 45 | public: 46 | struct ModuleData; 47 | 48 | Archive() = default; 49 | Archive(const Archive&) = default; 50 | Archive(Archive&&) noexcept = default; 51 | ~Archive() = default; 52 | 53 | void AddModule(std::string moduleName, ArchiveEntryKind kind, const void* moduleData, std::size_t moduleSize, ArchiveEntryFlags flags = ArchiveEntryFlag::CompressedLZ4HC); 54 | void AddModule(ModuleData moduleData); 55 | 56 | inline const std::vector& GetModules() const; 57 | 58 | void Merge(Archive&& archive); 59 | 60 | Archive& operator=(const Archive&) = default; 61 | Archive& operator=(Archive&&) = default; 62 | 63 | struct ModuleData 64 | { 65 | std::string name; 66 | std::vector data; 67 | ArchiveEntryFlags flags; 68 | ArchiveEntryKind kind; 69 | }; 70 | 71 | static std::vector CompressModule(const void* moduleData, std::size_t moduleSize, ArchiveEntryFlags flags); 72 | static std::vector DecompressModule(const void* moduleData, std::size_t moduleSize, ArchiveEntryFlags flags); 73 | 74 | private: 75 | std::vector m_modules; 76 | }; 77 | 78 | NZSL_API Archive DeserializeArchive(AbstractDeserializer& deserializer); 79 | NZSL_API void SerializeArchive(AbstractSerializer& serializer, const Archive& archive); 80 | 81 | NZSL_API std::string_view ToString(ArchiveEntryKind entryKind); 82 | NZSL_API std::string_view ToString(ArchiveEntryFlag entryFlag); 83 | NZSL_API std::string ToString(ArchiveEntryFlags entryFlags); 84 | } 85 | 86 | #include 87 | 88 | #endif // NZSL_ARCHIVE_HPP 89 | -------------------------------------------------------------------------------- /include/NZSL/Archive.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | namespace nzsl 6 | { 7 | inline auto Archive::GetModules() const -> const std::vector& 8 | { 9 | return m_modules; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Cloner.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | template 9 | ExpressionValue Cloner::Clone(const ExpressionValue& expressionValue) 10 | { 11 | if (!expressionValue.HasValue()) 12 | return {}; 13 | 14 | if (expressionValue.IsExpression()) 15 | return CloneExpression(expressionValue.GetExpression()); 16 | else 17 | { 18 | assert(expressionValue.IsResultingValue()); 19 | return expressionValue.GetResultingValue(); 20 | } 21 | } 22 | 23 | inline ExpressionValue Cloner::Clone(const ExpressionValue& expressionValue) 24 | { 25 | return CloneType(expressionValue); 26 | } 27 | 28 | inline ExpressionPtr Cloner::CloneExpression(const ExpressionPtr& expr) 29 | { 30 | if (!expr) 31 | return nullptr; 32 | 33 | return CloneExpression(*expr); 34 | } 35 | 36 | inline StatementPtr Cloner::CloneStatement(const StatementPtr& statement) 37 | { 38 | if (!statement) 39 | return nullptr; 40 | 41 | return CloneStatement(*statement); 42 | } 43 | 44 | 45 | template 46 | ExpressionValue Clone(const ExpressionValue& attribute) 47 | { 48 | Cloner cloner; 49 | return cloner.Clone(attribute); 50 | } 51 | 52 | inline ExpressionPtr Clone(Expression& node) 53 | { 54 | Cloner cloner; 55 | return cloner.Clone(node); 56 | } 57 | 58 | inline StatementPtr Clone(Statement& node) 59 | { 60 | Cloner cloner; 61 | return cloner.Clone(node); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ConstantPropagationVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | inline ExpressionPtr ConstantPropagationVisitor::Process(Expression& expression) 9 | { 10 | m_options = {}; 11 | return CloneExpression(expression); 12 | } 13 | 14 | inline ExpressionPtr ConstantPropagationVisitor::Process(Expression& expression, const Options& options) 15 | { 16 | m_options = options; 17 | return CloneExpression(expression); 18 | } 19 | 20 | inline StatementPtr ConstantPropagationVisitor::Process(Statement& statement) 21 | { 22 | m_options = {}; 23 | return CloneStatement(statement); 24 | } 25 | 26 | inline StatementPtr ConstantPropagationVisitor::Process(Statement& statement, const Options& options) 27 | { 28 | m_options = options; 29 | return CloneStatement(statement); 30 | } 31 | 32 | inline ExpressionPtr PropagateConstants(Expression& ast) 33 | { 34 | ConstantPropagationVisitor optimize; 35 | return optimize.Process(ast); 36 | } 37 | 38 | inline ExpressionPtr PropagateConstants(Expression& ast, const ConstantPropagationVisitor::Options& options) 39 | { 40 | ConstantPropagationVisitor optimize; 41 | return optimize.Process(ast, options); 42 | } 43 | 44 | inline ModulePtr PropagateConstants(const Module& shaderModule) 45 | { 46 | ConstantPropagationVisitor optimize; 47 | return optimize.Process(shaderModule); 48 | } 49 | 50 | inline ModulePtr PropagateConstants(const Module& shaderModule, const ConstantPropagationVisitor::Options& options) 51 | { 52 | ConstantPropagationVisitor optimize; 53 | return optimize.Process(shaderModule, options); 54 | } 55 | 56 | inline StatementPtr PropagateConstants(Statement& ast) 57 | { 58 | ConstantPropagationVisitor optimize; 59 | return optimize.Process(ast); 60 | } 61 | 62 | inline StatementPtr PropagateConstants(Statement& ast, const ConstantPropagationVisitor::Options& options) 63 | { 64 | ConstantPropagationVisitor optimize; 65 | return optimize.Process(ast, options); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ConstantValue.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_CONSTANTVALUE_HPP 8 | #define NZSL_AST_CONSTANTVALUE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace nzsl::Ast 18 | { 19 | using NoValue = std::monostate; 20 | 21 | using ConstantSingleTypes = Nz::TypeList< 22 | bool, 23 | float, 24 | std::int32_t, 25 | std::uint32_t, 26 | Vector2f32, 27 | Vector3f32, 28 | Vector4f32, 29 | Vector2i32, 30 | Vector3i32, 31 | Vector4i32, 32 | std::string, 33 | double, 34 | Vector2f64, 35 | Vector3f64, 36 | Vector4f64, 37 | Vector2u32, 38 | Vector3u32, 39 | Vector4u32, 40 | Vector2, 41 | Vector3, 42 | Vector4 43 | >; 44 | 45 | template 46 | struct WrapInVector 47 | { 48 | using type = std::vector; 49 | }; 50 | 51 | using ConstantArrayTypes = Nz::TypeListTransform; 52 | 53 | using ConstantTypes = Nz::TypeListConcat; 54 | 55 | using ConstantSingleValue = Nz::TypeListInstantiate, ConstantSingleTypes>, std::variant>; 56 | using ConstantArrayValue = Nz::TypeListInstantiate, ConstantArrayTypes>, std::variant>; 57 | using ConstantValue = Nz::TypeListInstantiate, ConstantTypes>, std::variant>; 58 | 59 | template ExpressionType GetConstantExpressionType(); 60 | 61 | NZSL_API ExpressionType GetConstantType(const ConstantValue& constant); 62 | NZSL_API ExpressionType GetConstantType(const ConstantArrayValue& constantArray); 63 | NZSL_API ExpressionType GetConstantType(const ConstantSingleValue& constant); 64 | 65 | NZSL_API std::string ConstantToString(const ConstantSingleValue& value); 66 | 67 | NZSL_API std::string ToString(bool value); 68 | NZSL_API std::string ToString(double value); 69 | NZSL_API std::string ToString(float value); 70 | NZSL_API std::string ToString(std::int32_t value); 71 | NZSL_API std::string ToString(std::uint32_t value); 72 | 73 | inline ConstantValue ToConstantValue(ConstantSingleValue value); 74 | inline ConstantValue ToConstantValue(ConstantArrayValue value); 75 | } 76 | 77 | #include 78 | 79 | #endif // NZSL_AST_CONSTANTVALUE_HPP 80 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ConstantValue.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | template 9 | ExpressionType GetConstantExpressionType() 10 | { 11 | if constexpr (std::is_same_v) 12 | return NoType{}; 13 | else if constexpr (std::is_same_v) 14 | return PrimitiveType::Boolean; 15 | else if constexpr (std::is_same_v) 16 | return PrimitiveType::Float64; 17 | else if constexpr (std::is_same_v) 18 | return PrimitiveType::Float32; 19 | else if constexpr (std::is_same_v) 20 | return PrimitiveType::Int32; 21 | else if constexpr (std::is_same_v) 22 | return PrimitiveType::UInt32; 23 | else if constexpr (std::is_same_v) 24 | return PrimitiveType::String; 25 | else if constexpr (IsVector_v && std::is_same_v) 26 | return VectorType{ T::Dimensions, PrimitiveType::Boolean }; 27 | else if constexpr (IsVector_v && std::is_same_v) 28 | return VectorType{ T::Dimensions, PrimitiveType::Float32 }; 29 | else if constexpr (IsVector_v && std::is_same_v) 30 | return VectorType{ T::Dimensions, PrimitiveType::Float64 }; 31 | else if constexpr (IsVector_v && std::is_same_v) 32 | return VectorType{ T::Dimensions, PrimitiveType::Int32 }; 33 | else if constexpr (IsVector_v && std::is_same_v) 34 | return VectorType{ T::Dimensions, PrimitiveType::UInt32 }; 35 | else 36 | static_assert(Nz::AlwaysFalse(), "non-exhaustive visitor"); 37 | } 38 | 39 | inline ConstantValue ToConstantValue(ConstantSingleValue value) 40 | { 41 | return std::visit([&](auto&& arg) -> ConstantValue 42 | { 43 | return std::move(arg); 44 | }, std::move(value)); 45 | } 46 | 47 | inline ConstantValue ToConstantValue(ConstantArrayValue value) 48 | { 49 | return std::visit([&](auto&& arg) -> ConstantValue 50 | { 51 | return std::move(arg); 52 | }, std::move(value)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /include/NZSL/Ast/DependencyCheckerVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_DEPENDENCYCHECKERVISITOR_HPP 8 | #define NZSL_AST_DEPENDENCYCHECKERVISITOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace nzsl::Ast 16 | { 17 | class NZSL_API DependencyCheckerVisitor : public RecursiveVisitor 18 | { 19 | public: 20 | struct Config; 21 | struct UsageSet; 22 | 23 | DependencyCheckerVisitor() = default; 24 | DependencyCheckerVisitor(const DependencyCheckerVisitor&) = delete; 25 | DependencyCheckerVisitor(DependencyCheckerVisitor&&) = delete; 26 | ~DependencyCheckerVisitor() = default; 27 | 28 | inline const UsageSet& GetUsage() const; 29 | 30 | inline void MarkConstantAsUsed(std::size_t constIndex); 31 | inline void MarkFunctionAsUsed(std::size_t funcIndex); 32 | inline void MarkStructAsUsed(std::size_t structIndex); 33 | 34 | inline void Register(Statement& statement); 35 | void Register(Statement& statement, const Config& config); 36 | 37 | inline void Resolve(bool allowUnknownId = false); 38 | 39 | DependencyCheckerVisitor& operator=(const DependencyCheckerVisitor&) = delete; 40 | DependencyCheckerVisitor& operator=(DependencyCheckerVisitor&&) = delete; 41 | 42 | struct Config 43 | { 44 | ShaderStageTypeFlags usedShaderStages; 45 | }; 46 | 47 | struct UsageSet 48 | { 49 | Nz::Bitset<> usedAliases; 50 | Nz::Bitset<> usedConstants; 51 | Nz::Bitset<> usedFunctions; 52 | Nz::Bitset<> usedStructs; 53 | Nz::Bitset<> usedVariables; 54 | }; 55 | 56 | private: 57 | UsageSet& GetContextUsageSet(); 58 | void RegisterType(UsageSet& usageSet, const ExpressionType& exprType); 59 | void Resolve(const UsageSet& usageSet, bool allowUnknownId); 60 | 61 | using RecursiveVisitor::Visit; 62 | 63 | void Visit(AliasValueExpression& node) override; 64 | void Visit(ConstantExpression& node) override; 65 | void Visit(FunctionExpression& node) override; 66 | void Visit(StructTypeExpression& node) override; 67 | void Visit(VariableValueExpression& node) override; 68 | 69 | void Visit(DeclareAliasStatement& node) override; 70 | void Visit(DeclareConstStatement& node) override; 71 | void Visit(DeclareExternalStatement& node) override; 72 | void Visit(DeclareFunctionStatement& node) override; 73 | void Visit(DeclareStructStatement& node) override; 74 | void Visit(DeclareVariableStatement& node) override; 75 | 76 | std::optional m_currentAliasDeclIndex; 77 | std::optional m_currentConstantIndex; 78 | std::optional m_currentFunctionIndex; 79 | std::optional m_currentVariableDeclIndex; 80 | std::unordered_map m_aliasUsages; 81 | std::unordered_map m_constantUsages; 82 | std::unordered_map m_functionUsages; 83 | std::unordered_map m_structUsages; 84 | std::unordered_map m_variableUsages; 85 | Config m_config; 86 | UsageSet m_globalUsage; 87 | UsageSet m_resolvedUsage; 88 | }; 89 | } 90 | 91 | #include 92 | 93 | #endif // NZSL_AST_DEPENDENCYCHECKERVISITOR_HPP 94 | -------------------------------------------------------------------------------- /include/NZSL/Ast/DependencyCheckerVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | inline auto DependencyCheckerVisitor::GetUsage() const -> const UsageSet& 9 | { 10 | return m_resolvedUsage; 11 | } 12 | 13 | inline void DependencyCheckerVisitor::MarkConstantAsUsed(std::size_t constIndex) 14 | { 15 | m_globalUsage.usedConstants.UnboundedSet(constIndex); 16 | } 17 | 18 | inline void DependencyCheckerVisitor::MarkFunctionAsUsed(std::size_t funcIndex) 19 | { 20 | m_globalUsage.usedFunctions.UnboundedSet(funcIndex); 21 | } 22 | 23 | inline void DependencyCheckerVisitor::MarkStructAsUsed(std::size_t structIndex) 24 | { 25 | m_globalUsage.usedStructs.UnboundedSet(structIndex); 26 | } 27 | 28 | inline void DependencyCheckerVisitor::Register(Statement& statement) 29 | { 30 | Config defaultConfig; 31 | return Register(statement, defaultConfig); 32 | } 33 | 34 | inline void DependencyCheckerVisitor::Resolve(bool allowUnknownId) 35 | { 36 | Resolve(m_globalUsage, allowUnknownId); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /include/NZSL/Ast/EliminateUnusedPassVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_ELIMINATEUNUSEDPASSVISITOR_HPP 8 | #define NZSL_AST_ELIMINATEUNUSEDPASSVISITOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl::Ast 17 | { 18 | class NZSL_API EliminateUnusedPassVisitor : Cloner 19 | { 20 | public: 21 | EliminateUnusedPassVisitor() = default; 22 | EliminateUnusedPassVisitor(const EliminateUnusedPassVisitor&) = delete; 23 | EliminateUnusedPassVisitor(EliminateUnusedPassVisitor&&) = delete; 24 | ~EliminateUnusedPassVisitor() = default; 25 | 26 | ModulePtr Process(const Module& shaderModule, const DependencyCheckerVisitor::UsageSet& usageSet); 27 | StatementPtr Process(Statement& statement, const DependencyCheckerVisitor::UsageSet& usageSet); 28 | 29 | EliminateUnusedPassVisitor& operator=(const EliminateUnusedPassVisitor&) = delete; 30 | EliminateUnusedPassVisitor& operator=(EliminateUnusedPassVisitor&&) = delete; 31 | 32 | private: 33 | using Cloner::Clone; 34 | StatementPtr Clone(DeclareAliasStatement& node) override; 35 | StatementPtr Clone(DeclareConstStatement& node) override; 36 | StatementPtr Clone(DeclareExternalStatement& node) override; 37 | StatementPtr Clone(DeclareFunctionStatement& node) override; 38 | StatementPtr Clone(DeclareStructStatement& node) override; 39 | StatementPtr Clone(DeclareVariableStatement& node) override; 40 | 41 | bool IsAliasUsed(std::size_t aliasIndex) const; 42 | bool IsConstantUsed(std::size_t constantIndex) const; 43 | bool IsFunctionUsed(std::size_t funcIndex) const; 44 | bool IsStructUsed(std::size_t structIndex) const; 45 | bool IsVariableUsed(std::size_t varIndex) const; 46 | 47 | struct Context; 48 | Context* m_context; 49 | }; 50 | 51 | inline ModulePtr EliminateUnusedPass(const Module& shaderModule); 52 | inline ModulePtr EliminateUnusedPass(const Module& shaderModule, const DependencyCheckerVisitor::Config& config); 53 | inline ModulePtr EliminateUnusedPass(const Module& shaderModule, const DependencyCheckerVisitor::UsageSet& usageSet); 54 | 55 | inline StatementPtr EliminateUnusedPass(Statement& ast); 56 | inline StatementPtr EliminateUnusedPass(Statement& ast, const DependencyCheckerVisitor::Config& config); 57 | inline StatementPtr EliminateUnusedPass(Statement& ast, const DependencyCheckerVisitor::UsageSet& usageSet); 58 | } 59 | 60 | #include 61 | 62 | #endif // NZSL_AST_ELIMINATEUNUSEDPASSVISITOR_HPP 63 | -------------------------------------------------------------------------------- /include/NZSL/Ast/EliminateUnusedPassVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | inline ModulePtr EliminateUnusedPass(const Module& shaderModule) 9 | { 10 | DependencyCheckerVisitor::Config defaultConfig; 11 | return EliminateUnusedPass(shaderModule, defaultConfig); 12 | } 13 | 14 | inline ModulePtr EliminateUnusedPass(const Module& shaderModule, const DependencyCheckerVisitor::Config& config) 15 | { 16 | DependencyCheckerVisitor dependencyVisitor; 17 | for (const auto& importedModule : shaderModule.importedModules) 18 | dependencyVisitor.Register(*importedModule.module->rootNode, config); 19 | 20 | dependencyVisitor.Register(*shaderModule.rootNode, config); 21 | dependencyVisitor.Resolve(); 22 | 23 | return EliminateUnusedPass(shaderModule, dependencyVisitor.GetUsage()); 24 | } 25 | 26 | ModulePtr EliminateUnusedPass(const Module& shaderModule, const DependencyCheckerVisitor::UsageSet& usageSet) 27 | { 28 | EliminateUnusedPassVisitor visitor; 29 | return visitor.Process(shaderModule, usageSet); 30 | } 31 | 32 | inline StatementPtr EliminateUnusedPass(Statement& ast) 33 | { 34 | DependencyCheckerVisitor::Config defaultConfig; 35 | return EliminateUnusedPass(ast, defaultConfig); 36 | } 37 | 38 | inline StatementPtr EliminateUnusedPass(Statement& ast, const DependencyCheckerVisitor::Config& config) 39 | { 40 | DependencyCheckerVisitor dependencyVisitor; 41 | dependencyVisitor.Register(ast, config); 42 | dependencyVisitor.Resolve(); 43 | 44 | return EliminateUnusedPass(ast, dependencyVisitor.GetUsage()); 45 | } 46 | 47 | StatementPtr EliminateUnusedPass(Statement& ast, const DependencyCheckerVisitor::UsageSet& usageSet) 48 | { 49 | EliminateUnusedPassVisitor visitor; 50 | return visitor.Process(ast, usageSet); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ExportVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_EXPORTVISITOR_HPP 8 | #define NZSL_AST_EXPORTVISITOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nzsl::Ast 15 | { 16 | class NZSL_API ExportVisitor : RecursiveVisitor 17 | { 18 | public: 19 | struct Callbacks; 20 | 21 | ExportVisitor() = default; 22 | ExportVisitor(const ExportVisitor&) = delete; 23 | ExportVisitor(ExportVisitor&&) = delete; 24 | ~ExportVisitor() = default; 25 | 26 | void Visit(Statement& statement, const Callbacks& callbacks); 27 | 28 | ExportVisitor& operator=(const ExportVisitor&) = delete; 29 | ExportVisitor& operator=(ExportVisitor&&) = delete; 30 | 31 | struct Callbacks 32 | { 33 | std::function onExportedConst; 34 | std::function onExportedFunc; 35 | std::function onExportedStruct; 36 | }; 37 | 38 | private: 39 | using RecursiveVisitor::Visit; 40 | 41 | void Visit(DeclareConstStatement& node) override; 42 | void Visit(DeclareFunctionStatement& node) override; 43 | void Visit(DeclareStructStatement& node) override; 44 | 45 | const Callbacks* m_callbacks; 46 | }; 47 | } 48 | 49 | #include 50 | 51 | #endif // NZSL_AST_EXPORTVISITOR_HPP 52 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ExportVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ExpressionValue.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_EXPRESSIONVALUE_HPP 8 | #define NZSL_AST_EXPRESSIONVALUE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace nzsl::Ast 16 | { 17 | struct Expression; 18 | 19 | using ExpressionPtr = std::unique_ptr; 20 | 21 | template 22 | class ExpressionValue 23 | { 24 | public: 25 | ExpressionValue() = default; 26 | ExpressionValue(T value); 27 | ExpressionValue(ExpressionPtr expr); 28 | ExpressionValue(const ExpressionValue&) = default; 29 | ExpressionValue(ExpressionValue&&) noexcept = default; 30 | ~ExpressionValue() = default; 31 | 32 | ExpressionPtr&& GetExpression() &&; 33 | const ExpressionPtr& GetExpression() const &; 34 | const T& GetResultingValue() const; 35 | 36 | bool IsExpression() const; 37 | bool IsResultingValue() const; 38 | 39 | bool HasValue() const; 40 | 41 | void Reset(); 42 | 43 | ExpressionValue& operator=(const ExpressionValue&) = default; 44 | ExpressionValue& operator=(ExpressionValue&&) noexcept = default; 45 | 46 | private: 47 | std::variant m_value; 48 | }; 49 | } 50 | 51 | #include 52 | 53 | #endif // NZSL_AST_EXPRESSIONVALUE_HPP 54 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ExpressionValue.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | 8 | namespace nzsl::Ast 9 | { 10 | template 11 | ExpressionValue::ExpressionValue(T value) : 12 | m_value(std::move(value)) 13 | { 14 | } 15 | 16 | template 17 | ExpressionValue::ExpressionValue(ExpressionPtr expr) 18 | { 19 | assert(expr); 20 | m_value = std::move(expr); 21 | } 22 | 23 | template 24 | ExpressionPtr&& ExpressionValue::GetExpression() && 25 | { 26 | if (!IsExpression()) 27 | throw std::runtime_error("excepted expression"); 28 | 29 | return std::get(std::move(m_value)); 30 | } 31 | 32 | template 33 | const ExpressionPtr& ExpressionValue::GetExpression() const & 34 | { 35 | if (!IsExpression()) 36 | throw std::runtime_error("excepted expression"); 37 | 38 | assert(std::get(m_value)); 39 | return std::get(m_value); 40 | } 41 | 42 | template 43 | const T& ExpressionValue::GetResultingValue() const 44 | { 45 | if (!IsResultingValue()) 46 | throw std::runtime_error("excepted resulting value"); 47 | 48 | return std::get(m_value); 49 | } 50 | 51 | template 52 | bool ExpressionValue::IsExpression() const 53 | { 54 | return std::holds_alternative(m_value); 55 | } 56 | 57 | template 58 | bool ExpressionValue::IsResultingValue() const 59 | { 60 | return std::holds_alternative(m_value); 61 | } 62 | 63 | template 64 | bool ExpressionValue::HasValue() const 65 | { 66 | return !std::holds_alternative(m_value); 67 | } 68 | 69 | template 70 | void ExpressionValue::Reset() 71 | { 72 | m_value = {}; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ExpressionVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_EXPRESSIONVISITOR_HPP 8 | #define NZSL_AST_EXPRESSIONVISITOR_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace nzsl::Ast 14 | { 15 | class NZSL_API ExpressionVisitor 16 | { 17 | public: 18 | ExpressionVisitor() = default; 19 | ExpressionVisitor(const ExpressionVisitor&) = delete; 20 | ExpressionVisitor(ExpressionVisitor&&) = delete; 21 | virtual ~ExpressionVisitor(); 22 | 23 | #define NZSL_SHADERAST_EXPRESSION(Node) virtual void Visit(Node##Expression& node) = 0; 24 | #include 25 | 26 | ExpressionVisitor& operator=(const ExpressionVisitor&) = delete; 27 | ExpressionVisitor& operator=(ExpressionVisitor&&) = delete; 28 | }; 29 | } 30 | 31 | #endif // NZSL_AST_EXPRESSIONVISITOR_HPP 32 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ExpressionVisitorExcept.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_EXPRESSIONVISITOREXCEPT_HPP 8 | #define NZSL_AST_EXPRESSIONVISITOREXCEPT_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace nzsl::Ast 14 | { 15 | class NZSL_API ExpressionVisitorExcept : public ExpressionVisitor 16 | { 17 | public: 18 | using ExpressionVisitor::Visit; 19 | 20 | #define NZSL_SHADERAST_EXPRESSION(Node) void Visit(Ast::Node##Expression& node) override; 21 | #include 22 | }; 23 | } 24 | 25 | #endif // NZSL_AST_EXPRESSIONVISITOREXCEPT_HPP 26 | -------------------------------------------------------------------------------- /include/NZSL/Ast/IndexRemapperVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_INDEXREMAPPERVISITOR_HPP 8 | #define NZSL_AST_INDEXREMAPPERVISITOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nzsl::Ast 15 | { 16 | class NZSL_API IndexRemapperVisitor : public Cloner 17 | { 18 | public: 19 | struct Options; 20 | 21 | IndexRemapperVisitor() = default; 22 | IndexRemapperVisitor(const IndexRemapperVisitor&) = delete; 23 | IndexRemapperVisitor(IndexRemapperVisitor&&) = delete; 24 | ~IndexRemapperVisitor() = default; 25 | 26 | StatementPtr Clone(Statement& statement, const Options& options); 27 | 28 | IndexRemapperVisitor& operator=(const IndexRemapperVisitor&) = delete; 29 | IndexRemapperVisitor& operator=(IndexRemapperVisitor&&) = delete; 30 | 31 | struct Options 32 | { 33 | std::function aliasIndexGenerator; 34 | std::function constIndexGenerator; 35 | std::function funcIndexGenerator; 36 | std::function structIndexGenerator; 37 | //std::function typeIndexGenerator; 38 | std::function varIndexGenerator; 39 | bool forceIndexGeneration = false; 40 | }; 41 | 42 | private: 43 | using Cloner::Clone; 44 | 45 | ExpressionPtr CloneExpression(Expression& expr) override; 46 | 47 | StatementPtr Clone(DeclareAliasStatement& node) override; 48 | StatementPtr Clone(DeclareConstStatement& node) override; 49 | StatementPtr Clone(DeclareExternalStatement& node) override; 50 | StatementPtr Clone(DeclareFunctionStatement& node) override; 51 | StatementPtr Clone(DeclareOptionStatement& node) override; 52 | StatementPtr Clone(DeclareStructStatement& node) override; 53 | StatementPtr Clone(DeclareVariableStatement& node) override; 54 | StatementPtr Clone(ForStatement& node) override; 55 | StatementPtr Clone(ForEachStatement& node) override; 56 | 57 | ExpressionPtr Clone(AliasValueExpression& node) override; 58 | ExpressionPtr Clone(ConstantExpression& node) override; 59 | ExpressionPtr Clone(FunctionExpression& node) override; 60 | ExpressionPtr Clone(StructTypeExpression& node) override; 61 | ExpressionPtr Clone(VariableValueExpression& node) override; 62 | 63 | void HandleType(ExpressionValue& exprType); 64 | ExpressionType RemapType(const ExpressionType& exprType); 65 | 66 | struct Context; 67 | Context* m_context; 68 | }; 69 | 70 | inline StatementPtr RemapIndices(Statement& statement, const IndexRemapperVisitor::Options& options); 71 | } 72 | 73 | #include 74 | 75 | #endif // NZSL_AST_INDEXREMAPPERVISITOR_HPP 76 | -------------------------------------------------------------------------------- /include/NZSL/Ast/IndexRemapperVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | StatementPtr RemapIndices(Statement& statement, const IndexRemapperVisitor::Options& options) 9 | { 10 | IndexRemapperVisitor visitor; 11 | return visitor.Clone(statement, options); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Module.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_MODULE_HPP 8 | #define NZSL_AST_MODULE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl::Ast 17 | { 18 | class Module; 19 | 20 | using ModulePtr = std::shared_ptr; 21 | 22 | class Module 23 | { 24 | public: 25 | struct ImportedModule; 26 | struct Metadata; 27 | 28 | Module() = default; 29 | inline Module(std::uint32_t shaderLangVersion, std::string moduleName = std::string()); 30 | inline Module(std::shared_ptr metadata, std::vector importedModules = {}); 31 | inline Module(std::shared_ptr metadata, MultiStatementPtr rootNode, std::vector importedModules = {}); 32 | Module(const Module&) = delete; 33 | Module(Module&&) noexcept = default; 34 | ~Module() = default; 35 | 36 | Module& operator=(const Module&) = delete; 37 | Module& operator=(Module&&) noexcept = default; 38 | 39 | struct ImportedModule 40 | { 41 | std::string identifier; 42 | ModulePtr module; 43 | }; 44 | 45 | struct Metadata 46 | { 47 | std::string author; 48 | std::string description; 49 | std::string license; 50 | std::string moduleName; 51 | std::uint32_t shaderLangVersion; 52 | std::vector enabledFeatures; 53 | }; 54 | 55 | std::shared_ptr metadata; 56 | std::vector importedModules; 57 | MultiStatementPtr rootNode; 58 | }; 59 | } 60 | 61 | #include 62 | 63 | #endif // NZSL_AST_MODULE_HPP 64 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Module.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl::Ast 8 | { 9 | inline Module::Module(std::uint32_t shaderLangVersion, std::string moduleName) 10 | { 11 | auto mutMetadata = std::make_shared(); 12 | mutMetadata->moduleName = std::move(moduleName); 13 | mutMetadata->shaderLangVersion = shaderLangVersion; 14 | 15 | metadata = std::move(mutMetadata); 16 | rootNode = ShaderBuilder::MultiStatement(); 17 | } 18 | 19 | inline Module::Module(std::shared_ptr metadata, std::vector importedModules) : 20 | Module(std::move(metadata), ShaderBuilder::MultiStatement(), std::move(importedModules)) 21 | { 22 | } 23 | 24 | inline Module::Module(std::shared_ptr Metadata, MultiStatementPtr RootNode, std::vector ImportedModules) : 25 | metadata(std::move(Metadata)), 26 | importedModules(std::move(ImportedModules)), 27 | rootNode(std::move(RootNode)) 28 | { 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /include/NZSL/Ast/NodeList.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | // no header guards 6 | 7 | #if !defined(NZSL_SHADERAST_NODE) && !defined(NZSL_SHADERAST_EXPRESSION) && !defined(NZSL_SHADERAST_STATEMENT) 8 | #error You must define NZSL_SHADERAST_NODE or NZSL_SHADERAST_EXPRESSION or NZSL_SHADERAST_STATEMENT before including this file 9 | #endif 10 | 11 | #ifndef NZSL_SHADERAST_NODE 12 | #define NZSL_SHADERAST_NODE(X, C) 13 | #endif 14 | 15 | #ifndef NZSL_SHADERAST_NODE_LAST 16 | #define NZSL_SHADERAST_NODE_LAST(X, C) 17 | #endif 18 | 19 | #ifndef NZSL_SHADERAST_EXPRESSION 20 | #define NZSL_SHADERAST_EXPRESSION(X) NZSL_SHADERAST_NODE(X, Expression) 21 | #endif 22 | 23 | #ifndef NZSL_SHADERAST_STATEMENT 24 | #define NZSL_SHADERAST_STATEMENT(X) NZSL_SHADERAST_NODE(X, Statement) 25 | #endif 26 | 27 | #ifndef NZSL_SHADERAST_STATEMENT_LAST 28 | #define NZSL_SHADERAST_STATEMENT_LAST(X) NZSL_SHADERAST_STATEMENT(X) 29 | #endif 30 | 31 | NZSL_SHADERAST_EXPRESSION(AccessIdentifier) 32 | NZSL_SHADERAST_EXPRESSION(AccessIndex) 33 | NZSL_SHADERAST_EXPRESSION(AliasValue) 34 | NZSL_SHADERAST_EXPRESSION(Assign) 35 | NZSL_SHADERAST_EXPRESSION(Binary) 36 | NZSL_SHADERAST_EXPRESSION(CallFunction) 37 | NZSL_SHADERAST_EXPRESSION(CallMethod) 38 | NZSL_SHADERAST_EXPRESSION(Cast) 39 | NZSL_SHADERAST_EXPRESSION(Conditional) 40 | NZSL_SHADERAST_EXPRESSION(Constant) 41 | NZSL_SHADERAST_EXPRESSION(ConstantArrayValue) 42 | NZSL_SHADERAST_EXPRESSION(ConstantValue) 43 | NZSL_SHADERAST_EXPRESSION(Function) 44 | NZSL_SHADERAST_EXPRESSION(Identifier) 45 | NZSL_SHADERAST_EXPRESSION(Intrinsic) 46 | NZSL_SHADERAST_EXPRESSION(IntrinsicFunction) 47 | NZSL_SHADERAST_EXPRESSION(Module) 48 | NZSL_SHADERAST_EXPRESSION(NamedExternalBlock) 49 | NZSL_SHADERAST_EXPRESSION(StructType) 50 | NZSL_SHADERAST_EXPRESSION(Swizzle) 51 | NZSL_SHADERAST_EXPRESSION(Type) 52 | NZSL_SHADERAST_EXPRESSION(VariableValue) 53 | NZSL_SHADERAST_EXPRESSION(Unary) 54 | NZSL_SHADERAST_STATEMENT(Branch) 55 | NZSL_SHADERAST_STATEMENT(Break) 56 | NZSL_SHADERAST_STATEMENT(Conditional) 57 | NZSL_SHADERAST_STATEMENT(Continue) 58 | NZSL_SHADERAST_STATEMENT(DeclareAlias) 59 | NZSL_SHADERAST_STATEMENT(DeclareConst) 60 | NZSL_SHADERAST_STATEMENT(DeclareExternal) 61 | NZSL_SHADERAST_STATEMENT(DeclareFunction) 62 | NZSL_SHADERAST_STATEMENT(DeclareOption) 63 | NZSL_SHADERAST_STATEMENT(DeclareStruct) 64 | NZSL_SHADERAST_STATEMENT(DeclareVariable) 65 | NZSL_SHADERAST_STATEMENT(Discard) 66 | NZSL_SHADERAST_STATEMENT(For) 67 | NZSL_SHADERAST_STATEMENT(ForEach) 68 | NZSL_SHADERAST_STATEMENT(Expression) 69 | NZSL_SHADERAST_STATEMENT(Import) 70 | NZSL_SHADERAST_STATEMENT(Multi) 71 | NZSL_SHADERAST_STATEMENT(NoOp) 72 | NZSL_SHADERAST_STATEMENT(Return) 73 | NZSL_SHADERAST_STATEMENT(Scoped) 74 | NZSL_SHADERAST_STATEMENT_LAST(While) 75 | 76 | #undef NZSL_SHADERAST_EXPRESSION 77 | #undef NZSL_SHADERAST_NODE 78 | #undef NZSL_SHADERAST_NODE_LAST 79 | #undef NZSL_SHADERAST_STATEMENT 80 | #undef NZSL_SHADERAST_STATEMENT_LAST 81 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Nodes.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | inline const ExpressionType* GetExpressionType(const Expression& expr) 9 | { 10 | return (expr.cachedExpressionType) ? &expr.cachedExpressionType.value() : nullptr; 11 | } 12 | 13 | inline ExpressionType* GetExpressionTypeMut(Expression& expr) 14 | { 15 | return (expr.cachedExpressionType) ? &expr.cachedExpressionType.value() : nullptr; 16 | } 17 | 18 | inline bool IsExpression(NodeType nodeType) 19 | { 20 | switch (nodeType) 21 | { 22 | #define NZSL_SHADERAST_EXPRESSION(Node) case NodeType::Node##Expression: return true; 23 | #include 24 | 25 | default: 26 | return false; 27 | } 28 | } 29 | 30 | inline bool IsStatement(NodeType nodeType) 31 | { 32 | switch (nodeType) 33 | { 34 | #define NZSL_SHADERAST_STATEMENT(Node) case NodeType::Node##Statement: return true; 35 | #include 36 | 37 | default: 38 | return false; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Option.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_OPTION_HPP 8 | #define NZSL_AST_OPTION_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace nzsl::Ast 14 | { 15 | using OptionHash = std::uint32_t; 16 | 17 | template constexpr OptionHash HashOption(Args&&... args); 18 | 19 | namespace Literals 20 | { 21 | constexpr OptionHash operator ""_opt(const char* str, std::size_t length); 22 | } 23 | } 24 | 25 | #include 26 | 27 | #endif // NZSL_AST_OPTION_HPP 28 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Option.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | namespace nzsl::Ast 6 | { 7 | template 8 | constexpr OptionHash HashOption(Args&&... args) 9 | { 10 | return Nz::FNV1a32(std::forward(args)...); 11 | } 12 | 13 | namespace Literals 14 | { 15 | constexpr OptionHash operator""_opt(const char* str, std::size_t length) 16 | { 17 | return HashOption(std::string_view(str, length)); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /include/NZSL/Ast/RecursiveVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_RECURSIVEVISITOR_HPP 8 | #define NZSL_AST_RECURSIVEVISITOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nzsl::Ast 15 | { 16 | class NZSL_API RecursiveVisitor : public ExpressionVisitor, public StatementVisitor 17 | { 18 | public: 19 | RecursiveVisitor() = default; 20 | ~RecursiveVisitor() = default; 21 | 22 | void Visit(AccessIdentifierExpression& node) override; 23 | void Visit(AccessIndexExpression& node) override; 24 | void Visit(AliasValueExpression& node) override; 25 | void Visit(AssignExpression& node) override; 26 | void Visit(BinaryExpression& node) override; 27 | void Visit(CallFunctionExpression& node) override; 28 | void Visit(CallMethodExpression& node) override; 29 | void Visit(CastExpression& node) override; 30 | void Visit(ConditionalExpression& node) override; 31 | void Visit(ConstantExpression& node) override; 32 | void Visit(ConstantArrayValueExpression& node) override; 33 | void Visit(ConstantValueExpression& node) override; 34 | void Visit(FunctionExpression& node) override; 35 | void Visit(IdentifierExpression& node) override; 36 | void Visit(IntrinsicExpression& node) override; 37 | void Visit(IntrinsicFunctionExpression& node) override; 38 | void Visit(ModuleExpression& node) override; 39 | void Visit(NamedExternalBlockExpression& node) override; 40 | void Visit(StructTypeExpression& node) override; 41 | void Visit(SwizzleExpression& node) override; 42 | void Visit(TypeExpression& node) override; 43 | void Visit(VariableValueExpression& node) override; 44 | void Visit(UnaryExpression& node) override; 45 | 46 | void Visit(BranchStatement& node) override; 47 | void Visit(BreakStatement& node) override; 48 | void Visit(ConditionalStatement& node) override; 49 | void Visit(ContinueStatement& node) override; 50 | void Visit(DeclareAliasStatement& node) override; 51 | void Visit(DeclareConstStatement& node) override; 52 | void Visit(DeclareExternalStatement& node) override; 53 | void Visit(DeclareFunctionStatement& node) override; 54 | void Visit(DeclareOptionStatement& node) override; 55 | void Visit(DeclareStructStatement& node) override; 56 | void Visit(DeclareVariableStatement& node) override; 57 | void Visit(DiscardStatement& node) override; 58 | void Visit(ExpressionStatement& node) override; 59 | void Visit(ForStatement& node) override; 60 | void Visit(ForEachStatement& node) override; 61 | void Visit(ImportStatement& node) override; 62 | void Visit(MultiStatement& node) override; 63 | void Visit(NoOpStatement& node) override; 64 | void Visit(ReturnStatement& node) override; 65 | void Visit(ScopedStatement& node) override; 66 | void Visit(WhileStatement& node) override; 67 | }; 68 | } 69 | 70 | #include 71 | 72 | #endif // NZSL_AST_RECURSIVEVISITOR_HPP 73 | -------------------------------------------------------------------------------- /include/NZSL/Ast/RecursiveVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ReflectVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_REFLECTVISITOR_HPP 8 | #define NZSL_AST_REFLECTVISITOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl::Ast 17 | { 18 | class NZSL_API ReflectVisitor : public RecursiveVisitor 19 | { 20 | public: 21 | struct Callbacks; 22 | 23 | ReflectVisitor() = default; 24 | ReflectVisitor(const ReflectVisitor&) = delete; 25 | ReflectVisitor(ReflectVisitor&&) = delete; 26 | ~ReflectVisitor() = default; 27 | 28 | void Reflect(const Module& shaderModule, const Callbacks& callbacks); 29 | void Reflect(Statement& statement, const Callbacks& callbacks); 30 | 31 | ReflectVisitor& operator=(const ReflectVisitor&) = delete; 32 | ReflectVisitor& operator=(ReflectVisitor&&) = delete; 33 | 34 | struct Callbacks 35 | { 36 | std::function onEntryPointDeclaration; 37 | 38 | std::function onAliasDeclaration; 39 | std::function onConstDeclaration; 40 | std::function onExternalDeclaration; 41 | std::function onFunctionDeclaration; 42 | std::function onOptionDeclaration; 43 | std::function onStructDeclaration; 44 | std::function onVariableDeclaration; 45 | 46 | std::function onAliasIndex; 47 | std::function onConstIndex; 48 | std::function onFunctionIndex; 49 | std::function onOptionIndex; 50 | std::function onStructIndex; 51 | std::function onVariableIndex; 52 | }; 53 | 54 | private: 55 | void Visit(DeclareAliasStatement& node) override; 56 | void Visit(DeclareConstStatement& node) override; 57 | void Visit(DeclareExternalStatement& node) override; 58 | void Visit(DeclareFunctionStatement& node) override; 59 | void Visit(DeclareOptionStatement& node) override; 60 | void Visit(DeclareStructStatement& node) override; 61 | void Visit(DeclareVariableStatement& node) override; 62 | void Visit(ForStatement& node) override; 63 | void Visit(ForEachStatement& node) override; 64 | 65 | const Callbacks* m_callbacks; 66 | }; 67 | } 68 | 69 | #include 70 | 71 | #endif // NZSL_AST_REFLECTVISITOR_HPP 72 | -------------------------------------------------------------------------------- /include/NZSL/Ast/ReflectVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /include/NZSL/Ast/SanitizeVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | namespace nzsl::Ast 6 | { 7 | inline ModulePtr SanitizeVisitor::Sanitize(const Module& module, std::string* error) 8 | { 9 | return Sanitize(module, {}, error); 10 | } 11 | 12 | inline ModulePtr Sanitize(const Module& module, std::string* error) 13 | { 14 | SanitizeVisitor sanitizer; 15 | return sanitizer.Sanitize(module, error); 16 | } 17 | 18 | inline ModulePtr Sanitize(const Module& module, const SanitizeVisitor::Options& options, std::string* error) 19 | { 20 | SanitizeVisitor sanitizer; 21 | return sanitizer.Sanitize(module, options, error); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /include/NZSL/Ast/StatementVisitor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_STATEMENTVISITOR_HPP 8 | #define NZSL_AST_STATEMENTVISITOR_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace nzsl::Ast 14 | { 15 | class NZSL_API StatementVisitor 16 | { 17 | public: 18 | StatementVisitor() = default; 19 | StatementVisitor(const StatementVisitor&) = delete; 20 | StatementVisitor(StatementVisitor&&) = delete; 21 | virtual ~StatementVisitor(); 22 | 23 | #define NZSL_SHADERAST_STATEMENT(Node) virtual void Visit(Ast::Node##Statement& node) = 0; 24 | #include 25 | 26 | StatementVisitor& operator=(const StatementVisitor&) = delete; 27 | StatementVisitor& operator=(StatementVisitor&&) = delete; 28 | }; 29 | } 30 | 31 | #endif // NZSL_AST_STATEMENTVISITOR_HPP 32 | -------------------------------------------------------------------------------- /include/NZSL/Ast/StatementVisitorExcept.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_STATEMENTVISITOREXCEPT_HPP 8 | #define NZSL_AST_STATEMENTVISITOREXCEPT_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace nzsl::Ast 14 | { 15 | class NZSL_API StatementVisitorExcept : public StatementVisitor 16 | { 17 | public: 18 | using StatementVisitor::Visit; 19 | 20 | #define NZSL_SHADERAST_STATEMENT(Node) void Visit(Ast::Node##Statement& node) override; 21 | #include 22 | }; 23 | } 24 | 25 | #endif // NZSL_AST_STATEMENTVISITOREXCEPT_HPP 26 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Types.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_TYPES_HPP 8 | #define NZSL_AST_TYPES_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace nzsl::Ast 16 | { 17 | enum class TypeParameterCategory 18 | { 19 | ConstantValue, 20 | FullType, 21 | PrimitiveType, 22 | StructType 23 | }; 24 | 25 | struct PartialType; 26 | 27 | using TypeParameter = std::variant; 28 | 29 | struct PartialType 30 | { 31 | std::vector parameters; 32 | std::vector optParameters; 33 | std::function buildFunc; 34 | }; 35 | 36 | } 37 | 38 | #endif // NZSL_AST_TYPES_HPP 39 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Utils.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_AST_UTILS_HPP 8 | #define NZSL_AST_UTILS_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace nzsl::Ast 16 | { 17 | class NZSL_API ValueCategory final : public ExpressionVisitor 18 | { 19 | public: 20 | ValueCategory() = default; 21 | ValueCategory(const ValueCategory&) = delete; 22 | ValueCategory(ValueCategory&&) = delete; 23 | ~ValueCategory() = default; 24 | 25 | ExpressionCategory GetExpressionCategory(Expression& expression); 26 | 27 | ValueCategory& operator=(const ValueCategory&) = delete; 28 | ValueCategory& operator=(ValueCategory&&) = delete; 29 | 30 | private: 31 | using ExpressionVisitor::Visit; 32 | 33 | void Visit(AccessIdentifierExpression& node) override; 34 | void Visit(AccessIndexExpression& node) override; 35 | void Visit(AliasValueExpression& node) override; 36 | void Visit(AssignExpression& node) override; 37 | void Visit(BinaryExpression& node) override; 38 | void Visit(CallFunctionExpression& node) override; 39 | void Visit(CallMethodExpression& node) override; 40 | void Visit(CastExpression& node) override; 41 | void Visit(ConditionalExpression& node) override; 42 | void Visit(ConstantExpression& node) override; 43 | void Visit(ConstantArrayValueExpression& node) override; 44 | void Visit(ConstantValueExpression& node) override; 45 | void Visit(FunctionExpression& node) override; 46 | void Visit(IdentifierExpression& node) override; 47 | void Visit(IntrinsicExpression& node) override; 48 | void Visit(IntrinsicFunctionExpression& node) override; 49 | void Visit(ModuleExpression& node) override; 50 | void Visit(NamedExternalBlockExpression& node) override; 51 | void Visit(StructTypeExpression& node) override; 52 | void Visit(SwizzleExpression& node) override; 53 | void Visit(TypeExpression& node) override; 54 | void Visit(VariableValueExpression& node) override; 55 | void Visit(UnaryExpression& node) override; 56 | 57 | ExpressionCategory m_expressionCategory; 58 | }; 59 | 60 | inline ExpressionCategory GetExpressionCategory(Expression& expression); 61 | } 62 | 63 | #include 64 | 65 | #endif // NZSL_AST_UTILS_HPP 66 | -------------------------------------------------------------------------------- /include/NZSL/Ast/Utils.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl::Ast 7 | { 8 | ExpressionCategory GetExpressionCategory(Expression& expression) 9 | { 10 | ValueCategory visitor; 11 | return visitor.GetExpressionCategory(expression); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /include/NZSL/Config.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Nazara Shading Language (NZSL) 3 | 4 | Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is furnished to do 11 | so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #ifndef NZSL_CONFIG_HPP 28 | #define NZSL_CONFIG_HPP 29 | 30 | #include 31 | 32 | // NZSL version macro 33 | #define NZSL_VERSION_MAJOR 0 34 | #define NZSL_VERSION_MINOR 1 35 | #define NZSL_VERSION_PATCH 0 36 | 37 | #if !defined(NZSL_STATIC) 38 | #ifdef NZSL_BUILD 39 | #define NZSL_API NAZARA_EXPORT 40 | #else 41 | #define NZSL_API NAZARA_IMPORT 42 | #endif 43 | #else 44 | #define NZSL_API 45 | #endif 46 | 47 | #include 48 | 49 | #endif // NZSL_CONFIG_HPP 50 | -------------------------------------------------------------------------------- /include/NZSL/Enums.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_ENUMS_HPP 8 | #define NZSL_ENUMS_HPP 9 | 10 | #include 11 | 12 | namespace nzsl 13 | { 14 | enum class AccessPolicy 15 | { 16 | ReadOnly, 17 | ReadWrite, 18 | WriteOnly 19 | }; 20 | 21 | enum class DebugLevel 22 | { 23 | Full = 3, //< Full + Original source code is embed if possible 24 | Regular = 2, //< Minimal + lines annotations (SPIR-V OpLine) 25 | Minimal = 1, //< Variable names, struct members (SPIR-V OpName and OpMemberName are generated) 26 | None = 0, //< No effort is made to generate debug info (no SPIR-V debug annotation are generated) 27 | }; 28 | 29 | enum class ImageFormat 30 | { 31 | Unknown, 32 | 33 | R11fG11fB10f, 34 | R16, 35 | R16f, 36 | R16i, 37 | R16Snorm, 38 | R16ui, 39 | R32f, 40 | R32i, 41 | R32ui, 42 | R64i, 43 | R64ui, 44 | R8, 45 | R8i, 46 | R8Snorm, 47 | R8ui, 48 | RG16, 49 | RG16f, 50 | RG16i, 51 | RG16Snorm, 52 | RG16ui, 53 | RG32f, 54 | RG32i, 55 | RG32ui, 56 | RG8, 57 | RG8i, 58 | RG8Snorm, 59 | RG8ui, 60 | RGB10A2, 61 | RGB10a2ui, 62 | RGBA16, 63 | RGBA16f, 64 | RGBA16i, 65 | RGBA16Snorm, 66 | RGBA16ui, 67 | RGBA32f, 68 | RGBA32i, 69 | RGBA32ui, 70 | RGBA8, 71 | RGBA8i, 72 | RGBA8Snorm, 73 | RGBA8ui, 74 | 75 | Max = RGBA8ui 76 | }; 77 | 78 | constexpr std::size_t ImageFormatCount = static_cast(ImageFormat::Max) + 1; 79 | 80 | enum class ImageType 81 | { 82 | E1D, 83 | E1D_Array, 84 | E2D, 85 | E2D_Array, 86 | E3D, 87 | Cubemap, 88 | 89 | Max = Cubemap 90 | }; 91 | 92 | constexpr std::size_t ImageTypeCount = static_cast(ImageType::Max) + 1; 93 | 94 | enum class ShaderStageType 95 | { 96 | Compute, 97 | Fragment, 98 | Vertex, 99 | 100 | Max = Vertex 101 | }; 102 | 103 | constexpr std::size_t ShaderStageTypeCount = static_cast(ShaderStageType::Max) + 1; 104 | 105 | constexpr bool EnableEnumAsNzFlags(ShaderStageType) { return true; } 106 | 107 | using ShaderStageTypeFlags = Nz::Flags; 108 | 109 | constexpr ShaderStageTypeFlags ShaderStageType_All = ShaderStageType::Compute | ShaderStageType::Fragment | ShaderStageType::Vertex; 110 | 111 | enum class StructFieldType 112 | { 113 | Bool1, 114 | Bool2, 115 | Bool3, 116 | Bool4, 117 | Float1, 118 | Float2, 119 | Float3, 120 | Float4, 121 | Double1, 122 | Double2, 123 | Double3, 124 | Double4, 125 | Int1, 126 | Int2, 127 | Int3, 128 | Int4, 129 | UInt1, 130 | UInt2, 131 | UInt3, 132 | UInt4, 133 | 134 | Max = UInt4 135 | }; 136 | 137 | enum class StructLayout 138 | { 139 | Packed, 140 | Std140, 141 | Std430, 142 | Scalar, 143 | 144 | Max = Scalar, 145 | }; 146 | } 147 | 148 | #endif // NZSL_ENUMS_HPP 149 | -------------------------------------------------------------------------------- /include/NZSL/FilesystemModuleResolver.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_FILESYSTEMMODULERESOLVER_HPP 8 | #define NZSL_FILESYSTEMMODULERESOLVER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace nzsl 19 | { 20 | class Archive; 21 | 22 | class NZSL_API FilesystemModuleResolver : public ModuleResolver 23 | { 24 | public: 25 | FilesystemModuleResolver() = default; 26 | FilesystemModuleResolver(const FilesystemModuleResolver&) = delete; 27 | FilesystemModuleResolver(FilesystemModuleResolver&&) noexcept = delete; 28 | ~FilesystemModuleResolver(); 29 | 30 | void RegisterArchive(const Archive& archive); 31 | void RegisterDirectory(const std::filesystem::path& realPath, bool watchDirectory = false); 32 | void RegisterFile(const std::filesystem::path& realPath); 33 | void RegisterModule(std::string_view moduleSource); 34 | void RegisterModule(Ast::ModulePtr module); 35 | 36 | Ast::ModulePtr Resolve(const std::string& moduleName) override; 37 | 38 | FilesystemModuleResolver& operator=(const FilesystemModuleResolver&) = delete; 39 | FilesystemModuleResolver& operator=(FilesystemModuleResolver&&) noexcept = delete; 40 | 41 | static constexpr const char* ArchiveExtension = ".nzsla"; 42 | static constexpr const char* BinaryModuleExtension = ".nzslb"; 43 | static constexpr const char* ModuleExtension = ".nzsl"; 44 | 45 | private: 46 | void OnFileAdded(std::string_view directory, std::string_view filename); 47 | void OnFileRemoved(std::string_view directory, std::string_view filename); 48 | void OnFileMoved(std::string_view directory, std::string_view filename, std::string_view oldFilename); 49 | void OnFileUpdated(std::string_view directory, std::string_view filename); 50 | 51 | static bool CheckExtension(std::string_view filename); 52 | 53 | std::recursive_mutex m_moduleLock; 54 | std::unordered_map m_moduleByFilepath; 55 | std::unordered_map m_modules; 56 | Nz::MovablePtr m_fileWatcher; 57 | }; 58 | } 59 | 60 | #include 61 | 62 | #endif // NZSL_FILESYSTEMMODULERESOLVER_HPP 63 | -------------------------------------------------------------------------------- /include/NZSL/FilesystemModuleResolver.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /include/NZSL/GlslWriter.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | namespace nzsl 6 | { 7 | inline GlslWriter::GlslWriter() : 8 | m_currentState(nullptr) 9 | { 10 | } 11 | 12 | inline auto GlslWriter::Generate(const Ast::Module& shader, const Parameters& parameters, const States& states) -> Output 13 | { 14 | return Generate(std::nullopt, shader, parameters, states); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /include/NZSL/Lang/Errors.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline Error::Error(SourceLocation sourceLocation, ErrorCategory errorCategory, ErrorType errorType) noexcept : 9 | m_errorCategory(errorCategory), 10 | m_sourceLocation(std::move(sourceLocation)), 11 | m_errorType(errorType) 12 | { 13 | } 14 | 15 | inline ErrorCategory Error::GetErrorCategory() const 16 | { 17 | return m_errorCategory; 18 | } 19 | 20 | inline ErrorType Error::GetErrorType() const 21 | { 22 | return m_errorType; 23 | } 24 | 25 | inline const SourceLocation& Error::GetSourceLocation() const 26 | { 27 | return m_sourceLocation; 28 | } 29 | 30 | 31 | inline AstError::AstError(SourceLocation sourceLocation, ErrorType errorType) noexcept : 32 | Error(std::move(sourceLocation), ErrorCategory::Ast, errorType) 33 | { 34 | } 35 | 36 | inline CompilationError::CompilationError(SourceLocation sourceLocation, ErrorType errorType) noexcept : 37 | Error(std::move(sourceLocation), ErrorCategory::Compilation, errorType) 38 | { 39 | } 40 | 41 | inline ParsingError::ParsingError(SourceLocation sourceLocation, ErrorType errorType) noexcept : 42 | Error(std::move(sourceLocation), ErrorCategory::Parsing, errorType) 43 | { 44 | } 45 | 46 | inline LexingError::LexingError(SourceLocation sourceLocation, ErrorType errorType) noexcept : 47 | Error(std::move(sourceLocation), ErrorCategory::Lexing, errorType) 48 | { 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /include/NZSL/Lang/SourceLocation.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_LANG_SOURCELOCATION_HPP 8 | #define NZSL_LANG_SOURCELOCATION_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nzsl 15 | { 16 | struct SourceLocation 17 | { 18 | inline SourceLocation(); 19 | inline SourceLocation(unsigned int line, unsigned int column, std::shared_ptr file); 20 | inline SourceLocation(unsigned int line, unsigned int startColumn, unsigned int endColumn, std::shared_ptr file); 21 | inline SourceLocation(unsigned int startLine, unsigned int endLine, unsigned int startColumn, unsigned int endColumn, std::shared_ptr file); 22 | 23 | inline void ExtendToLeft(const SourceLocation& leftLocation); 24 | inline void ExtendToRight(const SourceLocation& rightLocation); 25 | 26 | inline bool IsValid() const; 27 | 28 | bool operator==(const SourceLocation& other) const; 29 | bool operator!=(const SourceLocation& other) const; 30 | 31 | static inline SourceLocation BuildFromTo(const SourceLocation& leftSource, const SourceLocation& rightSource); 32 | 33 | std::shared_ptr file; //< Since the same file will be used for every node, prevent storing X time the same path 34 | std::uint32_t endColumn; 35 | std::uint32_t endLine; 36 | std::uint32_t startColumn; 37 | std::uint32_t startLine; 38 | }; 39 | } 40 | 41 | #include 42 | 43 | #endif // NZSL_LANG_SOURCELOCATION_HPP 44 | -------------------------------------------------------------------------------- /include/NZSL/Lang/SourceLocation.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl 8 | { 9 | inline SourceLocation::SourceLocation() : 10 | endColumn(0), 11 | endLine(0), 12 | startColumn(0), 13 | startLine(0) 14 | { 15 | } 16 | 17 | inline SourceLocation::SourceLocation(unsigned int Line, unsigned int Column, std::shared_ptr File) : 18 | file(std::move(File)), 19 | endColumn(Column), 20 | endLine(Line), 21 | startColumn(Column), 22 | startLine(Line) 23 | { 24 | } 25 | 26 | inline SourceLocation::SourceLocation(unsigned int Line, unsigned int StartColumn, unsigned int EndColumn, std::shared_ptr File) : 27 | file(std::move(File)), 28 | endColumn(EndColumn), 29 | endLine(Line), 30 | startColumn(StartColumn), 31 | startLine(Line) 32 | { 33 | } 34 | 35 | inline SourceLocation::SourceLocation(unsigned int StartLine, unsigned int EndLine, unsigned int StartColumn, unsigned int EndColumn, std::shared_ptr File) : 36 | file(std::move(File)), 37 | endColumn(EndColumn), 38 | endLine(EndLine), 39 | startColumn(StartColumn), 40 | startLine(StartLine) 41 | { 42 | } 43 | 44 | inline void SourceLocation::ExtendToLeft(const SourceLocation& leftLocation) 45 | { 46 | assert(file == leftLocation.file); 47 | assert(leftLocation.startLine <= endLine); 48 | startLine = leftLocation.startLine; 49 | assert(leftLocation.startLine < endLine || leftLocation.startColumn <= endColumn); 50 | startColumn = leftLocation.startColumn; 51 | } 52 | 53 | inline void SourceLocation::ExtendToRight(const SourceLocation& rightLocation) 54 | { 55 | assert(file == rightLocation.file); 56 | assert(rightLocation.endLine >= startLine); 57 | endLine = rightLocation.endLine; 58 | assert(rightLocation.endLine > startLine || rightLocation.endColumn >= startColumn); 59 | endColumn = rightLocation.endColumn; 60 | } 61 | 62 | inline SourceLocation SourceLocation::BuildFromTo(const SourceLocation& leftSource, const SourceLocation& rightSource) 63 | { 64 | assert(leftSource.file == rightSource.file); 65 | assert(leftSource.startLine <= rightSource.endLine); 66 | assert(leftSource.startLine < rightSource.endLine || leftSource.startColumn <= rightSource.endColumn); 67 | 68 | SourceLocation sourceLoc; 69 | sourceLoc.file = leftSource.file; 70 | sourceLoc.startLine = leftSource.startLine; 71 | sourceLoc.startColumn = leftSource.startColumn; 72 | sourceLoc.endLine = rightSource.endLine; 73 | sourceLoc.endColumn = rightSource.endColumn; 74 | 75 | return sourceLoc; 76 | } 77 | 78 | inline bool SourceLocation::IsValid() const 79 | { 80 | return startLine != 0 || endLine != 0 || endColumn != 0 || startColumn != 0; 81 | } 82 | 83 | inline bool SourceLocation::operator==(const SourceLocation& other) const 84 | { 85 | return file == other.file && endColumn == other.endColumn && endLine == other.endLine && startColumn == other.startColumn && startLine == other.startLine; 86 | } 87 | 88 | inline bool SourceLocation::operator!=(const SourceLocation& other) const 89 | { 90 | return !operator==(other); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /include/NZSL/Lang/TokenList.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | // no header guards 6 | 7 | #if !defined(NZSL_SHADERLANG_TOKEN) 8 | #error You must define NZSL_SHADERLANG_TOKEN before including this file 9 | #endif 10 | 11 | #ifndef NZSL_SHADERLANG_TOKEN_LAST 12 | #define NZSL_SHADERLANG_TOKEN_LAST(X) NZSL_SHADERLANG_TOKEN(X) 13 | #endif 14 | 15 | NZSL_SHADERLANG_TOKEN(Alias) 16 | NZSL_SHADERLANG_TOKEN(Arrow) 17 | NZSL_SHADERLANG_TOKEN(As) 18 | NZSL_SHADERLANG_TOKEN(Assign) 19 | NZSL_SHADERLANG_TOKEN(BitwiseNot) 20 | NZSL_SHADERLANG_TOKEN(BitwiseAnd) 21 | NZSL_SHADERLANG_TOKEN(BitwiseOr) 22 | NZSL_SHADERLANG_TOKEN(BitwiseXor) 23 | NZSL_SHADERLANG_TOKEN(BoolFalse) 24 | NZSL_SHADERLANG_TOKEN(BoolTrue) 25 | NZSL_SHADERLANG_TOKEN(Break) 26 | NZSL_SHADERLANG_TOKEN(ClosingParenthesis) 27 | NZSL_SHADERLANG_TOKEN(ClosingCurlyBracket) 28 | NZSL_SHADERLANG_TOKEN(ClosingSquareBracket) 29 | NZSL_SHADERLANG_TOKEN(Colon) 30 | NZSL_SHADERLANG_TOKEN(Comma) 31 | NZSL_SHADERLANG_TOKEN(Const) 32 | NZSL_SHADERLANG_TOKEN(ConstSelect) 33 | NZSL_SHADERLANG_TOKEN(Continue) 34 | NZSL_SHADERLANG_TOKEN(Discard) 35 | NZSL_SHADERLANG_TOKEN(Divide) 36 | NZSL_SHADERLANG_TOKEN(DivideAssign) 37 | NZSL_SHADERLANG_TOKEN(Dot) 38 | NZSL_SHADERLANG_TOKEN(Equal) 39 | NZSL_SHADERLANG_TOKEN(Else) 40 | NZSL_SHADERLANG_TOKEN(EndOfStream) 41 | NZSL_SHADERLANG_TOKEN(External) 42 | NZSL_SHADERLANG_TOKEN(FloatingPointValue) 43 | NZSL_SHADERLANG_TOKEN(For) 44 | NZSL_SHADERLANG_TOKEN(From) 45 | NZSL_SHADERLANG_TOKEN(FunctionDeclaration) 46 | NZSL_SHADERLANG_TOKEN(GreaterThan) 47 | NZSL_SHADERLANG_TOKEN(GreaterThanEqual) 48 | NZSL_SHADERLANG_TOKEN(IntegerValue) 49 | NZSL_SHADERLANG_TOKEN(Identifier) 50 | NZSL_SHADERLANG_TOKEN(If) 51 | NZSL_SHADERLANG_TOKEN(Import) 52 | NZSL_SHADERLANG_TOKEN(In) 53 | NZSL_SHADERLANG_TOKEN(InOut) 54 | NZSL_SHADERLANG_TOKEN(LessThan) 55 | NZSL_SHADERLANG_TOKEN(LessThanEqual) 56 | NZSL_SHADERLANG_TOKEN(Let) 57 | NZSL_SHADERLANG_TOKEN(LogicalAnd) 58 | NZSL_SHADERLANG_TOKEN(LogicalAndAssign) 59 | NZSL_SHADERLANG_TOKEN(LogicalOr) 60 | NZSL_SHADERLANG_TOKEN(LogicalOrAssign) 61 | NZSL_SHADERLANG_TOKEN(Multiply) 62 | NZSL_SHADERLANG_TOKEN(MultiplyAssign) 63 | NZSL_SHADERLANG_TOKEN(Minus) 64 | NZSL_SHADERLANG_TOKEN(MinusAssign) 65 | NZSL_SHADERLANG_TOKEN(Module) 66 | NZSL_SHADERLANG_TOKEN(Modulo) 67 | NZSL_SHADERLANG_TOKEN(ModuloAssign) 68 | NZSL_SHADERLANG_TOKEN(Not) 69 | NZSL_SHADERLANG_TOKEN(NotEqual) 70 | NZSL_SHADERLANG_TOKEN(Plus) 71 | NZSL_SHADERLANG_TOKEN(PlusAssign) 72 | NZSL_SHADERLANG_TOKEN(OpenCurlyBracket) 73 | NZSL_SHADERLANG_TOKEN(OpenSquareBracket) 74 | NZSL_SHADERLANG_TOKEN(OpenParenthesis) 75 | NZSL_SHADERLANG_TOKEN(Option) 76 | NZSL_SHADERLANG_TOKEN(Out) 77 | NZSL_SHADERLANG_TOKEN(Return) 78 | NZSL_SHADERLANG_TOKEN(Semicolon) 79 | NZSL_SHADERLANG_TOKEN(ShiftLeft) 80 | NZSL_SHADERLANG_TOKEN(ShiftRight) 81 | NZSL_SHADERLANG_TOKEN(StringValue) 82 | NZSL_SHADERLANG_TOKEN(Struct) 83 | NZSL_SHADERLANG_TOKEN(While) 84 | 85 | #undef NZSL_SHADERLANG_TOKEN 86 | #undef NZSL_SHADERLANG_TOKEN_LAST 87 | -------------------------------------------------------------------------------- /include/NZSL/LangWriter.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline LangWriter::LangWriter() : 9 | m_currentState(nullptr) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /include/NZSL/Lexer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_LEXER_HPP 8 | #define NZSL_LEXER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace nzsl 19 | { 20 | enum class TokenType 21 | { 22 | #define NZSL_SHADERLANG_TOKEN(X) X, 23 | 24 | #include 25 | }; 26 | 27 | struct Token 28 | { 29 | SourceLocation location; 30 | TokenType type; 31 | std::variant data; 32 | }; 33 | 34 | NZSL_API std::string EscapeString(std::string_view str, bool quote = true); 35 | 36 | NZSL_API std::vector Tokenize(std::string_view str, const std::string& filePath = std::string{}); 37 | NZSL_API const char* ToString(TokenType tokenType); 38 | NZSL_API std::string ToString(const std::vector& tokens, bool pretty = true); 39 | } 40 | 41 | #include 42 | 43 | #endif // NZSL_LEXER_HPP 44 | -------------------------------------------------------------------------------- /include/NZSL/Lexer.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /include/NZSL/Math/FieldOffsets.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_MATH_FIELDOFFSETS_HPP 8 | #define NZSL_MATH_FIELDOFFSETS_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nzsl 15 | { 16 | class FieldOffsets 17 | { 18 | public: 19 | constexpr FieldOffsets(StructLayout layout); 20 | constexpr FieldOffsets(const FieldOffsets&) = default; 21 | constexpr FieldOffsets(FieldOffsets&&) = default; 22 | ~FieldOffsets() = default; 23 | 24 | constexpr std::size_t AddField(StructFieldType type); 25 | constexpr std::size_t AddFieldArray(StructFieldType type, std::size_t arraySize); 26 | constexpr std::size_t AddMatrix(StructFieldType cellType, unsigned int columns, unsigned int rows, bool columnMajor); 27 | constexpr std::size_t AddMatrixArray(StructFieldType cellType, unsigned int columns, unsigned int rows, bool columnMajor, std::size_t arraySize); 28 | constexpr std::size_t AddStruct(const FieldOffsets& fieldStruct); 29 | constexpr std::size_t AddStructArray(const FieldOffsets& fieldStruct, std::size_t arraySize); 30 | 31 | constexpr std::size_t GetAlignedSize() const; 32 | constexpr std::size_t GetLargestFieldAlignement() const; 33 | constexpr StructLayout GetLayout() const; 34 | constexpr std::size_t GetSize() const; 35 | 36 | constexpr FieldOffsets& operator=(const FieldOffsets&) = default; 37 | constexpr FieldOffsets& operator=(FieldOffsets&&) = default; 38 | 39 | static constexpr std::size_t GetAlignement(StructLayout layout, StructFieldType fieldType); 40 | static constexpr std::size_t GetCount(StructFieldType fieldType); 41 | static constexpr std::size_t GetSize(StructFieldType fieldType); 42 | 43 | private: 44 | std::size_t m_largestFieldAlignment; 45 | std::size_t m_offsetRounding; 46 | std::size_t m_size; 47 | StructLayout m_layout; 48 | }; 49 | } 50 | 51 | #include 52 | 53 | #endif // NZSL_MATH_FIELDOFFSETS_HPP 54 | -------------------------------------------------------------------------------- /include/NZSL/ModuleResolver.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_MODULERESOLVER_HPP 8 | #define NZSL_MODULERESOLVER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | namespace Ast 19 | { 20 | using ModulePtr = std::shared_ptr; 21 | } 22 | 23 | class NZSL_API ModuleResolver 24 | { 25 | public: 26 | ModuleResolver() = default; 27 | ModuleResolver(const ModuleResolver&) = default; 28 | ModuleResolver(ModuleResolver&&) = default; 29 | virtual ~ModuleResolver(); 30 | 31 | virtual Ast::ModulePtr Resolve(const std::string& /*moduleName*/) = 0; 32 | 33 | ModuleResolver& operator=(const ModuleResolver&) = default; 34 | ModuleResolver& operator=(ModuleResolver&&) = default; 35 | 36 | NazaraSignal(OnModuleUpdated, ModuleResolver* /*resolver*/, const std::string& /*moduleName*/); 37 | }; 38 | } 39 | 40 | #include 41 | 42 | #endif // NZSL_MODULERESOLVER_HPP 43 | -------------------------------------------------------------------------------- /include/NZSL/ModuleResolver.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /include/NZSL/Parser.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline Parser::Parser() : 9 | m_context(nullptr) 10 | { 11 | } 12 | 13 | inline Ast::ModulePtr Parse(std::string_view source, const std::string& filePath) 14 | { 15 | return Parse(Tokenize(source, filePath)); 16 | } 17 | 18 | inline Ast::ModulePtr Parse(const std::vector& tokens) 19 | { 20 | Parser parser; 21 | return parser.Parse(tokens); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /include/NZSL/Serializer.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl 8 | { 9 | inline const std::vector& Serializer::GetData() const& 10 | { 11 | return m_data; 12 | } 13 | 14 | inline std::vector Serializer::GetData() && 15 | { 16 | return std::move(m_data); 17 | } 18 | 19 | inline Deserializer::Deserializer(const void* data, std::size_t dataSize) 20 | { 21 | m_ptr = static_cast(data); 22 | m_ptrBegin = m_ptr; 23 | m_ptrEnd = m_ptr + dataSize; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /include/NZSL/ShaderWriter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SHADERWRITER_HPP 8 | #define NZSL_SHADERWRITER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class ModuleResolver; 19 | 20 | class NZSL_API ShaderWriter 21 | { 22 | public: 23 | struct States; 24 | 25 | ShaderWriter() = default; 26 | ShaderWriter(const ShaderWriter&) = default; 27 | ShaderWriter(ShaderWriter&&) = default; 28 | virtual ~ShaderWriter(); 29 | 30 | struct States 31 | { 32 | std::shared_ptr shaderModuleResolver; 33 | std::unordered_map optionValues; 34 | DebugLevel debugLevel = DebugLevel::Minimal; 35 | bool optimize = false; 36 | bool sanitized = false; 37 | }; 38 | }; 39 | } 40 | 41 | #endif // NZSL_SHADERWRITER_HPP 42 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvAstVisitor.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl 8 | { 9 | inline SpirvAstVisitor::SpirvAstVisitor(SpirvWriter& writer, SpirvSection& instructions, std::function functionRetriever) : 10 | m_functionRetriever(std::move(functionRetriever)), 11 | m_currentBlock(nullptr), 12 | m_instructions(instructions), 13 | m_writer(writer), 14 | m_isEvaluatingPointer(false) 15 | { 16 | } 17 | 18 | inline void SpirvAstVisitor::RegisterVariable(std::size_t varIndex, SpirvConstantCache::TypePtr typePtr, std::uint32_t typeId, std::uint32_t pointerId, SpirvStorageClass storageClass) 19 | { 20 | assert(m_variables.find(varIndex) == m_variables.end()); 21 | m_variables[varIndex] = SpirvVariable{ 22 | pointerId, 23 | typeId, 24 | std::move(typePtr), 25 | storageClass 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvBlock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVBLOCK_HPP 8 | #define NZSL_SPIRV_SPIRVBLOCK_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class NZSL_API SpirvBlock : public SpirvSectionBase 19 | { 20 | public: 21 | inline SpirvBlock(SpirvWriter& writer); 22 | SpirvBlock(const SpirvBlock&) = default; 23 | SpirvBlock(SpirvBlock&&) = default; 24 | ~SpirvBlock() = default; 25 | 26 | inline std::size_t Append(SpirvOp opcode, const OpSize& wordCount); 27 | template std::size_t Append(SpirvOp opcode, Args&&... args); 28 | template std::size_t AppendVariadic(SpirvOp opcode, F&& callback); 29 | 30 | inline std::uint32_t GetLabelId() const; 31 | 32 | inline bool IsTerminated() const; 33 | 34 | SpirvBlock& operator=(const SpirvBlock&) = delete; 35 | SpirvBlock& operator=(SpirvBlock&&) = default; 36 | 37 | static inline bool IsTerminationInstruction(SpirvOp op); 38 | 39 | private: 40 | inline void HandleSpirvOp(SpirvOp op); 41 | 42 | std::uint32_t m_labelId; 43 | bool m_isTerminated; 44 | }; 45 | } 46 | 47 | #include 48 | 49 | #endif // NZSL_SPIRV_SPIRVBLOCK_HPP 50 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvBlock.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline SpirvBlock::SpirvBlock(SpirvWriter& writer) : 9 | m_isTerminated(false) 10 | { 11 | m_labelId = writer.AllocateResultId(); 12 | Append(SpirvOp::OpLabel, m_labelId); 13 | } 14 | 15 | inline std::size_t SpirvBlock::Append(SpirvOp opcode, const OpSize& wordCount) 16 | { 17 | HandleSpirvOp(opcode); 18 | 19 | return SpirvSectionBase::Append(opcode, wordCount); 20 | } 21 | 22 | template 23 | std::size_t SpirvBlock::Append(SpirvOp opcode, Args&&... args) 24 | { 25 | HandleSpirvOp(opcode); 26 | 27 | return SpirvSectionBase::Append(opcode, std::forward(args)...); 28 | } 29 | 30 | template 31 | std::size_t SpirvBlock::AppendVariadic(SpirvOp opcode, F&& callback) 32 | { 33 | HandleSpirvOp(opcode); 34 | 35 | return SpirvSectionBase::AppendVariadic(opcode, std::forward(callback)); 36 | } 37 | 38 | inline std::uint32_t SpirvBlock::GetLabelId() const 39 | { 40 | return m_labelId; 41 | } 42 | 43 | inline bool SpirvBlock::IsTerminated() const 44 | { 45 | return m_isTerminated; 46 | } 47 | 48 | inline bool SpirvBlock::IsTerminationInstruction(SpirvOp op) 49 | { 50 | switch (op) 51 | { 52 | case SpirvOp::OpBranch: 53 | case SpirvOp::OpBranchConditional: 54 | case SpirvOp::OpKill: 55 | case SpirvOp::OpReturn: 56 | case SpirvOp::OpReturnValue: 57 | case SpirvOp::OpSwitch: 58 | case SpirvOp::OpUnreachable: 59 | return true; 60 | 61 | default: 62 | return false; 63 | } 64 | } 65 | 66 | inline void SpirvBlock::HandleSpirvOp(SpirvOp op) 67 | { 68 | assert(!m_isTerminated); 69 | if (IsTerminationInstruction(op)) 70 | m_isTerminated = true; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvConstantCache.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | template<> 9 | struct SpirvConstantCache::TypeBuilder 10 | { 11 | static Type Build() 12 | { 13 | return Type{ Bool{} }; 14 | } 15 | }; 16 | 17 | template 18 | struct SpirvConstantCache::TypeBuilder>> 19 | { 20 | static Type Build() 21 | { 22 | return { Float{ sizeof(T) * CHAR_BIT } }; 23 | } 24 | }; 25 | 26 | template 27 | struct SpirvConstantCache::TypeBuilder>> 28 | { 29 | static Type Build() 30 | { 31 | return { Integer{ sizeof(T) * CHAR_BIT, std::is_signed_v } }; 32 | } 33 | }; 34 | 35 | template 36 | struct SpirvConstantCache::TypeBuilder> 37 | { 38 | static Type Build() 39 | { 40 | return { Vector{ std::make_shared(BuildSingleType()), Nz::SafeCast(N) } }; 41 | } 42 | }; 43 | 44 | template 45 | auto SpirvConstantCache::BuildSingleType() -> Type 46 | { 47 | if constexpr (std::is_same_v) 48 | throw std::runtime_error("invalid type (value expected)"); 49 | else if constexpr (std::is_same_v) 50 | throw std::runtime_error("unexpected string literal"); 51 | else 52 | return TypeBuilder::Build(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvDecoder.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVDECODER_HPP 8 | #define NZSL_SPIRV_SPIRVDECODER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class NZSL_API SpirvDecoder 19 | { 20 | public: 21 | SpirvDecoder() = default; 22 | SpirvDecoder(const SpirvDecoder&) = default; 23 | SpirvDecoder(SpirvDecoder&&) = default; 24 | ~SpirvDecoder() = default; 25 | 26 | void Decode(const std::uint32_t* codepoints, std::size_t count); 27 | 28 | SpirvDecoder& operator=(const SpirvDecoder&) = default; 29 | SpirvDecoder& operator=(SpirvDecoder&&) = default; 30 | 31 | protected: 32 | struct SpirvHeader; 33 | 34 | inline const std::uint32_t* GetCurrentPtr() const; 35 | 36 | virtual bool HandleHeader(const SpirvHeader& header); 37 | virtual bool HandleOpcode(const SpirvInstruction& instruction, std::uint32_t wordCount) = 0; 38 | 39 | std::string ReadString(); 40 | std::uint32_t ReadWord(); 41 | 42 | inline void ResetPtr(const std::uint32_t* codepoint); 43 | 44 | struct SpirvHeader 45 | { 46 | std::uint32_t generatorId; 47 | std::uint32_t bound; 48 | std::uint32_t schema; 49 | std::uint32_t versionNumber; 50 | }; 51 | 52 | private: 53 | const std::uint32_t* m_currentCodepoint; 54 | const std::uint32_t* m_codepointEnd; 55 | }; 56 | } 57 | 58 | #include 59 | 60 | #endif // NZSL_SPIRV_SPIRVDECODER_HPP 61 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvDecoder.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline const std::uint32_t* SpirvDecoder::GetCurrentPtr() const 9 | { 10 | return m_currentCodepoint; 11 | } 12 | 13 | inline void SpirvDecoder::ResetPtr(const std::uint32_t* codepoint) 14 | { 15 | m_currentCodepoint = codepoint; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvExpressionLoad.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVEXPRESSIONLOAD_HPP 8 | #define NZSL_SPIRV_SPIRVEXPRESSIONLOAD_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class SpirvAstVisitor; 19 | class SpirvBlock; 20 | class SpirvWriter; 21 | 22 | class NZSL_API SpirvExpressionLoad : public Ast::ExpressionVisitorExcept 23 | { 24 | public: 25 | inline SpirvExpressionLoad(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block); 26 | SpirvExpressionLoad(const SpirvExpressionLoad&) = delete; 27 | SpirvExpressionLoad(SpirvExpressionLoad&&) = delete; 28 | ~SpirvExpressionLoad() = default; 29 | 30 | std::uint32_t EvaluatePointer(Ast::Expression& node); 31 | std::uint32_t EvaluateValue(Ast::Expression& node); 32 | 33 | using ExpressionVisitorExcept::Visit; 34 | void Visit(Ast::AccessIndexExpression& node) override; 35 | void Visit(Ast::ConstantExpression& node) override; 36 | void Visit(Ast::VariableValueExpression& node) override; 37 | 38 | SpirvExpressionLoad& operator=(const SpirvExpressionLoad&) = delete; 39 | SpirvExpressionLoad& operator=(SpirvExpressionLoad&&) = delete; 40 | 41 | private: 42 | struct CompositeExtraction 43 | { 44 | std::vector indices; 45 | std::uint32_t typeId; 46 | std::uint32_t valueId; 47 | }; 48 | 49 | struct PointerChainAccess 50 | { 51 | std::vector indicesId; 52 | const Ast::ExpressionType* exprType; 53 | SpirvConstantCache::TypePtr pointedTypePtr; 54 | SpirvStorageClass storage; 55 | std::uint32_t pointerId; 56 | std::uint32_t pointedTypeId; 57 | }; 58 | 59 | struct Pointer 60 | { 61 | SpirvConstantCache::TypePtr pointedTypePtr; 62 | SpirvStorageClass storage; 63 | std::uint32_t pointerId; 64 | std::uint32_t pointedTypeId; 65 | }; 66 | 67 | struct Value 68 | { 69 | std::uint32_t valueId; 70 | }; 71 | 72 | SpirvAstVisitor& m_visitor; 73 | SpirvBlock& m_block; 74 | SpirvWriter& m_writer; 75 | std::variant m_value; 76 | }; 77 | } 78 | 79 | #include 80 | 81 | #endif // NZSL_SPIRV_SPIRVEXPRESSIONLOAD_HPP 82 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvExpressionLoad.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline SpirvExpressionLoad::SpirvExpressionLoad(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block) : 9 | m_visitor(visitor), 10 | m_block(block), 11 | m_writer(writer) 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvExpressionStore.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVEXPRESSIONSTORE_HPP 8 | #define NZSL_SPIRV_SPIRVEXPRESSIONSTORE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class SpirvAstVisitor; 19 | class SpirvBlock; 20 | class SpirvWriter; 21 | 22 | class NZSL_API SpirvExpressionStore : public Ast::ExpressionVisitorExcept 23 | { 24 | public: 25 | inline SpirvExpressionStore(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block); 26 | SpirvExpressionStore(const SpirvExpressionStore&) = delete; 27 | SpirvExpressionStore(SpirvExpressionStore&&) = delete; 28 | ~SpirvExpressionStore() = default; 29 | 30 | void Store(Ast::ExpressionPtr& node, std::uint32_t resultId); 31 | 32 | using ExpressionVisitorExcept::Visit; 33 | void Visit(Ast::AccessIndexExpression& node) override; 34 | void Visit(Ast::SwizzleExpression& node) override; 35 | void Visit(Ast::VariableValueExpression& node) override; 36 | 37 | SpirvExpressionStore& operator=(const SpirvExpressionStore&) = delete; 38 | SpirvExpressionStore& operator=(SpirvExpressionStore&&) = delete; 39 | 40 | private: 41 | struct Pointer 42 | { 43 | SpirvConstantCache::TypePtr pointedTypePtr; 44 | SpirvStorageClass storage; 45 | std::uint32_t pointerId; 46 | }; 47 | 48 | struct SwizzledPointer : Pointer 49 | { 50 | Ast::VectorType swizzledType; 51 | std::array swizzleIndices; 52 | std::size_t componentCount; 53 | }; 54 | 55 | SpirvAstVisitor& m_visitor; 56 | SpirvBlock& m_block; 57 | SpirvWriter& m_writer; 58 | std::variant m_value; 59 | }; 60 | } 61 | 62 | #include 63 | 64 | #endif // NZSL_SPIRV_SPIRVEXPRESSIONSTORE_HPP 65 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvExpressionStore.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline SpirvExpressionStore::SpirvExpressionStore(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block) : 9 | m_visitor(visitor), 10 | m_block(block), 11 | m_writer(writer) 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvPrinter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVPRINTER_HPP 8 | #define NZSL_SPIRV_SPIRVPRINTER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class NZSL_API SpirvPrinter : SpirvDecoder 19 | { 20 | public: 21 | struct Settings; 22 | 23 | inline SpirvPrinter(); 24 | SpirvPrinter(const SpirvPrinter&) = default; 25 | SpirvPrinter(SpirvPrinter&&) = default; 26 | ~SpirvPrinter() = default; 27 | 28 | inline std::string Print(const std::vector& codepoints); 29 | inline std::string Print(const std::uint32_t* codepoints, std::size_t count); 30 | inline std::string Print(const std::vector& codepoints, const Settings& settings); 31 | std::string Print(const std::uint32_t* codepoints, std::size_t count, const Settings& settings); 32 | 33 | SpirvPrinter& operator=(const SpirvPrinter&) = default; 34 | SpirvPrinter& operator=(SpirvPrinter&&) = default; 35 | 36 | struct Settings 37 | { 38 | bool printHeader = true; 39 | bool printParameters = true; 40 | }; 41 | 42 | private: 43 | bool HandleHeader(const SpirvHeader& header) override; 44 | bool HandleOpcode(const SpirvInstruction& instruction, std::uint32_t wordCount) override; 45 | void PrintOperand(std::ostream& instructionStream, const SpirvOperand* operand); 46 | 47 | enum class ExtensionSet 48 | { 49 | GLSLstd450 50 | }; 51 | 52 | struct State; 53 | State* m_currentState; 54 | }; 55 | } 56 | 57 | #include 58 | 59 | #endif // NZSL_SPIRV_SPIRVPRINTER_HPP 60 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvPrinter.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | inline SpirvPrinter::SpirvPrinter() : 9 | m_currentState(nullptr) 10 | { 11 | } 12 | 13 | inline std::string SpirvPrinter::Print(const std::vector& codepoints) 14 | { 15 | return Print(codepoints.data(), codepoints.size()); 16 | } 17 | 18 | inline std::string SpirvPrinter::Print(const std::uint32_t* codepoints, std::size_t count) 19 | { 20 | Settings settings; 21 | return Print(codepoints, count, settings); 22 | } 23 | 24 | inline std::string SpirvPrinter::Print(const std::vector& codepoints, const Settings& settings) 25 | { 26 | return Print(codepoints.data(), codepoints.size(), settings); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvSection.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVSECTION_HPP 8 | #define NZSL_SPIRV_SPIRVSECTION_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace nzsl 14 | { 15 | class NZSL_API SpirvSection : public SpirvSectionBase 16 | { 17 | public: 18 | SpirvSection() = default; 19 | SpirvSection(const SpirvSection&) = default; 20 | SpirvSection(SpirvSection&&) = default; 21 | ~SpirvSection() = default; 22 | 23 | using SpirvSectionBase::Append; 24 | using SpirvSectionBase::AppendRaw; 25 | using SpirvSectionBase::AppendSection; 26 | using SpirvSectionBase::AppendVariadic; 27 | 28 | SpirvSection& operator=(const SpirvSection&) = delete; 29 | SpirvSection& operator=(SpirvSection&&) = default; 30 | }; 31 | } 32 | 33 | #include 34 | 35 | #endif // NZSL_SPIRV_SPIRVSECTION_HPP 36 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvSection.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvSectionBase.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVSECTIONBASE_HPP 8 | #define NZSL_SPIRV_SPIRVSECTIONBASE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace nzsl 17 | { 18 | class NZSL_API SpirvSectionBase 19 | { 20 | public: 21 | struct OpSize; 22 | struct Raw; 23 | 24 | SpirvSectionBase() = default; 25 | SpirvSectionBase(const SpirvSectionBase&) = default; 26 | SpirvSectionBase(SpirvSectionBase&&) = default; 27 | ~SpirvSectionBase() = default; 28 | 29 | inline const std::vector& GetBytecode() const; 30 | inline std::size_t GetOutputOffset() const; 31 | 32 | SpirvSectionBase& operator=(const SpirvSectionBase&) = delete; 33 | SpirvSectionBase& operator=(SpirvSectionBase&&) = default; 34 | 35 | struct OpSize 36 | { 37 | unsigned int wc; 38 | }; 39 | 40 | struct Raw 41 | { 42 | const void* ptr; 43 | std::size_t size; 44 | }; 45 | 46 | static inline std::uint32_t BuildOpcode(SpirvOp opcode, unsigned int wordCount); 47 | 48 | static constexpr std::size_t MaxWordCount = 0xFFFF; 49 | 50 | protected: 51 | inline std::size_t Append(SpirvOp opcode, const OpSize& wordCount); 52 | template std::size_t Append(SpirvOp opcode, const Args&... args); 53 | template std::size_t AppendVariadic(SpirvOp opcode, F&& callback); 54 | inline std::size_t AppendRaw(const char* str); 55 | inline std::size_t AppendRaw(std::string_view str); 56 | inline std::size_t AppendRaw(const std::string& str); 57 | inline std::size_t AppendRaw(std::uint32_t value); 58 | std::size_t AppendRaw(const Raw& raw); 59 | inline std::size_t AppendRaw(std::initializer_list codepoints); 60 | inline std::size_t AppendSection(const SpirvSectionBase& section); 61 | template || std::is_enum_v>> std::size_t AppendRaw(T value); 62 | 63 | inline unsigned int CountWord(const char* str); 64 | inline unsigned int CountWord(std::string_view str); 65 | inline unsigned int CountWord(const std::string& str); 66 | inline unsigned int CountWord(const Raw& raw); 67 | template || std::is_enum_v>> unsigned int CountWord(const T& value); 68 | template unsigned int CountWord(const T1& value, const T2& value2, const Args&... rest); 69 | 70 | private: 71 | std::vector m_bytecode; 72 | }; 73 | } 74 | 75 | #include 76 | 77 | #endif // NZSL_SPIRV_SPIRVSECTIONBASE_HPP 78 | -------------------------------------------------------------------------------- /include/NZSL/SpirV/SpirvVariable.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSL_SPIRV_SPIRVVARIABLE_HPP 8 | #define NZSL_SPIRV_SPIRVVARIABLE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nzsl 15 | { 16 | struct SpirvVariable 17 | { 18 | std::uint32_t pointerId; 19 | std::uint32_t typeId; 20 | SpirvConstantCache::TypePtr typePtr; 21 | SpirvStorageClass storageClass; 22 | }; 23 | } 24 | 25 | #endif // NZSL_SPIRV_SPIRVVARIABLE_HPP 26 | -------------------------------------------------------------------------------- /include/NZSL/SpirvWriter.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | 6 | namespace nzsl 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/CNZSL/LangWriter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 REMqb (remqb at remqb dot fr) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | extern "C" 15 | { 16 | CNZSL_API nzslLangWriter* nzslLangWriterCreate(void) 17 | { 18 | return new nzslLangWriter; 19 | } 20 | 21 | CNZSL_API void nzslLangWriterDestroy(nzslLangWriter* writerPtr) 22 | { 23 | delete writerPtr; 24 | } 25 | 26 | CNZSL_API nzslLangOutput* nzslLangWriterGenerate(nzslLangWriter* writerPtr, const nzslModule* modulePtr, const nzslWriterStates* statesPtr) 27 | { 28 | try 29 | { 30 | nzsl::LangWriter::States states; 31 | if (statesPtr) 32 | states = static_cast(*statesPtr); 33 | 34 | std::unique_ptr output = std::make_unique(); 35 | output->code = writerPtr->writer.Generate(*modulePtr->module, states); 36 | 37 | return output.release(); 38 | } 39 | catch (std::exception& e) 40 | { 41 | writerPtr->lastError = fmt::format("nzslLangWriterGenerate failed: {}", e.what()); 42 | return nullptr; 43 | } 44 | catch (...) 45 | { 46 | writerPtr->lastError = "nzslLangWriterGenerate failed with unknown error"; 47 | return nullptr; 48 | } 49 | } 50 | 51 | CNZSL_API const char* nzslLangWriterGetLastError(const nzslLangWriter* writerPtr) 52 | { 53 | return writerPtr->lastError.c_str(); 54 | } 55 | 56 | CNZSL_API void nzslLangOutputDestroy(nzslLangOutput* outputPtr) 57 | { 58 | delete outputPtr; 59 | } 60 | 61 | CNZSL_API const char* nzslLangOutputGetCode(const nzslLangOutput* outputPtr, size_t* length) 62 | { 63 | if (length) 64 | *length = outputPtr->code.size(); 65 | 66 | return outputPtr->code.data(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/CNZSL/Module.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 REMqb (remqb at remqb dot fr) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | CNZSL_API nzslModule* nzslModuleCreate(void) 12 | { 13 | return new nzslModule; 14 | } 15 | 16 | CNZSL_API void nzslModuleDestroy(nzslModule* module) 17 | { 18 | delete module; 19 | } 20 | 21 | CNZSL_API const char* nzslModuleGetLastError(const nzslModule* module) 22 | { 23 | assert(module); 24 | return module->lastError.c_str(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/CNZSL/Parser.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 REMqb (remqb at remqb dot fr) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern "C" 12 | { 13 | CNZSL_API int nzslParserParseFromFile(nzslModule* modulePtr, const char* sourcePath, size_t sourcePathLen) 14 | { 15 | try 16 | { 17 | modulePtr->module = nzsl::ParseFromFile({sourcePath, sourcePath + sourcePathLen}); 18 | return 0; 19 | } 20 | catch (std::exception& e) 21 | { 22 | modulePtr->lastError = fmt::format("nzslParserParseFromFile failed: {}", e.what()); 23 | return -1; 24 | } 25 | catch (...) 26 | { 27 | modulePtr->lastError = "nzslParserParseFromFile failed: unknown error"; 28 | return -1; 29 | } 30 | } 31 | 32 | CNZSL_API int nzslParserParseSource(nzslModule* modulePtr, const char* source, size_t sourceLen) 33 | { 34 | return nzslParserParseSourceWithFilePath(modulePtr, source, sourceLen, nullptr, 0); 35 | } 36 | 37 | CNZSL_API int nzslParserParseSourceWithFilePath(nzslModule* modulePtr, const char* source, size_t sourceLen, const char* filePath, size_t filePathLen) 38 | { 39 | try 40 | { 41 | std::string filePathStr; 42 | if (filePath) 43 | filePathStr.assign(filePath, filePathLen); 44 | 45 | modulePtr->module = nzsl::Parse({source, sourceLen}, std::move(filePathStr)); 46 | return 0; 47 | } 48 | catch (const std::exception& e) 49 | { 50 | modulePtr->lastError = fmt::format("nzslParserParseSourceWithFilePath failed: {}", e.what()); 51 | return -1; 52 | } 53 | catch (...) 54 | { 55 | modulePtr->lastError = "nzslParserParseSourceWithFilePath failed: unknown error"; 56 | return -1; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/CNZSL/Serializer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 kbz_8 ( contact@kbz8.me ) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | extern "C" 14 | { 15 | CNZSL_API nzslSerializer* nzslSerializerCreate(void) 16 | { 17 | return new nzslSerializer; 18 | } 19 | 20 | CNZSL_API void nzslSerializerDestroy(nzslSerializer* serializerPtr) 21 | { 22 | delete serializerPtr; 23 | } 24 | 25 | CNZSL_API nzslBool nzslSerializeShader(nzslSerializer* serializerPtr, const nzslModule* modulePtr) 26 | { 27 | assert(serializerPtr); 28 | assert(modulePtr); 29 | 30 | try 31 | { 32 | nzsl::Ast::SerializeShader(serializerPtr->serializer, *modulePtr->module); 33 | } 34 | catch(std::exception& e) 35 | { 36 | serializerPtr->lastError = fmt::format("nzslSerializeShader failed: {}", e.what()); 37 | return false; 38 | } 39 | catch(...) 40 | { 41 | serializerPtr->lastError = "nzslSerializeShader failed with unknown error"; 42 | return false; 43 | } 44 | 45 | return true; 46 | } 47 | 48 | CNZSL_API const void* nzslSerializerGetData(const nzslSerializer* serializerPtr, size_t* outSize) 49 | { 50 | const std::vector& serializerData = serializerPtr->serializer.GetData(); 51 | *outSize = serializerData.size(); 52 | return serializerData.data(); 53 | } 54 | 55 | CNZSL_API const char* nzslSerializerGetLastError(const nzslSerializer* serializerPtr) 56 | { 57 | assert(serializerPtr); 58 | return serializerPtr->lastError.c_str(); 59 | } 60 | 61 | CNZSL_API nzslDeserializer* nzslDeserializerCreate(const void* data, size_t dataSize) 62 | { 63 | return new nzslDeserializer(data, dataSize); 64 | } 65 | 66 | CNZSL_API void nzslDeserializerDestroy(nzslDeserializer* deserializerPtr) 67 | { 68 | delete deserializerPtr; 69 | } 70 | 71 | CNZSL_API nzslModule* nzslDeserializeShader(nzslDeserializer* deserializerPtr) 72 | { 73 | assert(deserializerPtr); 74 | 75 | try 76 | { 77 | nzsl::Ast::ModulePtr module = nzsl::Ast::DeserializeShader(deserializerPtr->deserializer); 78 | 79 | nzslModule* modulePtr = nzslModuleCreate(); 80 | modulePtr->module = std::move(module); 81 | return modulePtr; 82 | } 83 | catch(std::exception& e) 84 | { 85 | deserializerPtr->lastError = fmt::format("nzslDeserializeShader failed: {}", e.what()); 86 | return nullptr; 87 | } 88 | catch(...) 89 | { 90 | deserializerPtr->lastError = "nzslDeserializeShader failed with unknown error"; 91 | return nullptr; 92 | } 93 | } 94 | 95 | CNZSL_API const char* nzslDeserializerGetLastError(const nzslDeserializer* deserializerPtr) 96 | { 97 | assert(deserializerPtr); 98 | return deserializerPtr->lastError.c_str(); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/CNZSL/SpirvWriter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 REMqb (remqb at remqb dot fr) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | extern "C" 15 | { 16 | CNZSL_API nzslSpirvWriter* nzslSpirvWriterCreate(void) 17 | { 18 | return new nzslSpirvWriter; 19 | } 20 | 21 | CNZSL_API void nzslSpirvWriterDestroy(nzslSpirvWriter* writerPtr) 22 | { 23 | delete writerPtr; 24 | } 25 | 26 | CNZSL_API nzslSpirvOutput* nzslSpirvWriterGenerate(nzslSpirvWriter* writerPtr, const nzslModule* modulePtr, const nzslWriterStates* statesPtr) 27 | { 28 | try 29 | { 30 | nzsl::SpirvWriter::States states; 31 | if (statesPtr) 32 | states = static_cast(*statesPtr); 33 | 34 | std::unique_ptr output = std::make_unique(); 35 | output->spirv = writerPtr->writer.Generate(*modulePtr->module, states); 36 | 37 | return output.release(); 38 | } 39 | catch (std::exception& e) 40 | { 41 | writerPtr->lastError = fmt::format("nzslSpirvWriterGenerate failed: {}", e.what()); 42 | return nullptr; 43 | } 44 | catch (...) 45 | { 46 | writerPtr->lastError = "nzslSpirvWriterGenerate failed with unknown error"; 47 | return nullptr; 48 | } 49 | } 50 | 51 | CNZSL_API const char* nzslSpirvWriterGetLastError(const nzslSpirvWriter* writerPtr) 52 | { 53 | return writerPtr->lastError.c_str(); 54 | } 55 | 56 | CNZSL_API void nzslSpirvWriterSetEnv(nzslSpirvWriter* writerPtr, const nzslSpirvWriterEnvironment* env) 57 | { 58 | nzsl::SpirvWriter::Environment writerEnv; 59 | writerEnv.spvMajorVersion = env->spvMajorVersion; 60 | writerEnv.spvMinorVersion = env->spvMinorVersion; 61 | 62 | writerPtr->writer.SetEnv(writerEnv); 63 | } 64 | 65 | CNZSL_API void nzslSpirvOutputDestroy(nzslSpirvOutput* outputPtr) 66 | { 67 | delete outputPtr; 68 | } 69 | 70 | CNZSL_API const uint32_t* nzslSpirvOutputGetSpirv(const nzslSpirvOutput* outputPtr, size_t* length) 71 | { 72 | if (length) 73 | *length = outputPtr->spirv.size(); 74 | 75 | return outputPtr->spirv.data(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/FilesystemModuleResolver.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 kbz_8 ( contact@kbz8.me ) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_FILESYSTEM_MODULE_RESOLVER_HPP 8 | #define CNZSL_STRUCTS_FILESYSTEM_MODULE_RESOLVER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct nzslFilesystemModuleResolver 15 | { 16 | std::shared_ptr resolver; 17 | std::string lastError; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/GlslOutput.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_GLSLOUTPUT_HPP 8 | #define CNZSL_STRUCTS_GLSLOUTPUT_HPP 9 | 10 | #include 11 | 12 | struct nzslGlslOutput : nzsl::GlslWriter::Output 13 | { 14 | }; 15 | 16 | #endif // CNZSL_STRUCTS_GLSLOUTPUT_HPP 17 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/GlslWriter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_GLSLWRITER_HPP 8 | #define CNZSL_STRUCTS_GLSLWRITER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct nzslGlslWriter 15 | { 16 | std::string lastError; 17 | nzsl::GlslWriter writer; 18 | }; 19 | 20 | #endif // CNZSL_STRUCTS_GLSLWRITER_HPP 21 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/GlslWriterParameters.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_GLSLWRITERPARAMETERS_HPP 8 | #define CNZSL_STRUCTS_GLSLWRITERPARAMETERS_HPP 9 | 10 | #include 11 | 12 | struct nzslGlslWriterParameters 13 | { 14 | nzsl::GlslWriter::Parameters parameters; 15 | }; 16 | 17 | #endif // CNZSL_STRUCTS_GLSLWRITERPARAMETERS_HPP 18 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/LangOutput.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_LANGOUTPUT_HPP 8 | #define CNZSL_STRUCTS_LANGOUTPUT_HPP 9 | 10 | #include 11 | 12 | struct nzslLangOutput 13 | { 14 | std::string code; 15 | }; 16 | 17 | #endif // CNZSL_STRUCTS_LANGOUTPUT_HPP 18 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/LangWriter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_LANGWRITER_HPP 8 | #define CNZSL_STRUCTS_LANGWRITER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct nzslLangWriter 15 | { 16 | std::string lastError; 17 | nzsl::LangWriter writer; 18 | }; 19 | 20 | #endif // CNZSL_STRUCTS_LANGWRITER_HPP 21 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/Module.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_MODULE_HPP 8 | #define CNZSL_STRUCTS_MODULE_HPP 9 | 10 | #include 11 | #include 12 | 13 | struct nzslModule 14 | { 15 | nzsl::Ast::ModulePtr module; 16 | std::string lastError; 17 | }; 18 | 19 | #endif // CNZSL_STRUCTS_MODULE_HPP 20 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/Serializer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 kbz_8 ( contact@kbz8.me ) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_SERIALIZER_HPP 8 | #define CNZSL_STRUCTS_SERIALIZER_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | struct nzslSerializer 16 | { 17 | nzsl::Serializer serializer; 18 | std::string lastError; 19 | }; 20 | 21 | struct nzslDeserializer 22 | { 23 | nzsl::Deserializer deserializer; 24 | std::string lastError; 25 | 26 | nzslDeserializer(const void* data, size_t dataSize) : deserializer(data, dataSize) {} 27 | }; 28 | 29 | #endif // CNZSL_STRUCTS_SERIALIZER_HPP 30 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/SpirvOutput.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_SPIRVOUTPUT_HPP 8 | #define CNZSL_STRUCTS_SPIRVOUTPUT_HPP 9 | 10 | #include 11 | #include 12 | 13 | struct nzslSpirvOutput 14 | { 15 | std::vector spirv; 16 | }; 17 | 18 | #endif // CNZSL_STRUCTS_SPIRVOUTPUT_HPP 19 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/SpirvWriter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_SPIRVWRITER_HPP 8 | #define CNZSL_STRUCTS_SPIRVWRITER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct nzslSpirvWriter 15 | { 16 | std::string lastError; 17 | nzsl::SpirvWriter writer; 18 | }; 19 | 20 | #endif // CNZSL_STRUCTS_SPIRVWRITER_HPP 21 | -------------------------------------------------------------------------------- /src/CNZSL/Structs/WriterStates.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language - C Binding" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef CNZSL_STRUCTS_WRITERSTATES_HPP 8 | #define CNZSL_STRUCTS_WRITERSTATES_HPP 9 | 10 | #include 11 | 12 | struct nzslWriterStates : nzsl::ShaderWriter::States 13 | { 14 | }; 15 | 16 | #endif // CNZSL_STRUCTS_WRITERSTATES_HPP 17 | -------------------------------------------------------------------------------- /src/NZSL/Ast/ExportVisitor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | 8 | namespace nzsl::Ast 9 | { 10 | void ExportVisitor::Visit(Statement& statement, const Callbacks& callbacks) 11 | { 12 | m_callbacks = &callbacks; 13 | statement.Visit(*this); 14 | } 15 | 16 | void ExportVisitor::Visit(DeclareConstStatement& node) 17 | { 18 | if (!node.isExported.HasValue() || !node.isExported.GetResultingValue()) 19 | return; 20 | 21 | if (m_callbacks->onExportedConst) 22 | m_callbacks->onExportedConst(node); 23 | } 24 | 25 | void ExportVisitor::Visit(DeclareFunctionStatement& node) 26 | { 27 | if (!node.isExported.HasValue() || !node.isExported.GetResultingValue()) 28 | return; 29 | 30 | if (m_callbacks->onExportedFunc) 31 | m_callbacks->onExportedFunc(node); 32 | } 33 | 34 | void ExportVisitor::Visit(DeclareStructStatement& node) 35 | { 36 | if (!node.isExported.HasValue() || !node.isExported.GetResultingValue()) 37 | return; 38 | 39 | if (m_callbacks->onExportedStruct) 40 | m_callbacks->onExportedStruct(node); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/NZSL/Ast/ExpressionVisitor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl::Ast 8 | { 9 | ExpressionVisitor::~ExpressionVisitor() = default; 10 | } 11 | -------------------------------------------------------------------------------- /src/NZSL/Ast/ExpressionVisitorExcept.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl::Ast 8 | { 9 | #define NZSL_SHADERAST_EXPRESSION(Node) void ExpressionVisitorExcept::Visit(Ast::Node##Expression& /*node*/) \ 10 | { \ 11 | throw std::runtime_error("unexpected " #Node " expression"); \ 12 | } 13 | #include 14 | } 15 | -------------------------------------------------------------------------------- /src/NZSL/Ast/Nodes.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace nzsl::Ast 12 | { 13 | Node::~Node() = default; 14 | 15 | std::string_view ToString(FunctionParameterSemantic semantic) 16 | { 17 | switch (semantic) 18 | { 19 | case FunctionParameterSemantic::In: 20 | return "in"; 21 | case FunctionParameterSemantic::Out: 22 | return "out"; 23 | case FunctionParameterSemantic::InOut: 24 | return "inout"; 25 | default: 26 | break; 27 | } 28 | 29 | NAZARA_UNREACHABLE(); 30 | } 31 | 32 | #define NZSL_SHADERAST_NODE(Node, Category) NodeType Node##Category::GetType() const \ 33 | { \ 34 | return NodeType:: Node##Category; \ 35 | } 36 | #include 37 | 38 | #define NZSL_SHADERAST_NODE(Node, Category) void Node##Category::Visit(Category##Visitor& visitor) \ 39 | {\ 40 | visitor.Visit(*this); \ 41 | } 42 | 43 | #include 44 | 45 | const ExpressionType& EnsureExpressionType(const Expression& expr) 46 | { 47 | const ExpressionType* exprType = GetExpressionType(expr); 48 | if (!exprType) 49 | throw std::runtime_error("unexpected missing expression type"); 50 | 51 | return *exprType; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/NZSL/Ast/StatementVisitor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl::Ast 8 | { 9 | StatementVisitor::~StatementVisitor() = default; 10 | } 11 | -------------------------------------------------------------------------------- /src/NZSL/Ast/StatementVisitorExcept.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl::Ast 8 | { 9 | #define NZSL_SHADERAST_STATEMENT(Node) void StatementVisitorExcept::Visit(Ast::Node##Statement& /*node*/) \ 10 | { \ 11 | throw std::runtime_error("unexpected " #Node " statement"); \ 12 | } 13 | #include 14 | } 15 | -------------------------------------------------------------------------------- /src/NZSL/ModuleResolver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsl 8 | { 9 | ModuleResolver::~ModuleResolver() = default; 10 | } 11 | -------------------------------------------------------------------------------- /src/NZSL/ShaderWriter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | 8 | namespace nzsl 9 | { 10 | ShaderWriter::~ShaderWriter() = default; 11 | } 12 | -------------------------------------------------------------------------------- /src/NZSL/SpirV/SpirvDecoder.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nzsl 15 | { 16 | void SpirvDecoder::Decode(const std::uint32_t* codepoints, std::size_t count) 17 | { 18 | m_currentCodepoint = codepoints; 19 | m_codepointEnd = codepoints + count; 20 | 21 | std::uint32_t magicNumber = ReadWord(); 22 | if (magicNumber != SpirvMagicNumber) 23 | throw std::runtime_error("invalid SPIR-V: magic number didn't match"); 24 | 25 | std::uint32_t versionNumber = ReadWord(); 26 | if (versionNumber > SpirvVersion) 27 | throw std::runtime_error("SPIR-V is more recent than decoder, dismissing"); 28 | 29 | SpirvHeader header; 30 | header.generatorId = ReadWord(); 31 | header.bound = ReadWord(); 32 | header.schema = ReadWord(); 33 | header.versionNumber = versionNumber; 34 | 35 | if (!HandleHeader(header)) 36 | return; 37 | 38 | while (m_currentCodepoint < m_codepointEnd) 39 | { 40 | const std::uint32_t* instructionBegin = m_currentCodepoint; 41 | 42 | std::uint32_t firstWord = ReadWord(); 43 | 44 | std::uint16_t wordCount = static_cast((firstWord >> 16) & 0xFFFF); 45 | std::uint16_t opcode = static_cast(firstWord & 0xFFFF); 46 | 47 | const SpirvInstruction* inst = GetSpirvInstruction(opcode); 48 | if (!inst) 49 | throw std::runtime_error("invalid instruction"); 50 | 51 | if (!HandleOpcode(*inst, wordCount)) 52 | break; 53 | 54 | m_currentCodepoint = instructionBegin + wordCount; 55 | } 56 | } 57 | 58 | bool SpirvDecoder::HandleHeader(const SpirvHeader& /*header*/) 59 | { 60 | return true; 61 | } 62 | 63 | std::string SpirvDecoder::ReadString() 64 | { 65 | std::string str; 66 | 67 | for (;;) 68 | { 69 | std::uint32_t value = ReadWord(); 70 | for (std::size_t j = 0; j < 4; ++j) 71 | { 72 | char c = static_cast((value >> (j * 8)) & 0xFF); 73 | if (c == '\0') 74 | return str; 75 | 76 | str.push_back(c); 77 | } 78 | } 79 | } 80 | 81 | std::uint32_t SpirvDecoder::ReadWord() 82 | { 83 | if (m_currentCodepoint >= m_codepointEnd) 84 | throw std::runtime_error("unexpected end of stream"); 85 | 86 | return *m_currentCodepoint++; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/NZSL/SpirV/SpirvSectionBase.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | #include 7 | 8 | namespace nzsl 9 | { 10 | std::size_t SpirvSectionBase::AppendRaw(const Raw& raw) 11 | { 12 | std::size_t offset = GetOutputOffset(); 13 | 14 | const std::uint8_t* ptr = static_cast(raw.ptr); 15 | 16 | std::size_t size4 = CountWord(raw); 17 | for (std::size_t i = 0; i < size4; ++i) 18 | { 19 | std::uint32_t codepoint = 0; 20 | for (std::size_t j = 0; j < 4; ++j) 21 | { 22 | #ifdef NZSL_BIG_ENDIAN 23 | std::size_t pos = i * 4 + (3 - j); 24 | #else 25 | std::size_t pos = i * 4 + j; 26 | #endif 27 | 28 | if (pos < raw.size) 29 | codepoint |= std::uint32_t(ptr[pos]) << (j * 8); 30 | } 31 | 32 | AppendRaw(codepoint); 33 | } 34 | 35 | return offset; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ShaderArchiver/Archiver.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSLA_ARCHIVER_HPP 8 | #define NZSLA_ARCHIVER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace nzsla 16 | { 17 | class Archiver 18 | { 19 | public: 20 | static constexpr std::uint32_t MajorVersion = 0; 21 | static constexpr std::uint32_t MinorVersion = 1; 22 | static constexpr std::uint32_t PatchVersion = 0; 23 | 24 | Archiver(cxxopts::ParseResult& options); 25 | Archiver(const Archiver&) = delete; 26 | Archiver(Archiver&&) = delete; 27 | ~Archiver() = default; 28 | 29 | void HandleParameters(); 30 | 31 | void Process(); 32 | 33 | Archiver& operator=(const Archiver&) = delete; 34 | Archiver& operator=(Archiver&&) = delete; 35 | 36 | static cxxopts::Options BuildOptions(); 37 | 38 | private: 39 | void DoArchive(); 40 | void DoShow(); 41 | std::vector ReadFileContent(const std::filesystem::path& filePath); 42 | std::string ToHeader(const void* data, std::size_t size); 43 | void WriteFileContent(const std::filesystem::path& filePath, const void* data, std::size_t size); 44 | 45 | std::vector m_inputFiles; 46 | std::filesystem::path m_outputPath; 47 | cxxopts::ParseResult& m_options; 48 | bool m_isArchiving; 49 | bool m_isShowing; 50 | bool m_isVerbose; 51 | bool m_outputToStdout; 52 | }; 53 | } 54 | 55 | #include 56 | 57 | #endif // NZSLA_ARCHIVER_HPP 58 | -------------------------------------------------------------------------------- /src/ShaderArchiver/Archiver.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzsla 8 | { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/ShaderArchiver/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | try 7 | { 8 | cxxopts::Options cmdOptions = nzsla::Archiver::BuildOptions(); 9 | 10 | auto options = cmdOptions.parse(argc, argv); 11 | if (options.count("version") > 0) 12 | { 13 | fmt::print("nzsla version {}.{}.{} using nzsl {}.{}.{}\n", 14 | nzsla::Archiver::MajorVersion, nzsla::Archiver::MinorVersion, nzsla::Archiver::PatchVersion, 15 | NZSL_VERSION_MAJOR, NZSL_VERSION_MINOR, NZSL_VERSION_PATCH); 16 | 17 | return EXIT_SUCCESS; 18 | } 19 | 20 | if (options.count("help") > 0) 21 | { 22 | fmt::print("{}\n", cmdOptions.help()); 23 | return EXIT_SUCCESS; 24 | } 25 | 26 | nzsla::Archiver archiver(options); 27 | 28 | try 29 | { 30 | archiver.HandleParameters(); 31 | archiver.Process(); 32 | 33 | return EXIT_SUCCESS; 34 | } 35 | catch (const cxxopts::exceptions::exception& e) 36 | { 37 | fmt::print(stderr, "{}\n{}\n", e.what(), cmdOptions.help()); 38 | return EXIT_FAILURE; 39 | } 40 | } 41 | catch (const std::exception& e) 42 | { 43 | fmt::print(stderr, "{}\n", e.what()); 44 | return EXIT_FAILURE; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/ShaderCompiler/Compiler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #pragma once 6 | 7 | #ifndef NZSLC_COMPILER_HPP 8 | #define NZSLC_COMPILER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace nzslc 20 | { 21 | class Compiler 22 | { 23 | public: 24 | static constexpr std::uint32_t MajorVersion = 0; 25 | static constexpr std::uint32_t MinorVersion = 1; 26 | static constexpr std::uint32_t PatchVersion = 0; 27 | 28 | Compiler(cxxopts::ParseResult& options); 29 | Compiler(const Compiler&) = delete; 30 | Compiler(Compiler&&) = delete; 31 | ~Compiler() = default; 32 | 33 | void HandleParameters(); 34 | 35 | void PrintError(const nzsl::Error& error) const; 36 | 37 | void Process(); 38 | 39 | Compiler& operator=(const Compiler&) = delete; 40 | Compiler& operator=(Compiler&&) = delete; 41 | 42 | static cxxopts::Options BuildOptions(); 43 | 44 | enum class LogFormat 45 | { 46 | Classic, 47 | VisualStudio 48 | }; 49 | 50 | private: 51 | nzsl::ShaderWriter::States BuildWriterOptions(); 52 | void Compile(); 53 | void CompileToGLSL(std::filesystem::path outputPath, const nzsl::Ast::Module& module); 54 | void CompileToNZSL(std::filesystem::path outputPath, const nzsl::Ast::Module& module); 55 | void CompileToNZSLB(std::filesystem::path outputPath, const nzsl::Ast::Module& module); 56 | void CompileToSPV(std::filesystem::path outputPath, const nzsl::Ast::Module& module, bool textual); 57 | void PrintTime(); 58 | void OutputFile(std::filesystem::path filePath, const void* data, std::size_t size, bool disallowHeader = false); 59 | void OutputToStdout(std::string_view str); 60 | void ReadInput(); 61 | void Sanitize(); 62 | template auto Step(std::enable_if_t, std::string_view> stepName, F&& func, Args&&... args) -> decltype(std::invoke(func, std::forward(args)...)); 63 | template auto Step(std::enable_if_t, std::string_view> stepName, F&& func, Args&&... args) -> decltype(std::invoke(func, this, std::forward(args)...)); 64 | template auto StepInternal(std::string_view stepName, F&& func) -> decltype(func()); 65 | nzsl::Ast::ModulePtr Deserialize(const std::uint8_t* data, std::size_t size); 66 | 67 | static nzsl::Ast::ModulePtr Parse(std::string_view sourceContent, const std::string& filePath); 68 | static std::vector ReadFileContent(const std::filesystem::path& filePath); 69 | static std::string ReadSourceFileContent(const std::filesystem::path& filePath); 70 | static std::string ToHeader(const void* data, std::size_t size); 71 | static void WriteFileContent(const std::filesystem::path& filePath, const void* data, std::size_t size); 72 | 73 | struct StepTime 74 | { 75 | std::size_t childrenCount; 76 | std::string name; 77 | long long time; 78 | }; 79 | 80 | std::filesystem::path m_inputFilePath; 81 | std::filesystem::path m_outputPath; 82 | std::vector m_steps; 83 | LogFormat m_logFormat; 84 | nzsl::Ast::ModulePtr m_shaderModule; 85 | cxxopts::ParseResult& m_options; 86 | bool m_profiling; 87 | bool m_outputHeader; 88 | bool m_outputToStdout; 89 | bool m_verbose; 90 | unsigned int m_iterationCount; 91 | }; 92 | } 93 | 94 | #include 95 | 96 | #endif // NZSLC_COMPILER_HPP 97 | -------------------------------------------------------------------------------- /src/ShaderCompiler/Compiler.inl: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) 2 | // This file is part of the "Nazara Shading Language" project 3 | // For conditions of distribution and use, see copyright notice in Config.hpp 4 | 5 | #include 6 | 7 | namespace nzslc 8 | { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/ShaderCompiler/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | try 7 | { 8 | cxxopts::Options cmdOptions = nzslc::Compiler::BuildOptions(); 9 | 10 | auto options = cmdOptions.parse(argc, argv); 11 | if (options.count("version") > 0) 12 | { 13 | fmt::print("nzslc version {}.{}.{} using nzsl {}.{}.{}\n", 14 | nzslc::Compiler::MajorVersion, nzslc::Compiler::MinorVersion, nzslc::Compiler::PatchVersion, 15 | NZSL_VERSION_MAJOR, NZSL_VERSION_MINOR, NZSL_VERSION_PATCH); 16 | 17 | return EXIT_SUCCESS; 18 | } 19 | 20 | if (options.count("help") > 0) 21 | { 22 | fmt::print("{}\n", cmdOptions.help()); 23 | return EXIT_SUCCESS; 24 | } 25 | 26 | nzslc::Compiler compiler(options); 27 | 28 | try 29 | { 30 | compiler.HandleParameters(); 31 | compiler.Process(); 32 | 33 | return EXIT_SUCCESS; 34 | } 35 | catch (const nzsl::Error& error) 36 | { 37 | compiler.PrintError(error); 38 | return EXIT_FAILURE; 39 | } 40 | catch (const cxxopts::exceptions::exception& e) 41 | { 42 | fmt::print(stderr, "{}\n{}\n", e.what(), cmdOptions.help()); 43 | return EXIT_FAILURE; 44 | } 45 | } 46 | catch (const std::exception& e) 47 | { 48 | fmt::print(stderr, "{}\n", e.what()); 49 | return EXIT_FAILURE; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/src/Tests/AccessMemberTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_CASE("structure member access", "[Shader]") 8 | { 9 | SECTION("Nested member loading") 10 | { 11 | std::string_view nzslSource = R"( 12 | [nzsl_version("1.0")] 13 | module; 14 | 15 | struct innerStruct 16 | { 17 | field: vec3[f32] 18 | } 19 | 20 | struct outerStruct 21 | { 22 | s: innerStruct 23 | } 24 | 25 | external 26 | { 27 | [set(0), binding(0)] ubo: uniform[outerStruct] 28 | } 29 | )"; 30 | 31 | nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(nzslSource); 32 | shaderModule = SanitizeModule(*shaderModule); 33 | 34 | SECTION("Nested AccessMember") 35 | { 36 | auto ubo = nzsl::ShaderBuilder::Identifier("ubo"); 37 | auto firstAccess = nzsl::ShaderBuilder::AccessMember(std::move(ubo), { "s" }); 38 | auto secondAccess = nzsl::ShaderBuilder::AccessMember(std::move(firstAccess), { "field" }); 39 | 40 | auto swizzle = nzsl::ShaderBuilder::Swizzle(std::move(secondAccess), { 2u }); 41 | auto varDecl = nzsl::ShaderBuilder::DeclareVariable("result", nzsl::Ast::ExpressionType{ nzsl::Ast::PrimitiveType::Float32 }, std::move(swizzle)); 42 | 43 | shaderModule->rootNode->statements.push_back(nzsl::ShaderBuilder::DeclareFunction(nzsl::ShaderStageType::Vertex, "main", std::move(varDecl))); 44 | 45 | ExpectGLSL(*shaderModule, R"( 46 | void main() 47 | { 48 | float result = ubo.s.field.z; 49 | } 50 | )"); 51 | 52 | ExpectNZSL(*shaderModule, R"( 53 | [entry(vert)] 54 | fn main() 55 | { 56 | let result: f32 = ubo.s.field.z; 57 | } 58 | )"); 59 | 60 | ExpectSPIRV(*shaderModule, R"( 61 | OpFunction 62 | OpLabel 63 | OpVariable 64 | OpAccessChain 65 | OpLoad 66 | OpCompositeExtract 67 | OpStore 68 | OpReturn 69 | OpFunctionEnd)"); 70 | } 71 | 72 | SECTION("AccessMember with multiples fields") 73 | { 74 | auto ubo = nzsl::ShaderBuilder::Identifier("ubo"); 75 | auto access = nzsl::ShaderBuilder::AccessMember(std::move(ubo), { "s", "field" }); 76 | 77 | auto swizzle = nzsl::ShaderBuilder::Swizzle(std::move(access), { 2u }); 78 | auto varDecl = nzsl::ShaderBuilder::DeclareVariable("result", nzsl::Ast::ExpressionType{ nzsl::Ast::PrimitiveType::Float32 }, std::move(swizzle)); 79 | 80 | shaderModule->rootNode->statements.push_back(nzsl::ShaderBuilder::DeclareFunction(nzsl::ShaderStageType::Vertex, "main", std::move(varDecl))); 81 | 82 | ExpectGLSL(*shaderModule, R"( 83 | void main() 84 | { 85 | float result = ubo.s.field.z; 86 | } 87 | )"); 88 | 89 | ExpectNZSL(*shaderModule, R"( 90 | [entry(vert)] 91 | fn main() 92 | { 93 | let result: f32 = ubo.s.field.z; 94 | } 95 | )"); 96 | 97 | ExpectSPIRV(*shaderModule, R"( 98 | OpFunction 99 | OpLabel 100 | OpVariable 101 | OpAccessChain 102 | OpLoad 103 | OpCompositeExtract 104 | OpStore 105 | OpReturn 106 | OpFunctionEnd)"); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /tests/src/Tests/CastTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_CASE("Casts", "[Shader]") 8 | { 9 | SECTION("Scalar casts") 10 | { 11 | std::string_view nzslSource = R"( 12 | [nzsl_version("1.0")] 13 | [feature(float64)] 14 | module; 15 | 16 | [entry(frag)] 17 | fn main() 18 | { 19 | let fVal = 42.0; 20 | 21 | let x = f64(fVal); 22 | let x = i32(fVal); 23 | let x = u32(fVal); 24 | 25 | let iVal = 42; 26 | 27 | let x = f32(iVal); 28 | let x = f64(iVal); 29 | let x = u32(iVal); 30 | 31 | let uVal = u32(42); 32 | 33 | let x = f32(uVal); 34 | let x = f64(uVal); 35 | let x = i32(uVal); 36 | } 37 | )"; 38 | 39 | nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(nzslSource); 40 | shaderModule = SanitizeModule(*shaderModule); 41 | 42 | // We need GLSL 4.0 for fp64 43 | nzsl::GlslWriter::Environment glslEnv; 44 | glslEnv.glMajorVersion = 4; 45 | glslEnv.glMinorVersion = 0; 46 | glslEnv.glES = false; 47 | 48 | ExpectGLSL(*shaderModule, R"( 49 | void main() 50 | { 51 | float fVal = 42.0; 52 | double x = double(fVal); 53 | int x_2 = int(fVal); 54 | uint x_3 = uint(fVal); 55 | int iVal = 42; 56 | float x_4 = float(iVal); 57 | double x_5 = double(iVal); 58 | uint x_6 = uint(iVal); 59 | uint uVal = uint(42); 60 | float x_7 = float(uVal); 61 | double x_8 = double(uVal); 62 | int x_9 = int(uVal); 63 | } 64 | )", {}, glslEnv); 65 | 66 | ExpectNZSL(*shaderModule, R"( 67 | [entry(frag)] 68 | fn main() 69 | { 70 | let fVal: f32 = 42.0; 71 | let x: f64 = f64(fVal); 72 | let x: i32 = i32(fVal); 73 | let x: u32 = u32(fVal); 74 | let iVal: i32 = 42; 75 | let x: f32 = f32(iVal); 76 | let x: f64 = f64(iVal); 77 | let x: u32 = u32(iVal); 78 | let uVal: u32 = u32(42); 79 | let x: f32 = f32(uVal); 80 | let x: f64 = f64(uVal); 81 | let x: i32 = i32(uVal); 82 | } 83 | )"); 84 | 85 | ExpectSPIRV(*shaderModule, R"( 86 | %13 = OpFunction %1 FunctionControl(0) %2 87 | %14 = OpLabel 88 | %15 = OpVariable %5 StorageClass(Function) 89 | %16 = OpVariable %7 StorageClass(Function) 90 | %17 = OpVariable %9 StorageClass(Function) 91 | %18 = OpVariable %11 StorageClass(Function) 92 | %19 = OpVariable %9 StorageClass(Function) 93 | %20 = OpVariable %5 StorageClass(Function) 94 | %21 = OpVariable %7 StorageClass(Function) 95 | %22 = OpVariable %11 StorageClass(Function) 96 | %23 = OpVariable %11 StorageClass(Function) 97 | %24 = OpVariable %5 StorageClass(Function) 98 | %25 = OpVariable %7 StorageClass(Function) 99 | %26 = OpVariable %9 StorageClass(Function) 100 | OpStore %15 %4 101 | %27 = OpLoad %3 %15 102 | %28 = OpFConvert %6 %27 103 | OpStore %16 %28 104 | %29 = OpLoad %3 %15 105 | %30 = OpConvertFToS %8 %29 106 | OpStore %17 %30 107 | %31 = OpLoad %3 %15 108 | %32 = OpConvertFToU %10 %31 109 | OpStore %18 %32 110 | OpStore %19 %12 111 | %33 = OpLoad %8 %19 112 | %34 = OpConvertSToF %3 %33 113 | OpStore %20 %34 114 | %35 = OpLoad %8 %19 115 | %36 = OpConvertSToF %6 %35 116 | OpStore %21 %36 117 | %37 = OpLoad %8 %19 118 | %38 = OpBitcast %10 %37 119 | OpStore %22 %38 120 | %39 = OpBitcast %10 %12 121 | OpStore %23 %39 122 | %40 = OpLoad %10 %23 123 | %41 = OpConvertUToF %3 %40 124 | OpStore %24 %41 125 | %42 = OpLoad %10 %23 126 | %43 = OpConvertUToF %6 %42 127 | OpStore %25 %43 128 | %44 = OpLoad %10 %23 129 | %45 = OpBitcast %8 %44 130 | OpStore %26 %45 131 | OpReturn 132 | OpFunctionEnd)", {}, {}, true); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /tests/src/Tests/IdentifierTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_CASE("identifiers", "[Shader]") 8 | { 9 | SECTION("Reserved identifiers check") 10 | { 11 | // Here's a shader using exclusively GLSL reversed words as identifiers, it should generate proper GLSL 12 | std::string_view nzslSource = R"( 13 | [nzsl_version("1.0")] 14 | module; 15 | 16 | external 17 | { 18 | [binding(0)] texture: sampler2D[f32] 19 | } 20 | 21 | fn int() -> i32 22 | { 23 | return 42; 24 | } 25 | 26 | struct output 27 | { 28 | active: vec3[f32], 29 | active_: vec2[i32], 30 | _nzsl: i32, 31 | _: f32 32 | } 33 | 34 | [entry(frag)] 35 | fn main() -> output 36 | { 37 | let input = int(); 38 | let input_ = 0; 39 | 40 | let fl__oa________t = 42.0; 41 | 42 | let outValue: output; 43 | outValue.active = (f32(input) + fl__oa________t).xxx; 44 | 45 | return outValue; 46 | } 47 | )"; 48 | 49 | nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(nzslSource); 50 | shaderModule = SanitizeModule(*shaderModule); 51 | 52 | ExpectGLSL(*shaderModule, R"( 53 | uniform sampler2D texture_; 54 | 55 | int int_() 56 | { 57 | return 42; 58 | } 59 | 60 | struct output_ 61 | { 62 | vec3 active_; 63 | ivec2 active2_2; 64 | int _; 65 | float _2_2; 66 | }; 67 | 68 | /*************** Outputs ***************/ 69 | out vec3 _nzslOutactive_; 70 | out ivec2 _nzslOutactive2_2; 71 | out int _nzslOut_; 72 | out float _nzslOut_2_2; 73 | 74 | void main() 75 | { 76 | int input_ = int_(); 77 | int input2_2 = 0; 78 | float fl2_oa8_t = 42.0; 79 | output_ outValue; 80 | float cachedResult = (float(input_)) + fl2_oa8_t; 81 | outValue.active_ = vec3(cachedResult, cachedResult, cachedResult); 82 | 83 | _nzslOutactive_ = outValue.active_; 84 | _nzslOutactive2_2 = outValue.active2_2; 85 | _nzslOut_ = outValue._; 86 | _nzslOut_2_2 = outValue._2_2; 87 | return; 88 | } 89 | )"); 90 | 91 | ExpectNZSL(*shaderModule, R"( 92 | [nzsl_version("1.0")] 93 | module; 94 | 95 | external 96 | { 97 | [set(0), binding(0)] texture: sampler2D[f32] 98 | } 99 | 100 | fn int() -> i32 101 | { 102 | return 42; 103 | } 104 | 105 | struct output 106 | { 107 | active: vec3[f32], 108 | active_: vec2[i32], 109 | _nzsl: i32, 110 | _: f32 111 | } 112 | 113 | [entry(frag)] 114 | fn main() -> output 115 | { 116 | let input: i32 = int(); 117 | let input_: i32 = 0; 118 | let fl__oa________t: f32 = 42.0; 119 | let outValue: output; 120 | outValue.active = ((f32(input)) + fl__oa________t).xxx; 121 | return outValue; 122 | } 123 | )"); 124 | 125 | ExpectSPIRV(*shaderModule, R"( 126 | OpFunction 127 | OpLabel 128 | OpReturnValue 129 | OpFunctionEnd 130 | OpFunction 131 | OpLabel 132 | OpVariable 133 | OpVariable 134 | OpVariable 135 | OpVariable 136 | OpFunctionCall 137 | OpStore 138 | OpStore 139 | OpStore 140 | OpLoad 141 | OpConvertSToF 142 | OpLoad 143 | OpFAdd 144 | OpCompositeConstruct 145 | OpAccessChain 146 | OpStore 147 | OpLoad 148 | OpReturn 149 | OpFunctionEnd)"); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /tests/src/Tests/LexerTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | TEST_CASE("lexer", "[Shader]") 8 | { 9 | SECTION("Empty code") 10 | { 11 | CHECK(nzsl::ToString(nzsl::Tokenize("")) == "EndOfStream"); 12 | } 13 | 14 | SECTION("Simple code") 15 | { 16 | std::string_view nzslSource = R"( 17 | [nzsl_version("1.0")] 18 | module; 19 | 20 | [entry(frag)] 21 | fn main() 22 | { 23 | let vec = vec4[f32](0.0, 1.0, 2.0, 3.0); 24 | let i = 42; 25 | let value = vec.xyz; 26 | } 27 | )"; 28 | 29 | std::vector tokens = nzsl::Tokenize(nzslSource); 30 | CHECK(nzsl::ToString(tokens) == R"(OpenSquareBracket Identifier(nzsl_version) OpenParenthesis StringValue("1.0") ClosingParenthesis ClosingSquareBracket 31 | Module Semicolon 32 | OpenSquareBracket Identifier(entry) OpenParenthesis Identifier(frag) ClosingParenthesis ClosingSquareBracket 33 | FunctionDeclaration Identifier(main) OpenParenthesis ClosingParenthesis 34 | OpenCurlyBracket 35 | Let Identifier(vec) Assign Identifier(vec4) OpenSquareBracket Identifier(f32) ClosingSquareBracket OpenParenthesis FloatingPointValue(0) Comma FloatingPointValue(1) Comma FloatingPointValue(2) Comma FloatingPointValue(3) ClosingParenthesis Semicolon 36 | Let Identifier(i) Assign IntegerValue(42) Semicolon 37 | Let Identifier(value) Assign Identifier(vec) Dot Identifier(xyz) Semicolon 38 | ClosingCurlyBracket 39 | EndOfStream)"); 40 | } 41 | 42 | SECTION("Commented code") 43 | { 44 | std::string_view nzslSource = R"( 45 | [nzsl_version("1.0")] // could be 1.0.0 46 | module /* a module has no name*/; 47 | 48 | [entry(frag/*ment but we like to keep those small*/)] 49 | fn main(/* no parameters*/) 50 | { 51 | // Line comment 52 | let a = 42; 53 | let b = /*a **/ a; 54 | } 55 | )"; 56 | 57 | std::vector tokens = nzsl::Tokenize(nzslSource); 58 | CHECK(nzsl::ToString(tokens) == R"(OpenSquareBracket Identifier(nzsl_version) OpenParenthesis StringValue("1.0") ClosingParenthesis ClosingSquareBracket 59 | Module Semicolon 60 | OpenSquareBracket Identifier(entry) OpenParenthesis Identifier(frag) ClosingParenthesis ClosingSquareBracket 61 | FunctionDeclaration Identifier(main) OpenParenthesis ClosingParenthesis 62 | OpenCurlyBracket 63 | Let Identifier(a) Assign IntegerValue(42) Semicolon 64 | Let Identifier(b) Assign Identifier(a) Semicolon 65 | ClosingCurlyBracket 66 | EndOfStream)"); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/src/Tests/NzslcTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | TEST_CASE("Standalone compiler", "[NZSLC]") 9 | { 10 | WHEN("Printing help") 11 | { 12 | ExecuteCommand("./nzslc -h", R"(Tool for validating and compiling NZSL shaders)"); 13 | } 14 | 15 | WHEN("Printing version") 16 | { 17 | ExecuteCommand("./nzslc --version", fmt::format(R"(nzslc version \d\.\d\.\d using nzsl {}\.{}\.{})", NZSL_VERSION_MAJOR, NZSL_VERSION_MINOR, NZSL_VERSION_PATCH)); 18 | } 19 | 20 | WHEN("Compiling shader modules") 21 | { 22 | REQUIRE(std::filesystem::exists("../resources/Shader.nzsl")); 23 | 24 | auto Cleanup = [] 25 | { 26 | std::filesystem::remove("../resources/Shader.nzslb"); 27 | std::filesystem::remove("../resources/modules/Color.nzslb"); 28 | std::filesystem::remove("../resources/modules/Data/OutputStruct.nzslb"); 29 | std::filesystem::remove_all("test_files"); 30 | }; 31 | 32 | Cleanup(); 33 | 34 | Nz::CallOnExit cleanupOnExit(std::move(Cleanup)); 35 | 36 | // Compile each module separately 37 | ExecuteCommand("./nzslc --compile=nzslb --partial ../resources/Shader.nzsl"); 38 | ExecuteCommand("./nzslc --compile=nzslb --partial ../resources/modules/Color.nzsl"); 39 | ExecuteCommand("./nzslc --compile=nzslb --partial ../resources/modules/Data/OutputStruct.nzsl"); 40 | ExecuteCommand("./nzslc ../resources/modules/Data/DataStruct.nzslb"); //< validation 41 | 42 | // Try to generate a full shader based on partial compilation result 43 | ExecuteCommand("./nzslc --compile=glsl,glsl-header,nzsl,nzsl-header,nzslb,nzslb-header,spv,spv-header,spv-txt --gl-bindingmap --debug-level=regular -o test_files -m ../resources/modules/Color.nzslb -m ../resources/modules/Data/OutputStruct.nzslb -m ../resources/modules/Data/DataStruct.nzslb ../resources/Shader.nzslb"); 44 | 45 | // Validate generated files 46 | ExecuteCommand("./nzslc test_files/Shader.nzsl"); 47 | ExecuteCommand("./nzslc test_files/Shader.nzslb"); 48 | ExecuteCommand("glslang -S frag test_files/Shader.frag.glsl"); 49 | ExecuteCommand("spirv-val test_files/Shader.spv"); 50 | CheckFileMatch("../resources/Shader.glsl.binding.json", "test_files/Shader.glsl.binding.json"); 51 | 52 | // Check that header version matches original files 53 | CheckHeaderMatch("test_files/Shader.frag.glsl"); 54 | CheckHeaderMatch("test_files/Shader.nzsl"); 55 | CheckHeaderMatch("test_files/Shader.nzslb"); 56 | CheckHeaderMatch("test_files/Shader.spv"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/src/Tests/ShaderUtils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef NAZARA_UNITTESTS_SHADER_SHADERUTILS_HPP 4 | #define NAZARA_UNITTESTS_SHADER_SHADERUTILS_HPP 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | void ExpectGLSL(nzsl::ShaderStageType stageType, const nzsl::Ast::Module& shader, std::string_view expectedOutput, const nzsl::ShaderWriter::States& options = {}, const nzsl::GlslWriter::Environment& env = {}, bool testShaderCompilation = true); 14 | void ExpectGLSL(const nzsl::Ast::Module& shader, std::string_view expectedOutput, const nzsl::ShaderWriter::States& options = {}, const nzsl::GlslWriter::Environment& env = {}, bool testShaderCompilation = true); 15 | void ExpectNZSL(const nzsl::Ast::Module& shader, std::string_view expectedOutput, const nzsl::ShaderWriter::States& options = {}); 16 | void ExpectSPIRV(const nzsl::Ast::Module& shader, std::string_view expectedOutput, const nzsl::ShaderWriter::States& options = {}, const nzsl::SpirvWriter::Environment& env = {}, bool outputParameter = false, const spvtools::ValidatorOptions& validatorOptions = {}); 17 | 18 | std::filesystem::path GetResourceDir(); 19 | 20 | nzsl::Ast::ModulePtr SanitizeModule(const nzsl::Ast::Module& module); 21 | nzsl::Ast::ModulePtr SanitizeModule(const nzsl::Ast::Module& module, const nzsl::Ast::SanitizeVisitor::Options& options); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /tests/src/Tests/ToolUtils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef NAZARA_UNITTESTS_TOOLS_TOOLUTILS_HPP 4 | #define NAZARA_UNITTESTS_TOOLS_TOOLUTILS_HPP 5 | 6 | #include 7 | #include 8 | 9 | void CheckFileMatch(const std::filesystem::path& firstFile, const std::filesystem::path& secondFile); 10 | void CheckHeaderMatch(const std::filesystem::path& originalFilepath); 11 | void ExecuteCommand(const std::string& command, const std::string& pattern = {}, std::string expectedOutput = {}); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /tests/src/main.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_RUNNER 2 | #include 3 | 4 | #include 5 | 6 | int main(int argc, char* argv[]) 7 | { 8 | if (!glslang::InitializeProcess()) 9 | return EXIT_FAILURE; 10 | 11 | int result = Catch::Session().run(argc, argv); 12 | 13 | glslang::FinalizeProcess(); 14 | 15 | return result; 16 | } 17 | -------------------------------------------------------------------------------- /tests/xmake.lua: -------------------------------------------------------------------------------- 1 | option("tests", { description = "Build unit tests", default = false }) 2 | 3 | if has_config("tests") then 4 | if has_config("asan") then 5 | add_defines("CATCH_CONFIG_NO_WINDOWS_SEH") 6 | add_defines("CATCH_CONFIG_NO_POSIX_SIGNALS") 7 | end 8 | 9 | add_requires("catch2 3", "spirv-tools", "tiny-process-library") 10 | add_requires("glslang", { configs = { rtti = has_config("ubsan") } }) -- ubsan requires rtti 11 | 12 | add_includedirs("src") 13 | 14 | target("UnitTests", function () 15 | set_kind("binary") 16 | set_group("Tests") 17 | add_headerfiles("src/**.hpp") 18 | add_files("src/main.cpp", { unity_ignored = true }) 19 | add_files("src/**.cpp") 20 | 21 | add_deps("nzsl") 22 | add_packages("catch2", "glslang", "spirv-tools") 23 | 24 | if has_config("with_nzslc") then 25 | add_deps("nzslc", { links = {} }) 26 | add_packages("fmt", "tiny-process-library") 27 | else 28 | remove_files("src/Tests/NzslcTests.cpp") 29 | end 30 | 31 | if has_config("with_nzsla") then 32 | add_deps("nzsla", { links = {} }) 33 | add_packages("fmt", "tiny-process-library") 34 | else 35 | remove_files("src/Tests/NzslaTests.cpp") 36 | end 37 | 38 | if not has_config("with_nzsla", "with_nzslc") then 39 | remove_headerfiles("src/Tests/ToolTests.hpp") 40 | remove_files("src/Tests/ToolTests.cpp") 41 | end 42 | end) 43 | end 44 | -------------------------------------------------------------------------------- /xmake/rules/debug_suffix.lua: -------------------------------------------------------------------------------- 1 | -- Adds -d as a debug suffix 2 | rule("debug_suffix") 3 | on_load(function (target) 4 | if target:kind() ~= "binary" then 5 | target:set("basename", target:basename() .. "-d") 6 | end 7 | end) 8 | -------------------------------------------------------------------------------- /xmake/rules/wasm_files.lua: -------------------------------------------------------------------------------- 1 | -- Copies every other file along with generated .html (see https://github.com/xmake-io/xmake/issues/2645) 2 | rule("wasm_files") 3 | on_load("wasm", function (target) 4 | if target:kind() == "binary" then 5 | target:add("installfiles", (target:targetfile():gsub("%.html", ".js")), { prefixdir = "bin" }) 6 | target:add("installfiles", (target:targetfile():gsub("%.html", ".mem")), { prefixdir = "bin" }) 7 | target:add("installfiles", (target:targetfile():gsub("%.html", ".mjs")), { prefixdir = "bin" }) 8 | target:add("installfiles", (target:targetfile():gsub("%.html", ".wasm")), { prefixdir = "bin" }) 9 | end 10 | end) 11 | --------------------------------------------------------------------------------