diff --git a/.configurations/configuration.dsc.yaml b/.configurations/configuration.dsc.yaml
deleted file mode 100644
index 77f910e0..00000000
--- a/.configurations/configuration.dsc.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2
-properties:
- resources:
- - resource: Microsoft.WinGet.DSC/WinGetPackage
- id: vsPackage
- directives:
- description: Install Visual Studio 2022 Community
- module: Microsoft.WinGet.DSC
- allowPrerelease: true
- settings:
- id: Microsoft.VisualStudio.2022.Community
- source: winget
- - resource: Microsoft.VisualStudio.DSC/VSComponents
- id: vsConfig
- dependsOn:
- - vsPackage
- directives:
- description: Install required VS workloads
- module: Microsoft.VisualStudio.DSC
- allowPrerelease: true
- settings:
- productId: Microsoft.VisualStudio.Product.Community
- channelId: VisualStudio.17.Release
- includeRecommended: true
- Components:
- - Microsoft.VisualStudio.Workload.NativeGame
- - resource: Microsoft.WinGet.DSC/WinGetPackage
- dependsOn:
- - vsConfig
- directives:
- description: Install Microsoft GDK
- module: Microsoft.WinGet.DSC
- allowPrerelease: true
- settings:
- id: Microsoft.GDK.2303
- source: winget
- configurationVersion: 0.2.0
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..f15501a0
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*.{cpp,h,inl,fx,fxh,hlsl,hlsli}]
+indent_size = 4
+indent_style = space
+trim_trailing_whitespace = true
+insert_final_newline = true
+end_of_line = crlf
+charset = latin1
diff --git a/.gitattributes b/.gitattributes
index 0bda1ce6..af734a06 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,7 +1,6 @@
-# Auto detect text files and perform LF normalization
* text=auto
-
# Explicitly declare code/VS files as CRLF
+*.cs eol=crlf
*.cpp eol=crlf
*.cmd eol=crlf
*.h eol=crlf
@@ -11,17 +10,82 @@
*.fxh eol=crlf
*.inc eol=crlf
*.inl eol=crlf
+*.csproj eol=crlf
*.vcxproj eol=crlf
*.filters eol=crlf
*.sln eol=crlf
-
-# Explicitly declare resource files as binary
-*.docx binary
-*.pdb binary
-*.dds binary
-*.sdkmesh binary
-*.spritefont binary
-*.wav binary
-*.xwb binary
-*.jpg binary
-*.png binary
+# Binary
+*.bin filter=lfs diff=lfs merge=lfs -text
+*.BIN filter=lfs diff=lfs merge=lfs -text
+*.exe filter=lfs diff=lfs merge=lfs -text
+*.dll filter=lfs diff=lfs merge=lfs -text
+*.pdb filter=lfs diff=lfs merge=lfs -text
+*.pdn filter=lfs diff=lfs merge=lfs -text
+*.vsix filter=lfs diff=lfs merge=lfs -text
+*.*_ filter=lfs diff=lfs merge=lfs -text
+# Assets
+*.xbtc filter=lfs diff=lfs merge=lfs -text
+*.fbx filter=lfs diff=lfs merge=lfs -text
+*.glb filter=lfs diff=lfs merge=lfs -text
+*.gltf filter=lfs diff=lfs merge=lfs -text
+*.mb filter=lfs diff=lfs merge=lfs -text
+*.rasterfont filter=lfs diff=lfs merge=lfs -text
+*.sdkmesh filter=lfs diff=lfs merge=lfs -text
+*.sdkmesh_anim filter=lfs diff=lfs merge=lfs -text
+*.spritefont filter=lfs diff=lfs merge=lfs -text
+*.ttf filter=lfs diff=lfs merge=lfs -text
+*.otf filter=lfs diff=lfs merge=lfs -text
+# Unity Assets
+*.unitypackage filter=lfs diff=lfs merge=lfs -text
+# Images
+*.bmp filter=lfs diff=lfs merge=lfs -text
+*.BMP filter=lfs diff=lfs merge=lfs -text
+*.dds filter=lfs diff=lfs merge=lfs -text
+*.DDS filter=lfs diff=lfs merge=lfs -text
+*.gif filter=lfs diff=lfs merge=lfs -text
+*.hdr filter=lfs diff=lfs merge=lfs -text
+*.jpg filter=lfs diff=lfs merge=lfs -text
+*.JPG filter=lfs diff=lfs merge=lfs -text
+*.jpeg filter=lfs diff=lfs merge=lfs -text
+*.pfm filter=lfs diff=lfs merge=lfs -text
+*.png filter=lfs diff=lfs merge=lfs -text
+*.PNG filter=lfs diff=lfs merge=lfs -text
+*.svg filter=lfs diff=lfs merge=lfs -text
+*.tga filter=lfs diff=lfs merge=lfs -text
+*.TGA filter=lfs diff=lfs merge=lfs -text
+*.tif filter=lfs diff=lfs merge=lfs -text
+*.TIF filter=lfs diff=lfs merge=lfs -text
+*.tiff filter=lfs diff=lfs merge=lfs -text
+*.wdp filter=lfs diff=lfs merge=lfs -text
+# Video/Audio
+*.mp4 filter=lfs diff=lfs merge=lfs -text
+*.wav filter=lfs diff=lfs merge=lfs -text
+*.xwb filter=lfs diff=lfs merge=lfs -text
+*.xwma filter=lfs diff=lfs merge=lfs -text
+*.ogg filter=lfs diff=lfs merge=lfs -text
+# Misc
+*.docx filter=lfs diff=lfs merge=lfs -text
+*.pptx filter=lfs diff=lfs merge=lfs -text
+*.xvd filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
+*.snk filter=lfs diff=lfs merge=lfs -text
+*.AlignmentChunk filter=lfs diff=lfs merge=lfs -text
+# Exceptions needed for build
+*.lib -text
+Infrastructure/Policheck/*.mdb filter= diff= merge= -text
+Infrastructure/Automation/dependencies/XTF/*.dll filter= diff= merge= -text
+Infrastructure/Tools/InstallerWait.exe filter= diff= merge= -text
+Infrastructure/Tools/nuget.exe filter= diff= merge= -text
+Samples/Live/GameService/Game_Service_Configuration_and_Documentation.docx filter=lfs diff=lfs merge=lfs -text
+Samples/Live/GameService/Readme.docx filter=lfs diff=lfs merge=lfs -text
+Samples/Live/MicrosoftStoreService/MicrosoftStoreService/Microsoft_Store_Service_Configuration_and_Documentation.docx filter=lfs diff=lfs merge=lfs -text
+Samples/Live/MicrosoftStoreService/MicrosoftStoreService/Readme.docx filter=lfs diff=lfs merge=lfs -text
+Samples/_Deprecated/GameService_LegacyXTokens/GameService_ReadMe_ja-jp.docx filter=lfs diff=lfs merge=lfs -text
+Samples/_Deprecated/GameService_LegacyXTokens/GameService_ReadMe_ko-kr.docx filter=lfs diff=lfs merge=lfs -text
+Samples/_Deprecated/GameService_LegacyXTokens/GameService_ReadMe_zh-cn.docx filter=lfs diff=lfs merge=lfs -text
+Samples/_Deprecated/GameService_LegacyXTokens/LocalizedDocumentation/Game_Service_Readme_ja-jp.docx filter=lfs diff=lfs merge=lfs -text
+Samples/_Deprecated/GameService_LegacyXTokens/LocalizedDocumentation/Game_Service_Readme_ko-kr.docx filter=lfs diff=lfs merge=lfs -text
+Samples/_Deprecated/GameService_LegacyXTokens/LocalizedDocumentation/Game_Service_Readme_zh-cn.docx filter=lfs diff=lfs merge=lfs -text
+Kits/AMDTK/fidelityfx/tools/binary_store/FidelityFX_SC.exe filter= diff= merge= -text
+Kits/AMDTK/fidelityfx/tools/binary_store/glslangValidator.exe filter= diff= merge= -text
+Wiki/Media/*.png filter= diff= merge= -text
diff --git a/.gitignore b/.gitignore
index 51cb59f4..01e13a2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,40 +1,471 @@
-*.psess
-*.aps
-*.vsp
-*.log
-*.err
-*.wrn
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Original from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
*.suo
-*.sdf
*.user
-*.i
+*.userosscache
+*.sln.docstates
+
+# shortcuts
+*.lnk
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+**/xbox/build/
+Gaming.Desktop.x64/
+Gaming.Xbox.x64/
+Gaming.Xbox.XboxOne.x64/
+Gaming.Xbox.Scarlett.x64/
+[Pp]rofile/
+
+# ignore Unity samples for now?
+#[Uu]nitySamples/
+
+# ignore Unity GDK version mapper working files
+Scripts/Unity for Game Core Downloads - Microsoft Game Core on Xbox - Unity Discussions.html
+Scripts/Unity for Game Core Downloads - Microsoft Game Core on Xbox - Unity Discussions_files/
+Scripts/page_text.txt
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
*.vspscc
-*.opensdf
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+*.wrn
+*.err
+*.cso
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
*.opendb
-*.ipch
-*.cache
-*.tlog
-*.lastbuildstate
-*.ilk
+*.opensdf
+*.sdf
+*.cachefile
*.VC.db
-.vs
-"Generated Files"
-Bin
-ipch
-Debug
-Profile
-Release
-x64
-Gaming.Desktop.x64
-Gaming.Xbox.XboxOne.x64
-Gaming.Xbox.Scarlett.x64
-Kits/DirectXTK12/Src/Shaders/Compiled/
-Kits/DirectXTex/Shaders/Compiled/
-/wiki
-AppPackages
-packages
-!Kits/OpenSource/**/
-.vscode
-.editorconfig
-Directory.Build.props
-Directory.Build.targets
\ No newline at end of file
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross 4form F# VS Code tools) working folder
+.ionide/
+
+# vcpkg artifacts
+vcpkg_installed/
+
+# CMake out folder
+out/
+CMakeUserPresets.json
+
+# ignore User folder for samples
+User/*
+
+# ignore location for AtgSample.exe
+Infrastructure/Tools/AtgSample.exe
+
+
+# Ignore kit binaries & shaders and tests
+Kits/DirectXMesh/Bin
+Kits/DirectXTex/Bin
+Kits/DirectXTK12/Bin
+Kits/DirectXMesh/build
+Kits/DirectXTex/build
+Kits/DirectXTK12/build
+Kits/DirectXTK12/Src/Shaders/Compiled/*.inc
+Kits/DirectXTK12/Src/Shaders/Compiled/*.pdb
+Kits/DirectXTex/Shaders/Compiled/*.inc
+Kits/DirectXTex/Shaders/Compiled/*.pdb
+Kits/DirectXMesh/Tests
+Kits/DirectXTex/Tests
+Kits/DirectXTK12/Tests
+Kits/DirectXMesh/wiki
+Kits/DirectXTex/wiki
+Kits/DirectXTK12/wiki
+
+# Build related files we need to allow
+!Infrastructure/Tools/*.exe
+
+# Ignore VSIX payload modifications
+Infrastructure/Templates/**/[Pp]ayload/*.vstemplate
+!Infrastructure/Templates/**/*_branding_*/[Pp]ayload/*.vstemplate
+!Infrastructure/Templates/**/UITKMediaItems/[Pp]ayload/*.vstemplate
+Infrastructure/Templates/**/[Pp]ayload/Assets/
+Infrastructure/Templates/**/[Pp]ayload/Kits/
+
+# Ignore ATG build/dist folders
+SDKDist/
+LocalDist/
+
+# Ignore some LIVE package script stuff
+Samples/Live/Fundamentals_Desktop/Package/
+
+# Ignore HlslCompile sample tool
+Samples/Graphics/HlslCompile/*.exe
+
+# Ignore some NR stufff
+Samples/Live/NetRumble/GameLayout/
+Samples/Live/NetRumble_Desktop/GameLayout/
+
+# Ignore PSO stuff
+Samples/Graphics/AdvancedPSO/PSOGen/*.dll
+
+# SFS sample from SiGMA uses unusual extension for shaders
+!Samples/Graphics/SamplerFeedbackStreaming/Common/*.pfx
+!Samples/Graphics/SamplerFeedbackStreaming/Streaming/*.pfx
+
+# LLVM required files
+!LLVMGXDK-Changes/**
+
+# Include all OpenSource files
+!Kits/OpenSource/**
+
+# Ignore some alternative shader names
+*.csh
+
+# Ignore .orig files that happen from doing merges
+*.orig
+/Samples/Live/GameService/GameService/Properties/launchSettings.json
+/Samples/Live/GameService/Microsoft.XboxSecureTokens/Properties/launchSettings.json
+
+# Ignore the Properties folder of the GameService samples (these have usually deployment info specific to when I am testing and should not be checked in)
+Samples/Live/GameService/GameService/Properties/
+/Samples/Graphics/VRSandSparseLighting.zip
+
+# Ignore VSCode folder
+.vscode/
+/Samples/Live/InGameStore/output
+/Samples/Live/InGameStore/chunks.xml
+/Samples/Live/InGameStore/makescarlettpkg.cmd
+
+# Ignore output of AdvancedPSO
+psoset/
+
+# Ignore some AMDTK binary store copies of Microsoft files
+Kits/AMDTK/fidelityfx/tools/binary_store/[Dd]3[Dd]*.*
+Kits/AMDTK/fidelityfx/tools/binary_store/[Dd][Xx]*.*
+
+# Auto-generated GDK version cache (created by Scripts/Resolve-GdkVersion.ps1)
+Infrastructure/Build/GdkVersions.g.props
+Infrastructure/Build/GdkVersions.Specs.g.props
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 00000000..0979a2b7
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,20 @@
+
+
+
+
+ false
+
+
+
+ $(VCPKG_ROOT)
+ $(VSINSTALLDIR)VC\vcpkg
+
+ $([System.IO.Path]::GetFullPath('$(MSBuildExtensionsPath)\..\VC\vcpkg'))
+ $(MSBuildThisFileDirectory)vcpkg
+
+
+ true
+
+
diff --git a/Directory.Build.targets b/Directory.Build.targets
new file mode 100644
index 00000000..5ff29d81
--- /dev/null
+++ b/Directory.Build.targets
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/Kits/AMDTK/GLTF/GLTFResources.cpp b/Kits/AMDTK/GLTF/GltfResources.cpp
similarity index 100%
rename from Kits/AMDTK/GLTF/GLTFResources.cpp
rename to Kits/AMDTK/GLTF/GltfResources.cpp
diff --git a/Kits/AMDTK/GLTF/GLTFResources.h b/Kits/AMDTK/GLTF/GltfResources.h
similarity index 100%
rename from Kits/AMDTK/GLTF/GLTFResources.h
rename to Kits/AMDTK/GLTF/GltfResources.h
diff --git a/Kits/AMDTK/Readme.txt b/Kits/AMDTK/Readme.txt
new file mode 100644
index 00000000..ac234d30
--- /dev/null
+++ b/Kits/AMDTK/Readme.txt
@@ -0,0 +1,9 @@
+AMD Tool Kit
+
+Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+
+Selection of customised GPUOpen Cauldron based utilities for use in sample code.
+
+Unless otherwise noted, all source code is subject to the terms of the MIT License.
+.
+
diff --git a/Kits/AMDTK/ffx-api/PrebuiltSignedDLL/amd_fidelityfx_dx12.dll b/Kits/AMDTK/ffx-api/PrebuiltSignedDLL/amd_fidelityfx_dx12.dll
index 9bd0fbbf..5ba1c77a 100644
Binary files a/Kits/AMDTK/ffx-api/PrebuiltSignedDLL/amd_fidelityfx_dx12.dll and b/Kits/AMDTK/ffx-api/PrebuiltSignedDLL/amd_fidelityfx_dx12.dll differ
diff --git a/Kits/AMDTK/ffx-api/include/ffx_api/ffx_api_loader.h b/Kits/AMDTK/ffx-api/include/ffx_api/ffx_api_loader.h
new file mode 100644
index 00000000..9df9ac32
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/include/ffx_api/ffx_api_loader.h
@@ -0,0 +1,43 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+
+#include "ffx_api.h"
+#include
+
+typedef struct ffxFunctions {
+ PfnFfxCreateContext CreateContext;
+ PfnFfxDestroyContext DestroyContext;
+ PfnFfxConfigure Configure;
+ PfnFfxQuery Query;
+ PfnFfxDispatch Dispatch;
+} ffxFunctions;
+
+static inline void ffxLoadFunctions(ffxFunctions* pOutFunctions, HMODULE module)
+{
+ pOutFunctions->CreateContext = (PfnFfxCreateContext )GetProcAddress(module, "ffxCreateContext");
+ pOutFunctions->DestroyContext = (PfnFfxDestroyContext)GetProcAddress(module, "ffxDestroyContext");
+ pOutFunctions->Configure = (PfnFfxConfigure )GetProcAddress(module, "ffxConfigure");
+ pOutFunctions->Query = (PfnFfxQuery )GetProcAddress(module, "ffxQuery");
+ pOutFunctions->Dispatch = (PfnFfxDispatch )GetProcAddress(module, "ffxDispatch");
+}
diff --git a/Kits/AMDTK/ffx-api/include/ffx_api/vk/ffx_api_vk.h b/Kits/AMDTK/ffx-api/include/ffx_api/vk/ffx_api_vk.h
new file mode 100644
index 00000000..1f56ea6d
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/include/ffx_api/vk/ffx_api_vk.h
@@ -0,0 +1,360 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include "../ffx_api.h"
+#include "../ffx_api_types.h"
+#include
+
+/// FFX specific callback type when submitting a command buffer to a queue.
+typedef VkResult (*PFN_vkQueueSubmitFFXAPI)(uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence);
+
+/// Helper stucture
+struct VkQueueInfoFFXAPI
+{
+ VkQueue queue; ///< the vulkan queue
+ uint32_t familyIndex; ///< the queue family index, that will be used to perform queue family ownership transfer
+ PFN_vkQueueSubmitFFXAPI submitFunc; ///< an optional submit function in case there might be some concurrent submissions
+};
+
+#define FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_VK 0x0000003u
+struct ffxCreateBackendVKDesc
+{
+ ffxCreateContextDescHeader header;
+ VkDevice vkDevice; ///< the logical device used by the program.
+ VkPhysicalDevice vkPhysicalDevice; ///< the physical device used by the program.
+ PFN_vkGetDeviceProcAddr vkDeviceProcAddr; ///< function pointer to get device procedure addresses
+};
+
+#define FFX_API_EFFECT_ID_FGSC_VK 0x00040000u
+
+#define FFX_API_CREATE_CONTEXT_DESC_TYPE_FGSWAPCHAIN_VK 0x40001u
+struct ffxCreateContextDescFrameGenerationSwapChainVK
+{
+ ffxCreateContextDescHeader header;
+ VkPhysicalDevice physicalDevice; ///< the physicak device used by the program.
+ VkDevice device; ///< the logical device used by the program.
+ VkSwapchainKHR* swapchain; ///< the current swapchain to be replaced. Will be destroyed when the context is created. This can be VK_NULL_HANDLE. Will contain the new swapchain on return.
+ VkAllocationCallbacks* allocator; ///< optional allocation callbacks.
+ VkSwapchainCreateInfoKHR createInfo; ///< the description of the desired swapchain. If its VkSwapchainCreateInfoKHR::oldSwapchain field isn't VK_NULL_HANDLE, it should be the same as the ffxCreateContextDescFrameGenerationSwapChainVK::swapchain field above.
+ VkQueueInfoFFXAPI gameQueue; ///< the main graphics queue, where Present is called.
+ VkQueueInfoFFXAPI asyncComputeQueue; ///< A queue with Compute capability.
+ VkQueueInfoFFXAPI presentQueue; ///< A queue with Transfer and Present capabilities.
+ VkQueueInfoFFXAPI imageAcquireQueue; ///< A queue with no capability required.
+};
+
+#define FFX_API_CONFIGURE_DESC_TYPE_FGSWAPCHAIN_REGISTERUIRESOURCE_VK 0x40002u
+struct ffxConfigureDescFrameGenerationSwapChainRegisterUiResourceVK
+{
+ ffxConfigureDescHeader header;
+ struct FfxApiResource uiResource; ///< Resource containing user interface for composition. May be empty.
+ uint32_t flags; ///< Zero or combination of values from FfxApiUiCompositionFlags.
+};
+
+#define FFX_API_QUERY_DESC_TYPE_FGSWAPCHAIN_INTERPOLATIONCOMMANDLIST_VK 0x40003u
+struct ffxQueryDescFrameGenerationSwapChainInterpolationCommandListVK
+{
+ ffxQueryDescHeader header;
+ void** pOutCommandList; ///< Output command nuffer (VkCommandBuffer) to be used for frame generation dispatch.
+};
+
+#define FFX_API_QUERY_DESC_TYPE_FGSWAPCHAIN_INTERPOLATIONTEXTURE_VK 0x40004u
+struct ffxQueryDescFrameGenerationSwapChainInterpolationTextureVK
+{
+ ffxQueryDescHeader header;
+ struct FfxApiResource* pOutTexture; ///< Output resource in which the frame interpolation result should be placed.
+};
+
+#define FFX_API_DISPATCH_DESC_TYPE_FGSWAPCHAIN_WAIT_FOR_PRESENTS_VK 0x40007u
+struct ffxDispatchDescFrameGenerationSwapChainWaitForPresentsVK
+{
+ ffxDispatchDescHeader header;
+};
+
+#define FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_KEYVALUE_VK 0x40008u
+struct ffxConfigureDescFrameGenerationSwapChainKeyValueVK
+{
+ ffxConfigureDescHeader header;
+ uint64_t key; ///< Configuration key, member of the FfxApiConfigureFrameGenerationSwapChainKeyVK enumeration.
+ uint64_t u64; ///< Integer value or enum value to set.
+ void* ptr; ///< Pointer to set or pointer to value to set.
+};
+
+//enum value matches enum FfxFrameInterpolationSwapchainConfigureKey
+enum FfxApiConfigureFrameGenerationSwapChainKeyVK
+{
+ FFX_API_CONFIGURE_FG_SWAPCHAIN_KEY_WAITCALLBACK = 0, ///< Sets FfxWaitCallbackFunc
+ FFX_API_CONFIGURE_FG_SWAPCHAIN_KEY_FRAMEPACINGTUNING = 2, ///< Sets FfxApiSwapchainFramePacingTuning casted from ptr
+};
+
+#define FFX_API_QUERY_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_GPU_MEMORY_USAGE_VK 0x00040009u
+struct ffxQueryFrameGenerationSwapChainGetGPUMemoryUsageVK
+{
+ ffxQueryDescHeader header;
+ struct FfxApiEffectMemoryUsage* gpuMemoryUsageFrameGenerationSwapchain;
+};
+
+/// Function to get the number of presents. This is useful when using frame interpolation
+typedef uint64_t (*PFN_getLastPresentCountFFXAPI)(VkSwapchainKHR);
+
+/// FFX API specific functions to create and destroy a swapchain
+typedef VkResult(*PFN_vkCreateSwapchainFFXAPI)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain, void* pContext);
+typedef void(*PFN_vkDestroySwapchainFFXAPI)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator, void* pContext);
+
+#define FFX_API_QUERY_DESC_TYPE_FGSWAPCHAIN_FUNCTIONS_VK 0x40005u
+struct ffxQueryDescSwapchainReplacementFunctionsVK
+{
+ ffxQueryDescHeader header;
+ PFN_vkCreateSwapchainFFXAPI pOutCreateSwapchainFFXAPI; ///< Replacement of vkCreateSwapchainKHR. Can be called when swapchain is recreated but swapchain context isn't (for example when toggling vsync).
+ PFN_vkDestroySwapchainFFXAPI pOutDestroySwapchainFFXAPI; ///< Replacement of vkDestroySwapchainKHR. Can be called when swapchain is destroyed but swapchain context isn't.
+ PFN_vkGetSwapchainImagesKHR pOutGetSwapchainImagesKHR; ///< Replacement of vkGetSwapchainImagesKHR.
+ PFN_vkAcquireNextImageKHR pOutAcquireNextImageKHR; ///< Replacement of vkAcquireNextImageKHR.
+ PFN_vkQueuePresentKHR pOutQueuePresentKHR; ///< Replacement of vkQueuePresentKHR.
+ PFN_vkSetHdrMetadataEXT pOutSetHdrMetadataEXT; ///< Replacement of vkSetHdrMetadataEXT.
+ PFN_getLastPresentCountFFXAPI pOutGetLastPresentCountFFXAPI; ///< Additional function to get the number of times present has been called since the swapchain creation.
+};
+
+#define FFX_API_CREATE_CONTEXT_DESC_TYPE_FGSWAPCHAIN_MODE_VK 0x40010u
+struct ffxCreateContextDescFrameGenerationSwapChainModeVK
+{
+ ffxCreateContextDescHeader header;
+ bool composeOnPresentQueue; ///< flags indicating that composition will happen on the present queue
+};
+
+static inline uint32_t ffxApiGetSurfaceFormatVK(VkFormat fmt)
+{
+ switch (fmt)
+ {
+ case VK_FORMAT_R32G32B32A32_SFLOAT:
+ return FFX_API_SURFACE_FORMAT_R32G32B32A32_FLOAT;
+ case VK_FORMAT_R32G32B32_SFLOAT:
+ return FFX_API_SURFACE_FORMAT_R32G32B32_FLOAT;
+ case VK_FORMAT_R32G32B32A32_UINT:
+ return FFX_API_SURFACE_FORMAT_R32G32B32A32_UINT;
+ case VK_FORMAT_R16G16B16A16_SFLOAT:
+ return FFX_API_SURFACE_FORMAT_R16G16B16A16_FLOAT;
+ case VK_FORMAT_R32G32_SFLOAT:
+ return FFX_API_SURFACE_FORMAT_R32G32_FLOAT;
+ case VK_FORMAT_R32_UINT:
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ case VK_FORMAT_X8_D24_UNORM_PACK32:
+ return FFX_API_SURFACE_FORMAT_R32_UINT;
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ return FFX_API_SURFACE_FORMAT_R8G8B8A8_UNORM;
+ case VK_FORMAT_R8G8B8A8_SNORM:
+ return FFX_API_SURFACE_FORMAT_R8G8B8A8_SNORM;
+ case VK_FORMAT_R8G8B8A8_SRGB:
+ return FFX_API_SURFACE_FORMAT_R8G8B8A8_SRGB;
+ case VK_FORMAT_B8G8R8A8_UNORM:
+ return FFX_API_SURFACE_FORMAT_B8G8R8A8_UNORM;
+ case VK_FORMAT_B8G8R8A8_SRGB:
+ return FFX_API_SURFACE_FORMAT_B8G8R8A8_SRGB;
+ case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
+ return FFX_API_SURFACE_FORMAT_R11G11B10_FLOAT;
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+ return FFX_API_SURFACE_FORMAT_R10G10B10A2_UNORM;
+ case VK_FORMAT_R16G16_SFLOAT:
+ return FFX_API_SURFACE_FORMAT_R16G16_FLOAT;
+ case VK_FORMAT_R16G16_UINT:
+ return FFX_API_SURFACE_FORMAT_R16G16_UINT;
+ case VK_FORMAT_R16G16_SINT:
+ return FFX_API_SURFACE_FORMAT_R16G16_SINT;
+ case VK_FORMAT_R16_SFLOAT:
+ return FFX_API_SURFACE_FORMAT_R16_FLOAT;
+ case VK_FORMAT_R16_UINT:
+ return FFX_API_SURFACE_FORMAT_R16_UINT;
+ case VK_FORMAT_R16_UNORM:
+ case VK_FORMAT_D16_UNORM:
+ case VK_FORMAT_D16_UNORM_S8_UINT:
+ return FFX_API_SURFACE_FORMAT_R16_UNORM;
+ case VK_FORMAT_R16_SNORM:
+ return FFX_API_SURFACE_FORMAT_R16_SNORM;
+ case VK_FORMAT_R8_UNORM:
+ return FFX_API_SURFACE_FORMAT_R8_UNORM;
+ case VK_FORMAT_R8_UINT:
+ case VK_FORMAT_S8_UINT:
+ return FFX_API_SURFACE_FORMAT_R8_UINT;
+ case VK_FORMAT_R8G8_UNORM:
+ return FFX_API_SURFACE_FORMAT_R8G8_UNORM;
+ case VK_FORMAT_R8G8_UINT:
+ return FFX_API_SURFACE_FORMAT_R8G8_UINT;
+ case VK_FORMAT_R32_SFLOAT:
+ case VK_FORMAT_D32_SFLOAT:
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ return FFX_API_SURFACE_FORMAT_R32_FLOAT;
+ case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
+ return FFX_API_SURFACE_FORMAT_R9G9B9E5_SHAREDEXP;
+ case VK_FORMAT_UNDEFINED:
+ return FFX_API_SURFACE_FORMAT_UNKNOWN;
+
+ default:
+ // NOTE: we do not support typeless formats here
+ //FFX_ASSERT_MESSAGE(false, "Format not yet supported");
+ return FFX_API_SURFACE_FORMAT_UNKNOWN;
+ }
+}
+
+static inline uint32_t ffxApiGetSurfaceFormatToGamma(uint32_t fmt)
+{
+ switch (fmt)
+ {
+ case (FFX_API_SURFACE_FORMAT_R8G8B8A8_UNORM):
+ return FFX_API_SURFACE_FORMAT_R8G8B8A8_SRGB;
+ case (FFX_API_SURFACE_FORMAT_B8G8R8A8_UNORM):
+ return FFX_API_SURFACE_FORMAT_B8G8R8A8_SRGB;
+ default:
+ return fmt;
+ }
+}
+
+static inline bool ffxApiIsDepthFormat(VkFormat fmt)
+{
+ switch (fmt)
+ {
+ case VK_FORMAT_D16_UNORM:
+ case VK_FORMAT_X8_D24_UNORM_PACK32:
+ case VK_FORMAT_D32_SFLOAT:
+ case VK_FORMAT_D16_UNORM_S8_UINT:
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static inline bool ffxApiIsStencilFormat(VkFormat fmt)
+{
+ switch (fmt)
+ {
+ case VK_FORMAT_S8_UINT:
+ case VK_FORMAT_D16_UNORM_S8_UINT:
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static inline FfxApiResourceDescription ffxApiGetBufferResourceDescriptionVK(const VkBuffer buffer,
+ const VkBufferCreateInfo createInfo,
+ uint32_t additionalUsages)
+{
+ FfxApiResourceDescription resourceDescription = {};
+
+ // This is valid
+ if (buffer == VK_NULL_HANDLE)
+ return resourceDescription;
+
+ resourceDescription.flags = FFX_API_RESOURCE_FLAGS_NONE;
+ resourceDescription.usage = additionalUsages;
+ resourceDescription.size = (uint32_t)createInfo.size;
+ resourceDescription.stride = 0;
+ resourceDescription.format = FFX_API_SURFACE_FORMAT_UNKNOWN;
+
+ if ((createInfo.usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0)
+ resourceDescription.usage |= FFX_API_RESOURCE_USAGE_UAV;
+ if ((createInfo.usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) != 0)
+ resourceDescription.usage |= FFX_API_RESOURCE_USAGE_INDIRECT;
+
+ // What should we initialize this to?? No case for this yet
+ resourceDescription.depth = 0;
+ resourceDescription.mipCount = 0;
+
+ // Set the type
+ resourceDescription.type = FFX_API_RESOURCE_TYPE_BUFFER;
+
+ return resourceDescription;
+}
+
+static inline FfxApiResourceDescription ffxApiGetImageResourceDescriptionVK(const VkImage image, const VkImageCreateInfo createInfo, uint32_t additionalUsages)
+{
+ FfxApiResourceDescription resourceDescription = {};
+
+ // This is valid
+ if (image == VK_NULL_HANDLE)
+ return resourceDescription;
+
+ // Set flags properly for resource registration
+ resourceDescription.flags = FFX_API_RESOURCE_FLAGS_NONE;
+ resourceDescription.usage = FFX_API_RESOURCE_USAGE_READ_ONLY;
+
+ // Check for depth stencil use
+ if (ffxApiIsDepthFormat(createInfo.format))
+ resourceDescription.usage |= FFX_API_RESOURCE_USAGE_DEPTHTARGET;
+ if (ffxApiIsStencilFormat(createInfo.format))
+ resourceDescription.usage |= FFX_API_RESOURCE_USAGE_STENCILTARGET;
+
+ // Unordered access use
+ if ((createInfo.usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
+ resourceDescription.usage |= FFX_API_RESOURCE_USAGE_UAV;
+
+ // Resource-specific supplemental use flags
+ resourceDescription.usage |= additionalUsages;
+
+ resourceDescription.width = createInfo.extent.width;
+ resourceDescription.height = createInfo.extent.height;
+ resourceDescription.mipCount = createInfo.mipLevels;
+ resourceDescription.format = ffxApiGetSurfaceFormatVK(createInfo.format);
+
+ // if the mutable flag is present, assume that the real format is sRGB
+ if ((createInfo.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) != 0)
+ resourceDescription.format = ffxApiGetSurfaceFormatToGamma(resourceDescription.format);
+
+ switch (createInfo.imageType)
+ {
+ case VK_IMAGE_TYPE_1D:
+ resourceDescription.type = FFX_API_RESOURCE_TYPE_TEXTURE1D;
+ break;
+ case VK_IMAGE_TYPE_2D:
+ resourceDescription.depth = createInfo.arrayLayers;
+ if ((additionalUsages & FFX_API_RESOURCE_USAGE_ARRAYVIEW) != 0)
+ resourceDescription.type = FFX_API_RESOURCE_TYPE_TEXTURE2D;
+ else if ((createInfo.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0)
+ resourceDescription.type = FFX_API_RESOURCE_TYPE_TEXTURE_CUBE;
+ else
+ resourceDescription.type = FFX_API_RESOURCE_TYPE_TEXTURE2D;
+ break;
+ case VK_IMAGE_TYPE_3D:
+ resourceDescription.depth = createInfo.extent.depth;
+ resourceDescription.type = FFX_API_RESOURCE_TYPE_TEXTURE3D;
+ break;
+ default:
+ //FFX_ASSERT_MESSAGE(false, "FFXInterface: VK: Unsupported texture dimension requested. Please implement.");
+ break;
+ }
+
+ return resourceDescription;
+}
+
+static inline FfxApiResource ffxApiGetResourceVK(void* vkResource, FfxApiResourceDescription ffxResDescription, uint32_t state)
+{
+ FfxApiResource resource = {};
+ resource.resource = vkResource;
+ resource.state = state;
+ resource.description = ffxResDescription;
+
+ return resource;
+}
diff --git a/Kits/AMDTK/ffx-api/include/ffx_api/vk/ffx_api_vk.hpp b/Kits/AMDTK/ffx-api/include/ffx_api/vk/ffx_api_vk.hpp
new file mode 100644
index 00000000..6eb2cce7
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/include/ffx_api/vk/ffx_api_vk.hpp
@@ -0,0 +1,83 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+
+#include "../ffx_api.hpp"
+#include "ffx_api_vk.h"
+
+// Helper types for header initialization. Api definition is in .h file.
+
+namespace ffx
+{
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct CreateBackendVKDesc : public InitHelper {};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct CreateContextDescFrameGenerationSwapChainVK : public InitHelper {};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct CreateContextDescFrameGenerationSwapChainModeVK : public InitHelper {};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct ConfigureDescFrameGenerationSwapChainRegisterUiResourceVK : public InitHelper {};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct QueryDescFrameGenerationSwapChainInterpolationCommandListVK : public InitHelper {};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct QueryDescFrameGenerationSwapChainInterpolationTextureVK : public InitHelper {};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct QueryDescSwapchainReplacementFunctionsVK : public InitHelper {};
+
+template <>
+struct struct_type : std::integral_constant{};
+
+struct DispatchDescFrameGenerationSwapChainWaitForPresentsVK : public InitHelper{};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct ConfigureDescFrameGenerationSwapChainKeyValueVK : public InitHelper {};
+
+template<>
+struct struct_type : std::integral_constant {};
+
+struct QueryFrameGenerationSwapChainGetGPUMemoryUsageVK : public InitHelper {};
+
+}
diff --git a/Kits/AMDTK/ffx-api/src/backends.cpp b/Kits/AMDTK/ffx-api/src/backends.cpp
new file mode 100644
index 00000000..b532a2e9
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/backends.cpp
@@ -0,0 +1,125 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "backends.h"
+
+#ifdef FFX_BACKEND_DX12
+#include
+#include
+#endif // FFX_BACKEND_DX12
+#ifdef FFX_BACKEND_VK
+#include
+#include
+#endif // #ifdef FFX_BACKEND_VK
+
+ffxReturnCode_t CreateBackend(const ffxCreateContextDescHeader *desc, bool& backendFound, FfxInterface *iface, size_t contexts, Allocator& alloc)
+{
+ for (const auto* it = desc->pNext; it; it = it->pNext)
+ {
+ switch (it->type)
+ {
+#ifdef FFX_BACKEND_DX12
+ case FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12:
+ {
+ // check for double backend just to make sure.
+ if (backendFound)
+ return FFX_API_RETURN_ERROR;
+ backendFound = true;
+
+ const auto *backendDesc = reinterpret_cast(it);
+ FfxDevice device = ffxGetDeviceDX12(backendDesc->device);
+ size_t scratchBufferSize = ffxGetScratchMemorySizeDX12(contexts);
+ void* scratchBuffer = alloc.alloc(scratchBufferSize);
+ memset(scratchBuffer, 0, scratchBufferSize);
+ TRY2(ffxGetInterfaceDX12(iface, device, scratchBuffer, scratchBufferSize, contexts));
+ break;
+ }
+#elif FFX_BACKEND_VK
+ case FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_VK:
+ {
+ // check for double backend just to make sure.
+ if (backendFound)
+ return FFX_API_RETURN_ERROR;
+ backendFound = true;
+
+ const auto *backendDesc = reinterpret_cast(it);
+ VkDeviceContext deviceContext = { backendDesc->vkDevice, backendDesc->vkPhysicalDevice, backendDesc->vkDeviceProcAddr };
+ FfxDevice device = ffxGetDeviceVK(&deviceContext);
+ size_t scratchBufferSize = ffxGetScratchMemorySizeVK(backendDesc->vkPhysicalDevice, contexts);
+ void* scratchBuffer = alloc.alloc(scratchBufferSize);
+ memset(scratchBuffer, 0, scratchBufferSize);
+ TRY2(ffxGetInterfaceVK(iface, device, scratchBuffer, scratchBufferSize, contexts));
+ break;
+ }
+#endif // FFX_BACKEND_DX12
+ }
+ }
+ return FFX_API_RETURN_OK;
+}
+
+void* GetDevice(const ffxApiHeader* desc)
+{
+ for (const auto* it = desc; it; it = it->pNext)
+ {
+ switch (it->type)
+ {
+ case FFX_API_QUERY_DESC_TYPE_GET_VERSIONS:
+ {
+ return reinterpret_cast(it)->device;
+ }
+#ifdef FFX_BACKEND_DX12
+ case FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12:
+ {
+ return reinterpret_cast(it)->device;
+ }
+ case FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_FOR_HWND_DX12:
+ {
+ ID3D12Device* device = nullptr;
+ reinterpret_cast(it)->gameQueue->GetDevice(IID_PPV_ARGS(&device));
+ device->Release();
+ return device;
+ }
+ case FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_NEW_DX12:
+ {
+ ID3D12Device* device = nullptr;
+ reinterpret_cast(it)->gameQueue->GetDevice(IID_PPV_ARGS(&device));
+ device->Release();
+ return device;
+ }
+ case FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_WRAP_DX12:
+ {
+ ID3D12Device* device = nullptr;
+ reinterpret_cast(it)->gameQueue->GetDevice(IID_PPV_ARGS(&device));
+ device->Release();
+ return device;
+ }
+#endif
+#ifdef FFX_BACKEND_VK
+ case FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_VK:
+ {
+ return nullptr; // no idea what to return for now.
+ }
+#endif
+ }
+ }
+ return nullptr;
+}
diff --git a/Kits/AMDTK/ffx-api/src/backends.h b/Kits/AMDTK/ffx-api/src/backends.h
new file mode 100644
index 00000000..4ac2a546
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/backends.h
@@ -0,0 +1,38 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include "ffx_provider.h"
+#include
+#include
+
+ffxReturnCode_t CreateBackend(const ffxCreateContextDescHeader* desc, bool& backendFound, FfxInterface* iface, size_t contexts, Allocator& alloc);
+
+inline ffxReturnCode_t MustCreateBackend(const ffxCreateContextDescHeader* desc, FfxInterface* iface, size_t contexts, Allocator& alloc)
+{
+ bool backendFound = false;
+ TRY(CreateBackend(desc, backendFound, iface, contexts, alloc));
+ VERIFY(backendFound, FFX_API_RETURN_ERROR);
+ return FFX_API_RETURN_OK;
+}
+
+void* GetDevice(const ffxApiHeader* desc);
diff --git a/Kits/AMDTK/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.cpp b/Kits/AMDTK/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.cpp
new file mode 100644
index 00000000..9fac8eeb
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.cpp
@@ -0,0 +1,198 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifdef FFX_BACKEND_DX12
+#include "ffx_provider_framegenerationswapchain_dx12.h"
+#include
+#include
+#include
+
+#include
+
+bool ffxProvider_FrameGenerationSwapChain_DX12::CanProvide(uint64_t type) const
+{
+ return (type & FFX_API_EFFECT_MASK) == FFX_API_EFFECT_ID_FRAMEGENERATIONSWAPCHAIN_DX12;
+}
+
+struct InternalFgScContext
+{
+ InternalContextHeader header;
+ IDXGISwapChain4* fiSwapChain;
+};
+
+uint64_t ffxProvider_FrameGenerationSwapChain_DX12::GetId() const
+{
+ // FG SwapChain DX12, version 1.1.3
+ return 0xF65C'DD12'01'001'003ui64;
+}
+
+const char* ffxProvider_FrameGenerationSwapChain_DX12::GetVersionName() const
+{
+ return "1.1.3";
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_DX12::CreateContext(ffxContext* context,
+ ffxCreateContextDescHeader* header,
+ Allocator& alloc) const
+{
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ InternalFgScContext* internal_context = alloc.construct();
+ VERIFY(internal_context, FFX_API_RETURN_ERROR_MEMORY);
+ internal_context->header.provider = this;
+
+ FfxSwapchain swapChain = ffxGetSwapchainDX12(*desc->swapchain);
+ TRY2(ffxReplaceSwapchainForFrameinterpolationDX12(desc->gameQueue, swapChain));
+ internal_context->fiSwapChain = *desc->swapchain = ffxGetDX12SwapchainPtr(swapChain);
+
+ // reference tracked by internal_context
+ internal_context->fiSwapChain->AddRef();
+
+ *context = internal_context;
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ InternalFgScContext* internal_context = alloc.construct();
+ VERIFY(internal_context, FFX_API_RETURN_ERROR_MEMORY);
+ internal_context->header.provider = this;
+
+ FfxSwapchain swapChain;
+ TRY2(ffxCreateFrameinterpolationSwapchainDX12(desc->desc, desc->gameQueue, desc->dxgiFactory, swapChain));
+ internal_context->fiSwapChain = *desc->swapchain = ffxGetDX12SwapchainPtr(swapChain);
+
+ // reference tracked by internal_context
+ internal_context->fiSwapChain->AddRef();
+
+ *context = internal_context;
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ InternalFgScContext* internal_context = alloc.construct();
+ VERIFY(internal_context, FFX_API_RETURN_ERROR_MEMORY);
+ internal_context->header.provider = this;
+
+ FfxSwapchain swapChain;
+ TRY2(ffxCreateFrameinterpolationSwapchainForHwndDX12(desc->hwnd, desc->desc, desc->fullscreenDesc, desc->gameQueue, desc->dxgiFactory, swapChain));
+ internal_context->fiSwapChain = *desc->swapchain = ffxGetDX12SwapchainPtr(swapChain);
+
+ // reference tracked by internal_context
+ internal_context->fiSwapChain->AddRef();
+
+ *context = internal_context;
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_DX12::DestroyContext(ffxContext* context, Allocator& alloc) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+
+ internal_context->fiSwapChain->Release();
+
+ alloc.dealloc(internal_context);
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_DX12::Configure(ffxContext* context, const ffxConfigureDescHeader* header) const
+{
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ TRY2(ffxRegisterFrameinterpolationUiResourceDX12(ffxGetSwapchainDX12(internal_context->fiSwapChain), Convert(desc->uiResource), desc->flags));
+
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ TRY2(ffxConfigureFrameInterpolationSwapchainDX12(ffxGetSwapchainDX12(internal_context->fiSwapChain), static_cast (desc->key), desc->ptr));
+
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_PARAMETER;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_DX12::Query(ffxContext* context, ffxQueryDescHeader* header) const
+{
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ FfxCommandList outCommandList{};
+ TRY2(ffxGetFrameinterpolationCommandlistDX12(ffxGetSwapchainDX12(internal_context->fiSwapChain), outCommandList));
+ *desc->pOutCommandList = outCommandList;
+
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ *desc->pOutTexture = Convert(ffxGetFrameinterpolationTextureDX12(ffxGetSwapchainDX12(internal_context->fiSwapChain)));
+
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ TRY2(ffxFrameInterpolationSwapchainGetGpuMemoryUsageDX12(ffxGetSwapchainDX12(internal_context->fiSwapChain), reinterpret_cast (desc->gpuMemoryUsageFrameGenerationSwapchain)));
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_PARAMETER;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_DX12::Dispatch(ffxContext* context, const ffxDispatchDescHeader* header) const
+{
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ ffxWaitForPresents(internal_context->fiSwapChain);
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR;
+ }
+}
+
+ffxProvider_FrameGenerationSwapChain_DX12 ffxProvider_FrameGenerationSwapChain_DX12::Instance;
+#endif // FFX_BACKEND_DX12
diff --git a/Kits/AMDTK/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.h b/Kits/AMDTK/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.h
new file mode 100644
index 00000000..095b7866
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.h
@@ -0,0 +1,51 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#ifdef FFX_BACKEND_DX12
+#include "../ffx_provider.h"
+
+class ffxProvider_FrameGenerationSwapChain_DX12: public ffxProvider
+{
+public:
+ ffxProvider_FrameGenerationSwapChain_DX12() = default;
+ virtual ~ffxProvider_FrameGenerationSwapChain_DX12() = default;
+
+ virtual bool CanProvide(uint64_t type) const override;
+
+ virtual uint64_t GetId() const override;
+
+ virtual const char* GetVersionName() const override;
+
+ virtual ffxReturnCode_t CreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t DestroyContext(ffxContext* context, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t Configure(ffxContext* context, const ffxConfigureDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Query(ffxContext* context, ffxQueryDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Dispatch(ffxContext* context, const ffxDispatchDescHeader* desc) const override;
+
+ static ffxProvider_FrameGenerationSwapChain_DX12 Instance;
+};
+#endif // FFX_BACKEND_DX12
diff --git a/Kits/AMDTK/ffx-api/src/ffx_api.cpp b/Kits/AMDTK/ffx-api/src/ffx_api.cpp
new file mode 100644
index 00000000..9852e632
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_api.cpp
@@ -0,0 +1,132 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include
+#include
+#include
+#include "ffx_provider.h"
+#include "backends.h"
+
+static uint64_t GetVersionOverride(const ffxApiHeader* header)
+{
+ for (auto it = header; it; it = it->pNext)
+ {
+ if (auto versionDesc = ffx::DynamicCast(it))
+ {
+ return versionDesc->versionId;
+ }
+ }
+ return 0;
+}
+
+FFX_API_ENTRY ffxReturnCode_t ffxCreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb)
+{
+ VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+
+ *context = nullptr;
+
+ const ffxProvider* provider = GetffxProvider(desc->type, GetVersionOverride(desc), GetDevice(desc));
+ VERIFY(provider != nullptr, FFX_API_RETURN_NO_PROVIDER);
+
+ Allocator alloc{memCb};
+ return provider->CreateContext(context, desc, alloc);
+}
+
+FFX_API_ENTRY ffxReturnCode_t ffxDestroyContext(ffxContext* context, const ffxAllocationCallbacks* memCb)
+{
+ VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+
+ Allocator alloc{memCb};
+ return GetAssociatedProvider(context)->DestroyContext(context, alloc);
+}
+
+FFX_API_ENTRY ffxReturnCode_t ffxConfigure(ffxContext* context, const ffxConfigureDescHeader* desc)
+{
+ VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+
+ return GetAssociatedProvider(context)->Configure(context, desc);
+}
+
+FFX_API_ENTRY ffxReturnCode_t ffxQuery(ffxContext* context, ffxQueryDescHeader* header)
+{
+ VERIFY(header != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+
+ if (context == nullptr)
+ {
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ // if output count is zero or no other pointer passed, count providers only
+ if (desc->outputCount && (*desc->outputCount == 0 || (!desc->versionIds && !desc->versionNames)))
+ {
+ *desc->outputCount = GetProviderCount(desc->createDescType, desc->device);
+ }
+ else if (desc->outputCount && *desc->outputCount > 0)
+ {
+ uint64_t capacity = *desc->outputCount;
+ *desc->outputCount = GetProviderVersions(desc->createDescType, desc->device, capacity, desc->versionIds, desc->versionNames);
+ }
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto provider = GetffxProvider(header->type, GetVersionOverride(header), GetDevice(header)))
+ {
+ return provider->Query(nullptr, header);
+ }
+ else
+ {
+ return FFX_API_RETURN_NO_PROVIDER;
+ }
+ }
+
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ if (context != nullptr)
+ {
+ auto provider = GetAssociatedProvider(context);
+ if (provider)
+ {
+ desc->versionId = provider->GetId();
+ desc->versionName = provider->GetVersionName();
+ return FFX_API_RETURN_OK;
+ }
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_PARAMETER;
+ }
+
+ desc->versionId = 0u;
+ desc->versionName = nullptr;
+ return FFX_API_RETURN_NO_PROVIDER;
+ }
+
+ return GetAssociatedProvider(context)->Query(context, header);
+}
+
+FFX_API_ENTRY ffxReturnCode_t ffxDispatch(ffxContext* context, const ffxDispatchDescHeader* desc)
+{
+ VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER);
+
+ return GetAssociatedProvider(context)->Dispatch(context, desc);
+}
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider.cpp b/Kits/AMDTK/ffx-api/src/ffx_provider.cpp
new file mode 100644
index 00000000..d7c0e64b
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider.cpp
@@ -0,0 +1,251 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_provider.h"
+
+#include "ffx_provider_fsr2.h"
+#include "ffx_provider_fsr3upscale.h"
+#include "ffx_provider_framegeneration.h"
+#include "ffx_provider_external.h"
+
+#include
+#include
+
+#include
+
+#ifdef FFX_BACKEND_DX12
+#include "dx12/ffx_provider_framegenerationswapchain_dx12.h"
+#endif // FFX_BACKEND_DX12
+
+#ifdef FFX_BACKEND_VK
+#include "vk/ffx_provider_framegenerationswapchain_vk.h"
+#endif // FFX_BACKEND_VK
+
+static constexpr ffxProvider* providers[] = {
+ &ffxProvider_FSR3Upscale::Instance,
+ &ffxProvider_FSR2::Instance,
+ &ffxProvider_FrameGeneration::Instance,
+#ifdef FFX_BACKEND_DX12
+ &ffxProvider_FrameGenerationSwapChain_DX12::Instance,
+#endif // FFX_BACKEND_DX12
+#ifdef FFX_BACKEND_VK
+ &ffxProvider_FrameGenerationSwapChain_VK::Instance,
+#endif // FFX_BACKEND_VK
+};
+static constexpr size_t providerCount = _countof(providers);
+
+static std::array, 10> externalProviders = {};
+
+MIDL_INTERFACE("b58d6601-7401-4234-8180-6febfc0e484c")
+IAmdExtFfxApi : public IUnknown
+{
+public:
+ // Update FFX API provider
+ virtual HRESULT UpdateFfxApiProvider(void* pData, uint32_t dataSizeInBytes) = 0;
+};
+
+struct ExternalProviderData
+{
+ uint32_t structVersion = 0;
+ uint64_t descType;
+ ffxProviderInterface provider;
+};
+#define FFX_EXTERNAL_PROVIDER_STRUCT_VERSION 1u
+
+void GetExternalProviders(ID3D12Device* device, uint64_t descType)
+{
+ static IAmdExtFfxApi* apiExtension = nullptr;
+
+ if (nullptr != device)
+ {
+ static bool ranOnce = false;
+ if (!ranOnce)
+ {
+ ranOnce = true;
+ static HMODULE hModule = GetModuleHandleA("amdxc64.dll");
+
+ if (device && hModule && !apiExtension)
+ {
+ typedef HRESULT(__cdecl * PFNAmdExtD3DCreateInterface)(IUnknown * pOuter, REFIID riid, void** ppvObject);
+ PFNAmdExtD3DCreateInterface AmdExtD3DCreateInterface =
+ static_cast((VOID*)GetProcAddress(hModule, "AmdExtD3DCreateInterface"));
+ if (AmdExtD3DCreateInterface)
+ {
+ HRESULT hr = AmdExtD3DCreateInterface(device, IID_PPV_ARGS(&apiExtension));
+
+ if (hr != S_OK)
+ {
+ if (apiExtension)
+ apiExtension->Release();
+ apiExtension = nullptr;
+ }
+ }
+ }
+ }
+ }
+
+ if (apiExtension)
+ {
+ ExternalProviderData data;
+ data.structVersion = FFX_EXTERNAL_PROVIDER_STRUCT_VERSION;
+ data.descType = descType;
+ HRESULT hr = apiExtension->UpdateFfxApiProvider(&data, sizeof(data));
+ if (hr != S_OK)
+ return;
+
+ for (auto& slot : externalProviders)
+ {
+ if (slot.has_value() && slot->GetId() == data.provider.versionId)
+ {
+ // we already have this provider saved.
+ break;
+ }
+ if (!slot.has_value())
+ {
+ // first free slot. slots are filled start to end and never released.
+ // we do not have this provider yet, add it to the list.
+ slot = ffxProviderExternal{data.provider};
+ break;
+ }
+ }
+ }
+
+}
+
+const ffxProvider* GetffxProvider(ffxStructType_t descType, uint64_t overrideId, void* device)
+{
+ // check driver-side providers
+ GetExternalProviders(reinterpret_cast(device), descType);
+
+ // If we are overriding, do not make the best provider choice decision
+ if (overrideId)
+ {
+ for (const auto& provider : externalProviders)
+ {
+ if (provider.has_value())
+ {
+ if (provider->GetId() == overrideId && provider->CanProvide(descType))
+ return &*provider;
+ }
+ }
+
+ for (size_t i = 0; i < providerCount; ++i)
+ {
+ if (providers[i]->GetId() == overrideId && providers[i]->CanProvide(descType))
+ return providers[i];
+ }
+
+ }
+ else
+ {
+ const ffxProvider* bestExternalProvider = nullptr;
+ const ffxProvider* bestInternalProvider = nullptr;
+
+ for (const auto& provider : externalProviders)
+ {
+ if (provider.has_value())
+ {
+ if (provider->CanProvide(descType))
+ {
+ bestExternalProvider = &*provider;
+ break;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < providerCount; ++i)
+ {
+ if (providers[i]->CanProvide(descType))
+ {
+ bestInternalProvider = providers[i];
+ break;
+ }
+ }
+
+ if ((bestExternalProvider != nullptr) && (bestInternalProvider != nullptr))
+ {
+ // Do a version check, and take the newest version.
+ // Id()s have lowest 31b valid - bit32 is reserved for "driver override" indication
+ uint64_t extId = bestExternalProvider->GetId() & (0x7FFFFFFFu);
+ uint64_t intId = bestInternalProvider->GetId() & (0x7FFFFFFFu);
+
+ if (extId > intId)
+ {
+ return bestExternalProvider;
+ }
+ }
+
+ return bestInternalProvider;
+ }
+
+ return nullptr;
+}
+
+const ffxProvider* GetAssociatedProvider(ffxContext* context)
+{
+ const InternalContextHeader* hdr = (const InternalContextHeader*)(*context);
+ const ffxProvider* provider = hdr->provider;
+ return provider;
+}
+
+uint64_t GetProviderCount(ffxStructType_t descType, void* device)
+{
+ return GetProviderVersions(descType, device, UINT64_MAX, nullptr, nullptr);
+}
+
+uint64_t GetProviderVersions(ffxStructType_t descType, void* device, uint64_t capacity, uint64_t* versionIds, const char** versionNames)
+{
+ uint64_t count = 0;
+
+ // check driver-side providers
+ GetExternalProviders(reinterpret_cast(device), descType);
+
+ for (const auto& provider : externalProviders)
+ {
+ if (count >= capacity) break;
+ if (provider.has_value() && provider->CanProvide(descType))
+ {
+ auto index = count;
+ count++;
+ if (versionIds)
+ versionIds[index] = provider->GetId();
+ if (versionNames)
+ versionNames[index] = provider->GetVersionName();
+ }
+ }
+
+ for (size_t i = 0; i < providerCount; ++i)
+ {
+ if (count >= capacity) break;
+ if (providers[i]->CanProvide(descType))
+ {
+ auto index = count;
+ count++;
+ if (versionIds)
+ versionIds[index] = providers[i]->GetId();
+ if (versionNames)
+ versionNames[index] = providers[i]->GetVersionName();
+ }
+ }
+
+ return count;
+}
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider.h b/Kits/AMDTK/ffx-api/src/ffx_provider.h
new file mode 100644
index 00000000..d501887e
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider.h
@@ -0,0 +1,146 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include
+#include
+#include
+
+#define VERIFY(_cond, _retcode) \
+ if (!(_cond)) return _retcode
+
+#define TRY(_expr) \
+ if (ffxReturnCode_t _rc = (_expr); _rc != FFX_API_RETURN_OK) return _rc
+
+#define TRY2(_expr) \
+ if (FFX_OK != (_expr)) return FFX_API_RETURN_ERROR_RUNTIME_ERROR
+
+struct Allocator
+{
+ const ffxAllocationCallbacks* cb;
+
+ void* alloc(size_t sz)
+ {
+ if (cb)
+ return cb->alloc(cb->pUserData, static_cast(sz));
+ else
+ return malloc(sz);
+ }
+
+ void dealloc(void* ptr)
+ {
+ if (cb)
+ cb->dealloc(cb->pUserData, ptr);
+ else
+ free(ptr);
+ }
+
+ template
+ T* construct(Args&&... args)
+ {
+ void* addr = alloc(sizeof(T));
+ return ::new(addr) T(std::forward(args)...);
+ }
+};
+
+class ffxProvider
+{
+public:
+ virtual ~ffxProvider() = default;
+
+ virtual bool CanProvide(uint64_t) const
+ {
+ return false;
+ }
+
+ virtual uint64_t GetId() const = 0;
+
+ virtual const char* GetVersionName() const = 0;
+
+ virtual ffxReturnCode_t CreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, Allocator& alloc) const = 0;
+
+ virtual ffxReturnCode_t DestroyContext(ffxContext* context, Allocator& alloc) const = 0;
+
+ virtual ffxReturnCode_t Configure(ffxContext* context, const ffxConfigureDescHeader* desc) const = 0;
+
+ virtual ffxReturnCode_t Query(ffxContext* context, ffxQueryDescHeader* desc) const = 0;
+
+ virtual ffxReturnCode_t Dispatch(ffxContext* context, const ffxDispatchDescHeader* desc) const = 0;
+};
+
+const ffxProvider* GetffxProvider(ffxStructType_t descType, uint64_t overrideId, void* device);
+
+const ffxProvider* GetAssociatedProvider(ffxContext* context);
+
+uint64_t GetProviderCount(ffxStructType_t descType, void* device);
+
+uint64_t GetProviderVersions(ffxStructType_t descType, void* device, uint64_t capacity, uint64_t* versionIds, const char** versionNames);
+
+struct InternalContextHeader
+{
+ const ffxProvider* provider;
+};
+
+template
+static inline T ConvertEnum(uint32_t enumVal)
+{
+ return static_cast(enumVal);
+}
+
+template
+static inline uint32_t ReverseConvertEnum(T enumVal)
+{
+ return static_cast(enumVal);
+}
+
+static inline FfxResource Convert(const FfxApiResource& inRes)
+{
+ FfxResource outRes{};
+ memset(outRes.name, 0, sizeof(outRes.name));
+ outRes.resource = inRes.resource;
+ outRes.state = ConvertEnum(inRes.state);
+ outRes.description.type = ConvertEnum(inRes.description.type);
+ outRes.description.format = ConvertEnum(inRes.description.format);
+ outRes.description.width = inRes.description.width;
+ outRes.description.height = inRes.description.height;
+ outRes.description.depth = inRes.description.depth;
+ outRes.description.mipCount = inRes.description.mipCount;
+ outRes.description.flags = ConvertEnum(inRes.description.flags);
+ outRes.description.usage = ConvertEnum(inRes.description.usage);
+ return outRes;
+}
+
+static inline FfxApiResource Convert(const FfxResource& inRes)
+{
+ FfxApiResource outRes{};
+ outRes.resource = inRes.resource;
+ outRes.state = ReverseConvertEnum(inRes.state);
+ outRes.description.type = ReverseConvertEnum(inRes.description.type);
+ outRes.description.format = ReverseConvertEnum(inRes.description.format);
+ outRes.description.width = inRes.description.width;
+ outRes.description.height = inRes.description.height;
+ outRes.description.depth = inRes.description.depth;
+ outRes.description.mipCount = inRes.description.mipCount;
+ outRes.description.flags = ReverseConvertEnum(inRes.description.flags);
+ outRes.description.usage = ReverseConvertEnum(inRes.description.usage);
+ return outRes;
+}
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider_external.h b/Kits/AMDTK/ffx-api/src/ffx_provider_external.h
new file mode 100644
index 00000000..edaadffe
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider_external.h
@@ -0,0 +1,95 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+
+#include
+#include "ffx_provider.h"
+
+typedef uint32_t (*pfnCanProvide)(uint64_t typeId);
+typedef uint32_t (*pfnCreateContext)(void* context, void* desc, const void* allocator);
+typedef uint32_t (*pfnDestroyContext)(void* context, const void* allocator);
+typedef uint32_t (*pfnConfigure)(void* context, const void* desc);
+typedef uint32_t (*pfnQuery)(void* context, void* desc);
+typedef uint32_t (*pfnDispatch)(void* context, const void* desc);
+
+struct ffxProviderInterface
+{
+ uint64_t versionId;
+ const char* versionName;
+ pfnCanProvide canProvide;
+ pfnCreateContext createContext;
+ pfnDestroyContext destroyContext;
+ pfnConfigure configure;
+ pfnQuery query;
+ pfnDispatch dispatch;
+};
+
+class ffxProviderExternal final : public ffxProvider {
+public:
+ ffxProviderInterface data;
+
+ ffxProviderExternal(ffxProviderInterface data) : data(data) {}
+
+ bool CanProvide(uint64_t type) const override
+ {
+ return data.canProvide(type) != 0;
+ }
+
+ uint64_t GetId() const override
+ {
+ return data.versionId;
+ }
+
+ const char* GetVersionName() const override
+ {
+ return data.versionName;
+ }
+
+ ffxReturnCode_t CreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, Allocator& alloc) const override
+ {
+ TRY(data.createContext(context, desc, alloc.cb));
+ // Ensure the provider is set to this external wrapper class.
+ reinterpret_cast(*context)->provider = this;
+ return FFX_API_RETURN_OK;
+ }
+
+ ffxReturnCode_t DestroyContext(ffxContext* context, Allocator& alloc) const override
+ {
+ return data.destroyContext(context, alloc.cb);
+ }
+
+ ffxReturnCode_t Configure(ffxContext* context, const ffxConfigureDescHeader* desc) const override
+ {
+ return data.configure(context, desc);
+ }
+
+ ffxReturnCode_t Query(ffxContext* context, ffxQueryDescHeader* desc) const override
+ {
+ return data.query(context, desc);
+ }
+
+ ffxReturnCode_t Dispatch(ffxContext* context, const ffxDispatchDescHeader* desc) const override
+ {
+ return data.dispatch(context, desc);
+ }
+};
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider_framegeneration.cpp b/Kits/AMDTK/ffx-api/src/ffx_provider_framegeneration.cpp
new file mode 100644
index 00000000..5b6e9d7a
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider_framegeneration.cpp
@@ -0,0 +1,573 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_provider_framegeneration.h"
+#include "backends.h"
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+bool ffxProvider_FrameGeneration::CanProvide(uint64_t type) const
+{
+ return (type & FFX_API_EFFECT_MASK) == FFX_API_EFFECT_ID_FRAMEGENERATION;
+}
+
+const uint32_t MAX_QUEUED_FRAMES = 2;
+
+struct InternalFgContext
+{
+ InternalContextHeader header;
+
+ FfxInterface backendInterfaceFi;
+ FfxInterface backendInterfaceShared;
+ FfxOpticalflowContext ofContext;
+ FfxFrameInterpolationContext fiContext;
+ FfxResourceInternal sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_COUNT];
+ uint32_t sharedResoureFrameToggle;
+ uint32_t effectContextIdShared;
+ float deltaTime;
+ bool asyncWorkloadSupported;
+
+ FfxResource HUDLessColor;
+ FfxResource distortionField;
+
+ bool frameGenEnabled;
+ uint32_t frameGenFlags;
+ ffxDispatchDescFrameGenerationPrepare prepareDescriptions[MAX_QUEUED_FRAMES];
+
+ struct Callbacks {
+ FfxApiPresentCallbackFunc presentCallback;
+ void* presentCallbackUserContext;
+ FfxApiFrameGenerationDispatchFunc frameGenerationCallback;
+ void* frameGenerationCallbackUserContext;
+ } callbacks[MAX_QUEUED_FRAMES];
+
+ uint64_t lastConfigureFrameID;
+ ffxApiMessage fpMessage;
+ uint32_t debugLevel;
+};
+
+#define STRINGIFY_(X) #X
+#define STRINGIFY(X) STRINGIFY_(X)
+#define MAKE_VERSION_STRING(major, minor, patch) STRINGIFY major "." STRINGIFY minor "." STRINGIFY patch
+
+uint64_t ffxProvider_FrameGeneration::GetId() const
+{
+ // FG, version from header
+ return 0xF600'0000ui64 << 32u | (FFX_SDK_MAKE_VERSION(FFX_FRAMEINTERPOLATION_VERSION_MAJOR, FFX_FRAMEINTERPOLATION_VERSION_MINOR, FFX_FRAMEINTERPOLATION_VERSION_PATCH) & 0xFFFF'FFFF);
+}
+
+const char* ffxProvider_FrameGeneration::GetVersionName() const
+{
+ return MAKE_VERSION_STRING(FFX_FRAMEINTERPOLATION_VERSION_MAJOR, FFX_FRAMEINTERPOLATION_VERSION_MINOR, FFX_FRAMEINTERPOLATION_VERSION_PATCH);
+}
+
+ffxReturnCode_t ffxProvider_FrameGeneration::CreateContext(ffxContext* context, ffxCreateContextDescHeader* header, Allocator& alloc) const
+{
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ InternalFgContext* internal_context = alloc.construct();
+ VERIFY(internal_context, FFX_API_RETURN_ERROR_MEMORY);
+ internal_context->header.provider = this;
+
+ TRY(MustCreateBackend(header, &internal_context->backendInterfaceShared, 1, alloc));
+ TRY(MustCreateBackend(header, &internal_context->backendInterfaceFi, 2, alloc));
+
+ { // copied from ffxFsr3ContextCreate, simplified.
+ internal_context->asyncWorkloadSupported = (desc->flags & FFX_FRAMEGENERATION_ENABLE_ASYNC_WORKLOAD_SUPPORT) != 0;
+
+ TRY2(internal_context->backendInterfaceShared.fpCreateBackendContext(&internal_context->backendInterfaceShared, FFX_EFFECT_SHAREDAPIBACKEND, nullptr, &internal_context->effectContextIdShared));
+
+ FfxOpticalflowContextDescription ofDescription = {};
+ ofDescription.backendInterface = internal_context->backendInterfaceFi;
+ ofDescription.resolution.width = desc->displaySize.width;
+ ofDescription.resolution.height = desc->displaySize.height;
+
+ // set up Opticalflow
+ TRY2(ffxOpticalflowContextCreate(&internal_context->ofContext, &ofDescription));
+
+ FfxFrameInterpolationContextDescription fiDescription = {0};
+ fiDescription.backendInterface = internal_context->backendInterfaceFi;
+ fiDescription.flags |= (desc->flags & FFX_FRAMEGENERATION_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS) ? FFX_FRAMEINTERPOLATION_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS : 0;
+ fiDescription.flags |= (desc->flags & FFX_FRAMEGENERATION_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION) ? FFX_FRAMEINTERPOLATION_ENABLE_JITTER_MOTION_VECTORS : 0;
+ fiDescription.flags |= (desc->flags & FFX_FRAMEGENERATION_ENABLE_DEPTH_INVERTED) ? FFX_FRAMEINTERPOLATION_ENABLE_DEPTH_INVERTED : 0;
+ fiDescription.flags |= (desc->flags & FFX_FRAMEGENERATION_ENABLE_DEPTH_INFINITE) ? FFX_FRAMEINTERPOLATION_ENABLE_DEPTH_INFINITE : 0;
+ fiDescription.flags |= (desc->flags & FFX_FRAMEGENERATION_ENABLE_HIGH_DYNAMIC_RANGE) ? FFX_FRAMEINTERPOLATION_ENABLE_HDR_COLOR_INPUT : 0;
+ fiDescription.flags |= (desc->flags & FFX_FRAMEGENERATION_ENABLE_ASYNC_WORKLOAD_SUPPORT) ? FFX_FRAMEINTERPOLATION_ENABLE_ASYNC_SUPPORT : 0;
+ fiDescription.flags |= (desc->flags & FFX_FRAMEGENERATION_ENABLE_DEBUG_CHECKING) ? FFX_FRAMEINTERPOLATION_ENABLE_DEBUG_CHECKING : 0;
+ fiDescription.maxRenderSize.width = desc->maxRenderSize.width;
+ fiDescription.maxRenderSize.height = desc->maxRenderSize.height;
+ fiDescription.displaySize.width = desc->displaySize.width;
+ fiDescription.displaySize.height = desc->displaySize.height;
+ fiDescription.backBufferFormat = ConvertEnum(desc->backBufferFormat);
+ fiDescription.previousInterpolationSourceFormat = ConvertEnum(desc->backBufferFormat);
+ for (auto it = header; it; it = it->pNext)
+ {
+ if (auto descHudless = ffx::DynamicCast(it))
+ {
+ fiDescription.previousInterpolationSourceFormat = ConvertEnum(descHudless->hudlessBackBufferFormat);
+ }
+ }
+ // set up Frameinterpolation
+ TRY2(ffxFrameInterpolationContextCreate(&internal_context->fiContext, &fiDescription));
+
+ // set up optical flow resources
+ FfxOpticalflowSharedResourceDescriptions ofResourceDescs = {};
+ TRY2(ffxOpticalflowGetSharedResourceDescriptions(&internal_context->ofContext, &ofResourceDescs));
+
+ TRY2(internal_context->backendInterfaceShared.fpCreateResource(&internal_context->backendInterfaceShared, &ofResourceDescs.opticalFlowVector, internal_context->effectContextIdShared, &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_VECTOR]));
+ TRY2(internal_context->backendInterfaceShared.fpCreateResource(&internal_context->backendInterfaceShared, &ofResourceDescs.opticalFlowSCD, internal_context->effectContextIdShared, &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_OUTPUT]));
+ }
+ {
+ FfxFrameInterpolationSharedResourceDescriptions fiResourceDescs = {};
+ TRY2(ffxFrameInterpolationGetSharedResourceDescriptions(&internal_context->fiContext, &fiResourceDescs));
+
+ internal_context->sharedResoureFrameToggle = 0;
+ wchar_t Name[256] = {};
+ for (FfxUInt32 i = 0; i < 2; i++)
+ {
+ FfxCreateResourceDescription dilD = fiResourceDescs.dilatedDepth;
+ swprintf(Name, 255, L"%s%d", fiResourceDescs.dilatedDepth.name, i);
+ dilD.name = Name;
+ TRY2(internal_context->backendInterfaceShared.fpCreateResource(
+ &internal_context->backendInterfaceShared,
+ &dilD,
+ internal_context->effectContextIdShared,
+ &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_DEPTH_0 + (i * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]));
+
+ FfxCreateResourceDescription dilMVs = fiResourceDescs.dilatedMotionVectors;
+ swprintf(Name, 255, L"%s%d", fiResourceDescs.dilatedMotionVectors.name, i);
+ dilMVs.name = Name;
+ TRY2(internal_context->backendInterfaceShared.fpCreateResource(
+ &internal_context->backendInterfaceShared,
+ &dilMVs,
+ internal_context->effectContextIdShared,
+ &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_0 + (i * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]));
+
+ FfxCreateResourceDescription recND = fiResourceDescs.reconstructedPrevNearestDepth;
+ swprintf(Name, 255, L"%s%d", fiResourceDescs.reconstructedPrevNearestDepth.name, i);
+ recND.name = Name;
+ TRY2(internal_context->backendInterfaceShared.fpCreateResource(
+ &internal_context->backendInterfaceShared,
+ &recND,
+ internal_context->effectContextIdShared,
+ &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_RECONSTRUCTED_PREVIOUS_NEAREST_DEPTH_0 + (i * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]));
+ }
+ }
+
+ *context = internal_context;
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGeneration::DestroyContext(ffxContext* context, Allocator& alloc) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgContext* internal_context = reinterpret_cast(*context);
+
+ { // copied from ffxFsr3ContextDestroy, simplified.
+ for (FfxUInt32 i = 0; i < FFX_FSR3_RESOURCE_IDENTIFIER_COUNT; i++)
+ {
+ TRY2(internal_context->backendInterfaceShared.fpDestroyResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[i], internal_context->effectContextIdShared));
+ }
+
+ TRY2(ffxFrameInterpolationContextDestroy(&internal_context->fiContext));
+
+ TRY2(ffxOpticalflowContextDestroy(&internal_context->ofContext));
+
+ TRY2(internal_context->backendInterfaceShared.fpDestroyBackendContext(&internal_context->backendInterfaceShared, internal_context->effectContextIdShared));
+ }
+
+ alloc.dealloc(internal_context->backendInterfaceFi.scratchBuffer);
+ alloc.dealloc(internal_context->backendInterfaceShared.scratchBuffer);
+ alloc.dealloc(internal_context);
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FrameGeneration::Configure(ffxContext* context, const ffxConfigureDescHeader* header) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ FfxFrameGenerationConfig config{};
+ config.allowAsyncWorkloads = desc->allowAsyncWorkloads;
+ config.flags = desc->flags;
+
+ size_t callbacksIndex = desc->frameID % MAX_QUEUED_FRAMES;
+
+ bool const bPresentCallbackChanged = (internal_context->callbacks[callbacksIndex].presentCallback != desc->presentCallback) || (desc->presentCallback && (internal_context->callbacks[callbacksIndex].presentCallbackUserContext != desc->presentCallbackUserContext));
+ bool const bFrameGenerationCallback = (internal_context->callbacks[callbacksIndex].frameGenerationCallback != desc->frameGenerationCallback) || (desc->frameGenerationCallback && (internal_context->callbacks[callbacksIndex].frameGenerationCallbackUserContext != desc->frameGenerationCallbackUserContext));
+ internal_context->callbacks[callbacksIndex].presentCallback = desc->presentCallback;
+ internal_context->callbacks[callbacksIndex].frameGenerationCallback = desc->frameGenerationCallback;
+ internal_context->callbacks[callbacksIndex].presentCallbackUserContext = desc->presentCallbackUserContext;
+ internal_context->callbacks[callbacksIndex].frameGenerationCallbackUserContext = desc->frameGenerationCallbackUserContext;
+
+ config.frameGenerationCallback = nullptr;
+ config.frameGenerationCallbackContext = nullptr;
+ if (desc->frameGenerationCallback != nullptr)
+ {
+ config.frameGenerationCallback = [](const FfxFrameGenerationDispatchDescription* desc, void* ctx) -> FfxErrorCode {
+ size_t callbacksIndex = desc->frameID % MAX_QUEUED_FRAMES;
+ InternalFgContext* internal_context = reinterpret_cast(ctx);
+ auto callbacks = &internal_context->callbacks[callbacksIndex];
+ VERIFY(callbacks->frameGenerationCallback, FFX_ERROR_BACKEND_API_ERROR);
+
+ ffx::DispatchDescFrameGeneration dispatchDesc{};
+
+ dispatchDesc.backbufferTransferFunction = desc->backBufferTransferFunction;
+ dispatchDesc.commandList = desc->commandList;
+ dispatchDesc.minMaxLuminance[0] = desc->minMaxLuminance[0];
+ dispatchDesc.minMaxLuminance[1] = desc->minMaxLuminance[1];
+ dispatchDesc.numGeneratedFrames = desc->numInterpolatedFrames;
+ dispatchDesc.outputs[0] = Convert(desc->outputs[0]);
+ dispatchDesc.outputs[1] = Convert(desc->outputs[1]);
+ dispatchDesc.outputs[2] = Convert(desc->outputs[2]);
+ dispatchDesc.outputs[3] = Convert(desc->outputs[3]);
+ dispatchDesc.presentColor = Convert(desc->presentColor);
+ dispatchDesc.reset = desc->reset;
+ dispatchDesc.generationRect.top = desc->interpolationRect.top;
+ dispatchDesc.generationRect.left = desc->interpolationRect.left;
+ dispatchDesc.generationRect.height = desc->interpolationRect.height;
+ dispatchDesc.generationRect.width = desc->interpolationRect.width;
+ dispatchDesc.frameID = desc->frameID;
+
+ if (FFX_API_RETURN_OK != callbacks->frameGenerationCallback(&dispatchDesc, callbacks->frameGenerationCallbackUserContext))
+ return FFX_ERROR_BACKEND_API_ERROR;
+ return FFX_OK;
+ };
+ config.frameGenerationCallbackContext = internal_context;
+ }
+
+ config.presentCallback = nullptr;
+ config.presentCallbackContext = nullptr;
+ if (desc->presentCallback != nullptr)
+ {
+ config.presentCallback = [](const FfxPresentCallbackDescription* params, void* ctx) -> FfxErrorCode {
+ size_t callbacksIndex = params->frameID % MAX_QUEUED_FRAMES;
+ InternalFgContext* internal_context = reinterpret_cast(ctx);
+ auto callbacks = &internal_context->callbacks[callbacksIndex];
+ VERIFY(callbacks->presentCallback, FFX_ERROR_BACKEND_API_ERROR);
+
+ ffxCallbackDescFrameGenerationPresent cbDesc{};
+ cbDesc.header.pNext = nullptr;
+ cbDesc.header.type = FFX_API_CALLBACK_DESC_TYPE_FRAMEGENERATION_PRESENT;
+
+ cbDesc.commandList = params->commandList;
+ cbDesc.currentBackBuffer = Convert(params->currentBackBuffer);
+ cbDesc.currentUI = Convert(params->currentUI);
+ cbDesc.device = params->device;
+ cbDesc.isGeneratedFrame = params->isInterpolatedFrame;
+ cbDesc.outputSwapChainBuffer = Convert(params->outputSwapChainBuffer);
+ cbDesc.frameID = params->frameID;
+
+ if (FFX_API_RETURN_OK != callbacks->presentCallback(&cbDesc, callbacks->presentCallbackUserContext))
+ return FFX_ERROR_BACKEND_API_ERROR;
+ return FFX_OK;
+ };
+ config.presentCallbackContext = internal_context;
+ }
+
+ config.drawDebugPacingLines = false;
+ if (desc->flags & FFX_FRAMEGENERATION_FLAG_DRAW_DEBUG_PACING_LINES)
+ {
+ config.drawDebugPacingLines = true;
+ }
+
+ config.frameGenerationEnabled = desc->frameGenerationEnabled;
+ config.HUDLessColor = Convert(desc->HUDLessColor);
+ config.onlyPresentInterpolated = desc->onlyPresentGenerated;
+ config.swapChain = desc->swapChain;
+
+ config.interpolationRect.top = desc->generationRect.top;
+ config.interpolationRect.left = desc->generationRect.left;
+ config.interpolationRect.width = desc->generationRect.width;
+ config.interpolationRect.height = desc->generationRect.height;
+
+ config.frameID = desc->frameID;
+
+ { // copied from ffxFsr3ConfigureFrameGeneration
+ internal_context->frameGenFlags = config.flags;
+ internal_context->HUDLessColor = config.HUDLessColor;
+
+ if (config.flags & FFX_FRAMEGENERATION_FLAG_DRAW_DEBUG_VIEW)
+ {
+ config.onlyPresentInterpolated = true;
+ }
+
+ internal_context->frameGenEnabled = config.frameGenerationEnabled;
+
+ if (!(config.flags & FFX_FRAMEGENERATION_FLAG_NO_SWAPCHAIN_CONTEXT_NOTIFY))
+ {
+ // When the frame ID is not incrementing by 1 we could end up overwriting a pointer that is in-use, so reset the swap-chain state
+ if (((internal_context->lastConfigureFrameID + 1) != desc->frameID) && (bPresentCallbackChanged || bFrameGenerationCallback))
+ {
+ FfxFrameGenerationConfig resetConfig = config;
+ resetConfig.frameGenerationCallback = nullptr;
+ resetConfig.frameGenerationCallbackContext = nullptr;
+ resetConfig.presentCallback = nullptr;
+ resetConfig.presentCallbackContext = nullptr;
+
+ TRY2(internal_context->backendInterfaceShared.fpSwapChainConfigureFrameGeneration(&resetConfig));
+ }
+
+ TRY2(internal_context->backendInterfaceShared.fpSwapChainConfigureFrameGeneration(&config));
+
+ internal_context->lastConfigureFrameID = desc->frameID;
+ }
+ }
+
+ internal_context->distortionField = FfxResource({});
+ for (auto it = header; it; it = it->pNext)
+ {
+ if (auto distortionFieldDesc = ffx::DynamicCast(it))
+ {
+ if (distortionFieldDesc->distortionField.resource)
+ {
+ internal_context->distortionField = Convert(distortionFieldDesc->distortionField);
+ }
+ }
+ }
+
+ return FFX_API_RETURN_OK;
+ }
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ TRY2(ffxFrameInterpolationSetGlobalDebugMessage( reinterpret_cast(desc->fpMessage),
+ desc->debugLevel));
+
+ // Grab this fp for use in extensions later
+ internal_context->fpMessage = desc->fpMessage;
+ internal_context->debugLevel = desc->debugLevel;
+
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_PARAMETER;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGeneration::Query(ffxContext* context, ffxQueryDescHeader* header) const
+{
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ FfxEffectMemoryUsage pGpuMemoryUsageFrameGeneration;
+ FfxEffectMemoryUsage pGpuMemoryUsageOpticalFlow;
+ FfxEffectMemoryUsage pGpuMemoryUsageShared;
+
+ TRY2(ffxFrameInterpolationContextGetGpuMemoryUsage(&internal_context->fiContext, &pGpuMemoryUsageFrameGeneration));
+ TRY2(ffxOpticalflowContextGetGpuMemoryUsage(&internal_context->ofContext, &pGpuMemoryUsageOpticalFlow));
+ TRY2(ffxSharedContextGetGpuMemoryUsage(&internal_context->backendInterfaceShared, &pGpuMemoryUsageShared));
+ desc->gpuMemoryUsageFrameGeneration->totalUsageInBytes = pGpuMemoryUsageFrameGeneration.totalUsageInBytes + pGpuMemoryUsageOpticalFlow.totalUsageInBytes + pGpuMemoryUsageShared.totalUsageInBytes;
+ desc->gpuMemoryUsageFrameGeneration->aliasableUsageInBytes = pGpuMemoryUsageFrameGeneration.aliasableUsageInBytes + pGpuMemoryUsageOpticalFlow.aliasableUsageInBytes + pGpuMemoryUsageShared.aliasableUsageInBytes;
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGeneration::Dispatch(ffxContext* context, const ffxDispatchDescHeader* header) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ const ffxDispatchDescFrameGenerationPrepare* prepDesc = &internal_context->prepareDescriptions[desc->frameID % MAX_QUEUED_FRAMES];
+
+ // Optical flow
+ {
+ FfxOpticalflowDispatchDescription ofDispatchDesc{};
+ ofDispatchDesc.commandList = desc->commandList;
+ ofDispatchDesc.color = Convert(desc->presentColor);
+ if (internal_context->HUDLessColor.resource)
+ {
+ ofDispatchDesc.color = internal_context->HUDLessColor;
+ }
+ ofDispatchDesc.reset = desc->reset;
+ ofDispatchDesc.backbufferTransferFunction = desc->backbufferTransferFunction;
+ ofDispatchDesc.minMaxLuminance.x = desc->minMaxLuminance[0];
+ ofDispatchDesc.minMaxLuminance.y = desc->minMaxLuminance[1];
+ ofDispatchDesc.opticalFlowVector = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_VECTOR]);
+ ofDispatchDesc.opticalFlowSCD = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_OUTPUT]);
+
+ TRY2(ffxOpticalflowContextDispatch(&internal_context->ofContext, &ofDispatchDesc));
+ }
+
+ // Frame interpolation
+ {
+ FfxFrameInterpolationDispatchDescription fiDispatchDesc{0};
+
+ // don't dispatch interpolation async for now: use the same commandlist for copy and interpolate
+ fiDispatchDesc.commandList = desc->commandList;
+ fiDispatchDesc.displaySize.width = desc->presentColor.description.width;
+ fiDispatchDesc.displaySize.height = desc->presentColor.description.height;
+ fiDispatchDesc.currentBackBuffer = Convert(desc->presentColor);
+ fiDispatchDesc.currentBackBuffer_HUDLess = internal_context->HUDLessColor;
+ fiDispatchDesc.reset = desc->reset;
+
+ fiDispatchDesc.renderSize.width = prepDesc->renderSize.width;
+ fiDispatchDesc.renderSize.height = prepDesc->renderSize.height;
+ fiDispatchDesc.output = Convert(desc->outputs[0]);
+ fiDispatchDesc.opticalFlowVector = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_VECTOR]);
+ fiDispatchDesc.opticalFlowSceneChangeDetection = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_OUTPUT]);
+ fiDispatchDesc.opticalFlowBlockSize = 8;
+ fiDispatchDesc.opticalFlowScale = { 1.f / fiDispatchDesc.displaySize.width, 1.f / fiDispatchDesc.displaySize.height };
+ fiDispatchDesc.frameTimeDelta = prepDesc->frameTimeDelta;
+ fiDispatchDesc.cameraNear = prepDesc->cameraNear;
+ fiDispatchDesc.cameraFar = prepDesc->cameraFar;
+ fiDispatchDesc.viewSpaceToMetersFactor = prepDesc->viewSpaceToMetersFactor;
+ fiDispatchDesc.cameraFovAngleVertical = prepDesc->cameraFovAngleVertical;
+
+ fiDispatchDesc.dilatedDepth = internal_context->backendInterfaceShared.fpGetResource( &internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_DEPTH_0 + (internal_context->sharedResoureFrameToggle * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]);
+ fiDispatchDesc.dilatedMotionVectors = internal_context->backendInterfaceShared.fpGetResource( &internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_0 + (internal_context->sharedResoureFrameToggle * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]);
+ fiDispatchDesc.reconstructedPrevDepth = internal_context->backendInterfaceShared.fpGetResource( &internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_RECONSTRUCTED_PREVIOUS_NEAREST_DEPTH_0 + (internal_context->sharedResoureFrameToggle * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]);
+
+ if (desc->generationRect.height == 0 && desc->generationRect.width == 0)
+ {
+ fiDispatchDesc.interpolationRect.left = 0;
+ fiDispatchDesc.interpolationRect.top = 0;
+ fiDispatchDesc.interpolationRect.width = desc->presentColor.description.width;
+ fiDispatchDesc.interpolationRect.height = desc->presentColor.description.height;
+ }
+ else
+ {
+ fiDispatchDesc.interpolationRect.top = desc->generationRect.top;
+ fiDispatchDesc.interpolationRect.left = desc->generationRect.left;
+ fiDispatchDesc.interpolationRect.width = desc->generationRect.width;
+ fiDispatchDesc.interpolationRect.height = desc->generationRect.height;
+ }
+
+ if (internal_context->frameGenFlags & FFX_FRAMEGENERATION_FLAG_DRAW_DEBUG_TEAR_LINES)
+ {
+ fiDispatchDesc.flags |= FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_TEAR_LINES;
+ }
+
+
+ if (internal_context->frameGenFlags & FFX_FRAMEGENERATION_FLAG_DRAW_DEBUG_RESET_INDICATORS)
+ {
+ fiDispatchDesc.flags |= FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_RESET_INDICATORS;
+ }
+
+ if (internal_context->frameGenFlags & FFX_FRAMEGENERATION_FLAG_DRAW_DEBUG_VIEW)
+ {
+ fiDispatchDesc.flags |= FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_VIEW;
+ }
+
+ if (internal_context->frameGenFlags & FFX_FRAMEGENERATION_FLAG_RESERVED_1)
+ {
+ fiDispatchDesc.flags |= FFX_FRAMEINTERPOLATION_DISPATCH_RESERVED_1;
+ }
+
+ if (internal_context->frameGenFlags & FFX_FRAMEGENERATION_FLAG_RESERVED_2)
+ {
+ fiDispatchDesc.flags |= FFX_FRAMEINTERPOLATION_DISPATCH_RESERVED_2;
+ }
+
+ fiDispatchDesc.backBufferTransferFunction = ConvertEnum(desc->backbufferTransferFunction);
+ fiDispatchDesc.minMaxLuminance[0] = desc->minMaxLuminance[0];
+ fiDispatchDesc.minMaxLuminance[1] = desc->minMaxLuminance[1];
+
+ fiDispatchDesc.frameID = desc->frameID;
+
+ if (internal_context->distortionField.resource)
+ {
+ fiDispatchDesc.distortionField = internal_context->distortionField;
+ }
+ TRY2(ffxFrameInterpolationDispatch(&internal_context->fiContext, &fiDispatchDesc));
+ }
+
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ internal_context->prepareDescriptions[desc->frameID % MAX_QUEUED_FRAMES] = *desc;
+
+ internal_context->sharedResoureFrameToggle = (internal_context->sharedResoureFrameToggle + 1) & 1;
+
+ FfxFrameInterpolationPrepareDescription dispatchDesc{0};
+ dispatchDesc.flags = desc->flags; // TODO: flag conversion?
+ dispatchDesc.commandList = desc->commandList;
+ dispatchDesc.renderSize.width = desc->renderSize.width;
+ dispatchDesc.renderSize.height = desc->renderSize.height;
+ dispatchDesc.jitterOffset.x = desc->jitterOffset.x;
+ dispatchDesc.jitterOffset.y = desc->jitterOffset.y;
+ dispatchDesc.motionVectorScale.x = desc->motionVectorScale.x;
+ dispatchDesc.motionVectorScale.y = desc->motionVectorScale.y;
+ dispatchDesc.frameTimeDelta = desc->frameTimeDelta;
+ dispatchDesc.cameraNear = desc->cameraNear;
+ dispatchDesc.cameraFar = desc->cameraFar;
+ dispatchDesc.viewSpaceToMetersFactor = desc->viewSpaceToMetersFactor;
+ dispatchDesc.cameraFovAngleVertical = desc->cameraFovAngleVertical;
+ dispatchDesc.depth = Convert(desc->depth);
+ dispatchDesc.motionVectors = Convert(desc->motionVectors);
+ dispatchDesc.frameID = desc->frameID;
+
+ dispatchDesc.dilatedDepth = internal_context->backendInterfaceShared.fpGetResource( &internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_DEPTH_0 + (internal_context->sharedResoureFrameToggle * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]);
+ dispatchDesc.dilatedMotionVectors = internal_context->backendInterfaceShared.fpGetResource( &internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_0 + (internal_context->sharedResoureFrameToggle * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]);
+ dispatchDesc.reconstructedPrevDepth = internal_context->backendInterfaceShared.fpGetResource( &internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_RECONSTRUCTED_PREVIOUS_NEAREST_DEPTH_0 + (internal_context->sharedResoureFrameToggle * FFX_FSR3_RESOURCE_IDENTIFIER_UPSCALED_COUNT)]);
+
+ for (auto it = header; it; it = it->pNext)
+ {
+ if (auto cameraInfoDesc = ffx::DynamicCast(it))
+ {
+ memcpy(dispatchDesc.cameraPosition, &cameraInfoDesc->cameraPosition, sizeof(FfxFloat32x3));
+ memcpy(dispatchDesc.cameraUp, &cameraInfoDesc->cameraUp, sizeof(FfxFloat32x3));
+ memcpy(dispatchDesc.cameraRight, &cameraInfoDesc->cameraRight, sizeof(FfxFloat32x3));
+ memcpy(dispatchDesc.cameraForward, &cameraInfoDesc->cameraForward, sizeof(FfxFloat32x3));
+ }
+ }
+
+ TRY2(ffxFrameInterpolationPrepare(&internal_context->fiContext, &dispatchDesc));
+
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_PARAMETER;
+ }
+}
+
+ffxProvider_FrameGeneration ffxProvider_FrameGeneration::Instance;
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider_framegeneration.h b/Kits/AMDTK/ffx-api/src/ffx_provider_framegeneration.h
new file mode 100644
index 00000000..c02514f9
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider_framegeneration.h
@@ -0,0 +1,49 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include "ffx_provider.h"
+
+class ffxProvider_FrameGeneration: public ffxProvider
+{
+public:
+ ffxProvider_FrameGeneration() = default;
+ virtual ~ffxProvider_FrameGeneration() = default;
+
+ virtual bool CanProvide(uint64_t type) const override;
+
+ virtual uint64_t GetId() const override;
+
+ virtual const char* GetVersionName() const override;
+
+ virtual ffxReturnCode_t CreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t DestroyContext(ffxContext* context, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t Configure(ffxContext* context, const ffxConfigureDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Query(ffxContext* context, ffxQueryDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Dispatch(ffxContext* context, const ffxDispatchDescHeader* desc) const override;
+
+ static ffxProvider_FrameGeneration Instance;
+};
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider_fsr2.cpp b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr2.cpp
new file mode 100644
index 00000000..1c9e5514
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr2.cpp
@@ -0,0 +1,317 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_provider_fsr2.h"
+#include "backends.h"
+#include
+#include
+
+#include
+
+static FfxFsr2QualityMode ConvertQuality(uint32_t apiMode)
+{
+ switch (apiMode)
+ {
+ case FFX_UPSCALE_QUALITY_MODE_QUALITY:
+ return FFX_FSR2_QUALITY_MODE_QUALITY;
+ case FFX_UPSCALE_QUALITY_MODE_BALANCED:
+ return FFX_FSR2_QUALITY_MODE_BALANCED;
+ case FFX_UPSCALE_QUALITY_MODE_PERFORMANCE:
+ return FFX_FSR2_QUALITY_MODE_PERFORMANCE;
+ case FFX_UPSCALE_QUALITY_MODE_ULTRA_PERFORMANCE:
+ return FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE;
+ default:
+ // convert representation through int.
+ return (FfxFsr2QualityMode)(int)apiMode;
+ }
+}
+
+static uint32_t ConvertFlags(uint32_t apiFlags)
+{
+ uint32_t outFlags = 0;
+ if (apiFlags & FFX_UPSCALE_ENABLE_HIGH_DYNAMIC_RANGE)
+ outFlags |= FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS)
+ outFlags |= FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS;
+ if (apiFlags & FFX_UPSCALE_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION)
+ outFlags |= FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DEPTH_INVERTED)
+ outFlags |= FFX_FSR2_ENABLE_DEPTH_INVERTED;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DEPTH_INFINITE)
+ outFlags |= FFX_FSR2_ENABLE_DEPTH_INFINITE;
+ if (apiFlags & FFX_UPSCALE_ENABLE_AUTO_EXPOSURE)
+ outFlags |= FFX_FSR2_ENABLE_AUTO_EXPOSURE;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DYNAMIC_RESOLUTION)
+ outFlags |= FFX_FSR2_ENABLE_DYNAMIC_RESOLUTION;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DEBUG_CHECKING)
+ outFlags |= FFX_FSR2_ENABLE_DEBUG_CHECKING;
+ return outFlags;
+}
+
+bool ffxProvider_FSR2::CanProvide(uint64_t type) const
+{
+ return (type & FFX_API_EFFECT_MASK) == FFX_API_EFFECT_ID_UPSCALE;
+}
+
+#define STRINGIFY_(X) #X
+#define STRINGIFY(X) STRINGIFY_(X)
+#define MAKE_VERSION_STRING(major, minor, patch) STRINGIFY major "." STRINGIFY minor "." STRINGIFY patch
+
+uint64_t ffxProvider_FSR2::GetId() const
+{
+ // FSR Scale, version from header
+ return 0xF5A5'CA1Eui64 << 32 | (FFX_SDK_MAKE_VERSION(FFX_FSR2_VERSION_MAJOR, FFX_FSR2_VERSION_MINOR, FFX_FSR2_VERSION_PATCH) & 0xFFFF'FFFF);
+}
+
+const char* ffxProvider_FSR2::GetVersionName() const
+{
+ return MAKE_VERSION_STRING(FFX_FSR2_VERSION_MAJOR, FFX_FSR2_VERSION_MINOR, FFX_FSR2_VERSION_PATCH);
+}
+
+struct InternalFsr2Context
+{
+ InternalContextHeader header;
+ FfxInterface backendInterface;
+ FfxFsr2Context context;
+ ffxApiMessage fpMessage;
+ uint32_t debugLevel;
+};
+
+ffxReturnCode_t ffxProvider_FSR2::CreateContext(ffxContext* context, ffxCreateContextDescHeader* header, Allocator& alloc) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ InternalFsr2Context* internal_context = alloc.construct();
+ VERIFY(internal_context, FFX_API_RETURN_ERROR_MEMORY);
+ internal_context->header.provider = this;
+
+ TRY(MustCreateBackend(header, &internal_context->backendInterface, FFX_FSR2_CONTEXT_COUNT, alloc));
+
+ FfxFsr2ContextDescription initializationParameters = {0};
+ initializationParameters.backendInterface = internal_context->backendInterface;
+ initializationParameters.maxRenderSize.width = desc->maxRenderSize.width;
+ initializationParameters.maxRenderSize.height = desc->maxRenderSize.height;
+ initializationParameters.displaySize.width = desc->maxUpscaleSize.width;
+ initializationParameters.displaySize.height = desc->maxUpscaleSize.height;
+ initializationParameters.flags = ConvertFlags(desc->flags);
+ // Calling this casted function is undefined behaviour, but it's probably safe.
+ initializationParameters.fpMessage = reinterpret_cast(desc->fpMessage);
+
+ // Grab this fp for use in extensions later
+ internal_context->fpMessage = desc->fpMessage;
+
+ // Create the FSR2 context
+ TRY(ffxFsr2ContextCreate(&internal_context->context, &initializationParameters));
+
+ ffxFsr2SetGlobalDebugMessage(reinterpret_cast(desc->fpMessage), 0);
+
+ *context = internal_context;
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FSR2::DestroyContext(ffxContext* context, Allocator& alloc) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFsr2Context* internal_context = reinterpret_cast(*context);
+
+ TRY2(ffxFsr2ContextDestroy(&internal_context->context));
+
+ alloc.dealloc(internal_context->backendInterface.scratchBuffer);
+ alloc.dealloc(internal_context);
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FSR2::Configure(ffxContext* context, const ffxConfigureDescHeader* header) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+ InternalFsr2Context* internal_context = reinterpret_cast(*context);
+ switch (header->type)
+ {
+ case FFX_API_CONFIGURE_DESC_TYPE_GLOBALDEBUG1:
+ {
+ auto desc = reinterpret_cast(header);
+ TRY2(ffxFsr2SetGlobalDebugMessage( reinterpret_cast(desc->fpMessage), desc->debugLevel));
+ internal_context->fpMessage = desc->fpMessage;
+ internal_context->debugLevel = desc->debugLevel;
+ }
+ break;
+ }
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FSR2::Query(ffxContext* context, ffxQueryDescHeader* header) const
+{
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+
+ switch (header->type)
+ {
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTEROFFSET:
+ {
+ auto desc = reinterpret_cast(header);
+ float jitterX, jitterY;
+ TRY2(ffxFsr2GetJitterOffset(&jitterX, &jitterY, desc->index, desc->phaseCount));
+ if (desc->pOutX != nullptr)
+ {
+ *desc->pOutX = jitterX;
+ }
+ if (desc->pOutY != nullptr)
+ {
+ *desc->pOutY = jitterY;
+ }
+ break;
+ }
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTERPHASECOUNT:
+ {
+ auto desc = reinterpret_cast(header);
+ const int32_t jitterPhaseCount = ffxFsr2GetJitterPhaseCount(desc->renderWidth, desc->displayWidth);
+
+ if (desc->pOutPhaseCount != nullptr)
+ {
+ *desc->pOutPhaseCount = jitterPhaseCount;
+ }
+ break;
+ }
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETRENDERRESOLUTIONFROMQUALITYMODE:
+ {
+ auto desc = reinterpret_cast(header);
+ uint32_t renderWidth;
+ uint32_t renderHeight;
+
+ TRY2(ffxFsr2GetRenderResolutionFromQualityMode(&renderWidth, &renderHeight, desc->displayWidth, desc->displayHeight, ConvertQuality(desc->qualityMode)));
+ if (desc->pOutRenderWidth != nullptr)
+ {
+ *desc->pOutRenderWidth = renderWidth;
+ }
+ if (desc->pOutRenderHeight != nullptr)
+ {
+ *desc->pOutRenderHeight = renderHeight;
+ }
+ break;
+ }
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETUPSCALERATIOFROMQUALITYMODE:
+ {
+ auto desc = reinterpret_cast(header);
+ float ratio = ffxFsr2GetUpscaleRatioFromQualityMode(ConvertQuality(desc->qualityMode));
+
+ if (desc->pOutUpscaleRatio != nullptr)
+ {
+ *desc->pOutUpscaleRatio = ratio;
+ }
+ break;
+ }
+ default:
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FSR2::Dispatch(ffxContext* context, const ffxDispatchDescHeader* header) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFsr2Context* internal_context = (InternalFsr2Context*)context[0];
+
+ ffxDispatchDescHeader* descExt = header->pNext;
+
+ switch (header->type)
+ {
+ case FFX_API_DISPATCH_DESC_TYPE_UPSCALE:
+ {
+ auto desc = reinterpret_cast(header);
+
+ FfxFsr2DispatchDescription dispatchParameters = {};
+ dispatchParameters.commandList = desc->commandList;
+ dispatchParameters.color = Convert(desc->color);
+ dispatchParameters.depth = Convert(desc->depth);
+ dispatchParameters.motionVectors = Convert(desc->motionVectors);
+ dispatchParameters.exposure = Convert(desc->exposure);
+ dispatchParameters.output = Convert(desc->output);
+ dispatchParameters.reactive = Convert(desc->reactive);
+ dispatchParameters.transparencyAndComposition = Convert(desc->transparencyAndComposition);
+ dispatchParameters.jitterOffset.x = desc->jitterOffset.x;
+ dispatchParameters.jitterOffset.y = desc->jitterOffset.y;
+ dispatchParameters.motionVectorScale.x = desc->motionVectorScale.x;
+ dispatchParameters.motionVectorScale.y = desc->motionVectorScale.y;
+ dispatchParameters.reset = desc->reset;
+ dispatchParameters.enableSharpening = desc->enableSharpening;
+ dispatchParameters.sharpness = desc->sharpness;
+ dispatchParameters.frameTimeDelta = desc->frameTimeDelta;
+ dispatchParameters.preExposure = desc->preExposure;
+ dispatchParameters.renderSize.width = desc->renderSize.width;
+ dispatchParameters.renderSize.height = desc->renderSize.height;
+ dispatchParameters.cameraFovAngleVertical = desc->cameraFovAngleVertical;
+ dispatchParameters.cameraFar = desc->cameraFar;
+ dispatchParameters.cameraNear = desc->cameraNear;
+ dispatchParameters.viewSpaceToMetersFactor = desc->viewSpaceToMetersFactor;
+
+ // Check for and process extensions
+ //if (descExt != nullptr)
+ //{
+ // TRY(ProcessExtensionsPreDispatch(internal_context, &dispatchParameters, &descExt));
+ //}
+
+ TRY2(ffxFsr2ContextDispatch(&internal_context->context, &dispatchParameters));
+ break;
+ }
+ case FFX_API_DISPATCH_DESC_TYPE_UPSCALE_GENERATEREACTIVEMASK:
+ {
+ auto desc = reinterpret_cast(header);
+
+ FfxFsr2GenerateReactiveDescription dispatchParameters = {};
+ dispatchParameters.commandList = desc->commandList;
+ dispatchParameters.colorOpaqueOnly = Convert(desc->colorOpaqueOnly);
+ dispatchParameters.colorPreUpscale = Convert(desc->colorPreUpscale);
+ dispatchParameters.outReactive = Convert(desc->outReactive);
+ dispatchParameters.renderSize.width = desc->renderSize.width;
+ dispatchParameters.renderSize.height = desc->renderSize.height;
+ dispatchParameters.scale = desc->scale;
+ dispatchParameters.cutoffThreshold = desc->cutoffThreshold;
+ dispatchParameters.binaryValue = desc->binaryValue;
+ dispatchParameters.flags = desc->flags;
+
+ TRY2(ffxFsr2ContextGenerateReactiveMask(&internal_context->context, &dispatchParameters));
+ break;
+ }
+ default:
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxProvider_FSR2 ffxProvider_FSR2::Instance;
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider_fsr2.h b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr2.h
new file mode 100644
index 00000000..6a60827a
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr2.h
@@ -0,0 +1,50 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include "ffx_provider.h"
+
+class ffxProvider_FSR2: public ffxProvider
+{
+public:
+ ffxProvider_FSR2() = default;
+ virtual ~ffxProvider_FSR2() = default;
+
+ virtual bool CanProvide(uint64_t type) const override;
+
+ virtual uint64_t GetId() const override;
+
+ virtual const char* GetVersionName() const override;
+
+ virtual ffxReturnCode_t CreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t DestroyContext(ffxContext* context, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t Configure(ffxContext* context, const ffxConfigureDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Query(ffxContext* context, ffxQueryDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Dispatch(ffxContext* context, const ffxDispatchDescHeader* desc) const override;
+
+ static ffxProvider_FSR2 Instance;
+
+};
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider_fsr3upscale.cpp b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr3upscale.cpp
new file mode 100644
index 00000000..c1e140c2
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr3upscale.cpp
@@ -0,0 +1,388 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_provider_fsr3upscale.h"
+#include "backends.h"
+#include "validation.h"
+#include
+#ifdef FFX_BACKEND_DX12
+#include
+#endif // FFX_BACKEND_DX12
+#ifdef FFX_BACKEND_VK
+#include
+#endif // #ifdef FFX_BACKEND_VK
+#include
+#include
+
+#include
+
+static uint32_t ConvertFlags(uint32_t apiFlags)
+{
+ uint32_t outFlags = 0;
+ if (apiFlags & FFX_UPSCALE_ENABLE_HIGH_DYNAMIC_RANGE)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_HIGH_DYNAMIC_RANGE;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS;
+ if (apiFlags & FFX_UPSCALE_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DEPTH_INVERTED)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_DEPTH_INVERTED;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DEPTH_INFINITE)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_DEPTH_INFINITE;
+ if (apiFlags & FFX_UPSCALE_ENABLE_AUTO_EXPOSURE)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_AUTO_EXPOSURE;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DYNAMIC_RESOLUTION)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_DYNAMIC_RESOLUTION;
+ if (apiFlags & FFX_UPSCALE_ENABLE_DEBUG_CHECKING)
+ outFlags |= FFX_FSR3UPSCALER_ENABLE_DEBUG_CHECKING;
+ return outFlags;
+}
+
+bool ffxProvider_FSR3Upscale::CanProvide(uint64_t type) const
+{
+ return (type & FFX_API_EFFECT_MASK) == FFX_API_EFFECT_ID_UPSCALE;
+}
+
+#define STRINGIFY_(X) #X
+#define STRINGIFY(X) STRINGIFY_(X)
+#define MAKE_VERSION_STRING(major, minor, patch) STRINGIFY major "." STRINGIFY minor "." STRINGIFY patch
+
+uint64_t ffxProvider_FSR3Upscale::GetId() const
+{
+ // FSR Scale, version from header
+ return 0xF5A5'CA1Eui64 << 32 | (FFX_SDK_MAKE_VERSION(FFX_FSR3UPSCALER_VERSION_MAJOR, FFX_FSR3UPSCALER_VERSION_MINOR, FFX_FSR3UPSCALER_VERSION_PATCH) & 0xFFFF'FFFF);
+}
+
+const char* ffxProvider_FSR3Upscale::GetVersionName() const
+{
+ return MAKE_VERSION_STRING(FFX_FSR3UPSCALER_VERSION_MAJOR, FFX_FSR3UPSCALER_VERSION_MINOR, FFX_FSR3UPSCALER_VERSION_PATCH);
+}
+
+struct InternalFsr3UpscalerUContext
+{
+ InternalContextHeader header;
+ FfxInterface backendInterface;
+ FfxResourceInternal sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_COUNT];
+ FfxFsr3UpscalerContext context;
+ ffxApiMessage fpMessage;
+ uint32_t debugLevel;
+};
+
+ffxReturnCode_t ffxProvider_FSR3Upscale::CreateContext(ffxContext* context, ffxCreateContextDescHeader* header, Allocator& alloc) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ if (desc->fpMessage)
+ {
+#ifdef FFX_BACKEND_DX12
+ Validator{desc->fpMessage, header}.AcceptExtensions({FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12, FFX_API_DESC_TYPE_OVERRIDE_VERSION});
+#elif FFX_BACKEND_VK
+ Validator{ desc->fpMessage, header }.AcceptExtensions({ FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_VK, FFX_API_DESC_TYPE_OVERRIDE_VERSION });
+#endif // FFX_BACKEND_DX12
+ }
+ InternalFsr3UpscalerUContext* internal_context = alloc.construct();
+ VERIFY(internal_context, FFX_API_RETURN_ERROR_MEMORY);
+ internal_context->header.provider = this;
+
+ TRY(MustCreateBackend(header, &internal_context->backendInterface, 1, alloc));
+
+ FfxFsr3UpscalerContextDescription initializationParameters = {0};
+ initializationParameters.backendInterface = internal_context->backendInterface;
+ initializationParameters.maxRenderSize.width = desc->maxRenderSize.width;
+ initializationParameters.maxRenderSize.height = desc->maxRenderSize.height;
+ initializationParameters.maxUpscaleSize.width = desc->maxUpscaleSize.width;
+ initializationParameters.maxUpscaleSize.height = desc->maxUpscaleSize.height;
+ initializationParameters.flags = ConvertFlags(desc->flags);
+ // Calling this casted function is undefined behaviour, but it's probably safe.
+ initializationParameters.fpMessage = reinterpret_cast(desc->fpMessage);
+
+ // Grab this fp for use in extensions later
+ internal_context->fpMessage = desc->fpMessage;
+
+ // Create the FSR3UPSCALER context
+ TRY2(ffxFsr3UpscalerContextCreate(&internal_context->context, &initializationParameters));
+
+ ffxFsr3UpscalerSetGlobalDebugMessage(reinterpret_cast(desc->fpMessage), 0);
+
+ // set up FSR3Upscaler "shared" resources (no resource sharing in the upscaler provider though, since providers are fully independent and we can't guarantee all upscale providers will be compatible with other effects)
+ {
+ FfxFsr3UpscalerSharedResourceDescriptions fs3UpscalerResourceDescs = {};
+ TRY2(ffxFsr3UpscalerGetSharedResourceDescriptions(&internal_context->context, &fs3UpscalerResourceDescs));
+
+ {
+ FfxCreateResourceDescription dilD = fs3UpscalerResourceDescs.dilatedDepth;
+ dilD.name = fs3UpscalerResourceDescs.dilatedDepth.name;
+ TRY2(internal_context->backendInterface.fpCreateResource(
+ &internal_context->backendInterface,
+ &dilD,
+ 0,
+ &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_DEPTH_0]));
+
+ FfxCreateResourceDescription dilMVs = fs3UpscalerResourceDescs.dilatedMotionVectors;
+ dilD.name = fs3UpscalerResourceDescs.dilatedMotionVectors.name;
+ TRY2(internal_context->backendInterface.fpCreateResource(
+ &internal_context->backendInterface,
+ &dilMVs,
+ 0,
+ &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_0]));
+
+ FfxCreateResourceDescription recND = fs3UpscalerResourceDescs.reconstructedPrevNearestDepth;
+ recND.name = fs3UpscalerResourceDescs.reconstructedPrevNearestDepth.name;
+ TRY2(internal_context->backendInterface.fpCreateResource(
+ &internal_context->backendInterface,
+ &recND,
+ 0,
+ &internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_RECONSTRUCTED_PREVIOUS_NEAREST_DEPTH_0]));
+ }
+ }
+
+ *context = internal_context;
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FSR3Upscale::DestroyContext(ffxContext* context, Allocator& alloc) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFsr3UpscalerUContext* internal_context = reinterpret_cast(*context);
+
+ for (FfxUInt32 i = 0; i < FFX_FSR3_RESOURCE_IDENTIFIER_COUNT; i++)
+ {
+ TRY2(internal_context->backendInterface.fpDestroyResource(
+ &internal_context->backendInterface, internal_context->sharedResources[i], 0));
+ }
+
+ TRY2(ffxFsr3UpscalerContextDestroy(&internal_context->context));
+
+ alloc.dealloc(internal_context->backendInterface.scratchBuffer);
+ alloc.dealloc(internal_context);
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FSR3Upscale::Configure(ffxContext* context, const ffxConfigureDescHeader* header) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+ InternalFsr3UpscalerUContext* internal_context = reinterpret_cast(*context);
+ switch (header->type)
+ {
+ case FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE:
+ {
+ auto desc = reinterpret_cast(header);
+ TRY2(ffxFsr3UpscalerSetConstant(&internal_context->context, static_cast(desc->key), desc->ptr));
+ break;
+ }
+ case FFX_API_CONFIGURE_DESC_TYPE_GLOBALDEBUG1:
+ {
+ auto desc = reinterpret_cast(header);
+ TRY2(ffxFsr3UpscalerSetGlobalDebugMessage( reinterpret_cast(desc->fpMessage),
+ desc->debugLevel));
+ internal_context->fpMessage = desc->fpMessage;
+ internal_context->debugLevel = desc->debugLevel;
+ break;
+ }
+ default:
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FSR3Upscale::Query(ffxContext* context, ffxQueryDescHeader* header) const
+{
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+
+ if (context)
+ {
+ InternalFsr3UpscalerUContext* internal_context = reinterpret_cast(*context);
+ if (internal_context->fpMessage)
+ {
+ Validator{internal_context->fpMessage, header}.NoExtensions();
+ }
+ }
+
+ switch (header->type)
+ {
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTEROFFSET:
+ {
+ auto desc = reinterpret_cast(header);
+ float jitterX, jitterY;
+ TRY2(ffxFsr3UpscalerGetJitterOffset(&jitterX, &jitterY, desc->index, desc->phaseCount));
+ if (desc->pOutX != nullptr)
+ {
+ *desc->pOutX = jitterX;
+ }
+ if (desc->pOutY != nullptr)
+ {
+ *desc->pOutY = jitterY;
+ }
+ break;
+ }
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTERPHASECOUNT:
+ {
+ auto desc = reinterpret_cast(header);
+ const int32_t jitterPhaseCount = ffxFsr3UpscalerGetJitterPhaseCount(desc->renderWidth, desc->displayWidth);
+
+ if (desc->pOutPhaseCount != nullptr)
+ {
+ *desc->pOutPhaseCount = jitterPhaseCount;
+ }
+ break;
+ }
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETRENDERRESOLUTIONFROMQUALITYMODE:
+ {
+ auto desc = reinterpret_cast(header);
+ uint32_t renderWidth;
+ uint32_t renderHeight;
+
+ TRY2(ffxFsr3UpscalerGetRenderResolutionFromQualityMode(&renderWidth, &renderHeight, desc->displayWidth, desc->displayHeight, ConvertEnum(desc->qualityMode)));
+ if (desc->pOutRenderWidth != nullptr)
+ {
+ *desc->pOutRenderWidth = renderWidth;
+ }
+ if (desc->pOutRenderHeight != nullptr)
+ {
+ *desc->pOutRenderHeight = renderHeight;
+ }
+ break;
+ }
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GETUPSCALERATIOFROMQUALITYMODE:
+ {
+ auto desc = reinterpret_cast(header);
+ float ratio = ffxFsr3UpscalerGetUpscaleRatioFromQualityMode(ConvertEnum(desc->qualityMode));
+
+ if (desc->pOutUpscaleRatio != nullptr)
+ {
+ *desc->pOutUpscaleRatio = ratio;
+ }
+ break;
+ }
+ case FFX_API_QUERY_DESC_TYPE_UPSCALE_GPU_MEMORY_USAGE:
+ {
+ InternalFsr3UpscalerUContext* internal_context = reinterpret_cast(*context);
+ auto desc = reinterpret_cast(header);
+
+ TRY2(ffxFsr3UpscalerContextGetGpuMemoryUsage(&internal_context->context, reinterpret_cast (desc->gpuMemoryUsageUpscaler)));
+ break;
+ }
+ default:
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FSR3Upscale::Dispatch(ffxContext* context, const ffxDispatchDescHeader* header) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFsr3UpscalerUContext* internal_context = reinterpret_cast(*context);
+ if (internal_context->fpMessage)
+ {
+ Validator{internal_context->fpMessage, header}.NoExtensions();
+ }
+
+ switch (header->type)
+ {
+ case FFX_API_DISPATCH_DESC_TYPE_UPSCALE:
+ {
+ auto desc = reinterpret_cast(header);
+
+ FfxFsr3UpscalerDispatchDescription dispatchParameters = {};
+ dispatchParameters.commandList = desc->commandList;
+ dispatchParameters.color = Convert(desc->color);
+ dispatchParameters.depth = Convert(desc->depth);
+ dispatchParameters.motionVectors = Convert(desc->motionVectors);
+ dispatchParameters.exposure = Convert(desc->exposure);
+ dispatchParameters.output = Convert(desc->output);
+ dispatchParameters.reactive = Convert(desc->reactive);
+ dispatchParameters.transparencyAndComposition = Convert(desc->transparencyAndComposition);
+ dispatchParameters.jitterOffset.x = desc->jitterOffset.x;
+ dispatchParameters.jitterOffset.y = desc->jitterOffset.y;
+ dispatchParameters.motionVectorScale.x = desc->motionVectorScale.x;
+ dispatchParameters.motionVectorScale.y = desc->motionVectorScale.y;
+ dispatchParameters.reset = desc->reset;
+ dispatchParameters.enableSharpening = desc->enableSharpening;
+ dispatchParameters.sharpness = desc->sharpness;
+ dispatchParameters.frameTimeDelta = desc->frameTimeDelta;
+ dispatchParameters.preExposure = desc->preExposure;
+ dispatchParameters.renderSize.width = desc->renderSize.width;
+ dispatchParameters.renderSize.height = desc->renderSize.height;
+ dispatchParameters.upscaleSize.width = desc->upscaleSize.width;
+ dispatchParameters.upscaleSize.height = desc->upscaleSize.height;
+ dispatchParameters.cameraFovAngleVertical = desc->cameraFovAngleVertical;
+ dispatchParameters.cameraFar = desc->cameraFar;
+ dispatchParameters.cameraNear = desc->cameraNear;
+ dispatchParameters.viewSpaceToMetersFactor = desc->viewSpaceToMetersFactor;
+ dispatchParameters.flags = 0;
+
+ dispatchParameters.dilatedDepth = internal_context->backendInterface.fpGetResource( &internal_context->backendInterface, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_DEPTH_0]);
+ dispatchParameters.dilatedMotionVectors = internal_context->backendInterface.fpGetResource( &internal_context->backendInterface, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_0]);
+ dispatchParameters.reconstructedPrevNearestDepth = internal_context->backendInterface.fpGetResource( &internal_context->backendInterface, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_RECONSTRUCTED_PREVIOUS_NEAREST_DEPTH_0]);
+
+ if (desc->flags & FFX_UPSCALE_FLAG_DRAW_DEBUG_VIEW)
+ {
+ dispatchParameters.flags |= FFX_FSR3UPSCALER_DISPATCH_DRAW_DEBUG_VIEW;
+ }
+
+ TRY2(ffxFsr3UpscalerContextDispatch(&internal_context->context, &dispatchParameters));
+ break;
+ }
+ case FFX_API_DISPATCH_DESC_TYPE_UPSCALE_GENERATEREACTIVEMASK:
+ {
+ auto desc = reinterpret_cast(header);
+
+ FfxFsr3UpscalerGenerateReactiveDescription dispatchParameters = {};
+ dispatchParameters.commandList = desc->commandList;
+ dispatchParameters.colorOpaqueOnly = Convert(desc->colorOpaqueOnly);
+ dispatchParameters.colorPreUpscale = Convert(desc->colorPreUpscale);
+ dispatchParameters.outReactive = Convert(desc->outReactive);
+ dispatchParameters.renderSize.width = desc->renderSize.width;
+ dispatchParameters.renderSize.height = desc->renderSize.height;
+ dispatchParameters.scale = desc->scale;
+ dispatchParameters.cutoffThreshold = desc->cutoffThreshold;
+ dispatchParameters.binaryValue = desc->binaryValue;
+ dispatchParameters.flags = desc->flags;
+
+ TRY2(ffxFsr3UpscalerContextGenerateReactiveMask(&internal_context->context, &dispatchParameters));
+ break;
+ }
+ default:
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxProvider_FSR3Upscale ffxProvider_FSR3Upscale::Instance;
diff --git a/Kits/AMDTK/ffx-api/src/ffx_provider_fsr3upscale.h b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr3upscale.h
new file mode 100644
index 00000000..14bce1b2
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/ffx_provider_fsr3upscale.h
@@ -0,0 +1,50 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include "ffx_provider.h"
+
+class ffxProvider_FSR3Upscale: public ffxProvider
+{
+public:
+ ffxProvider_FSR3Upscale() = default;
+ virtual ~ffxProvider_FSR3Upscale() = default;
+
+ virtual bool CanProvide(uint64_t type) const override;
+
+ virtual uint64_t GetId() const override;
+
+ virtual const char* GetVersionName() const override;
+
+ virtual ffxReturnCode_t CreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t DestroyContext(ffxContext* context, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t Configure(ffxContext* context, const ffxConfigureDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Query(ffxContext* context, ffxQueryDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Dispatch(ffxContext* context, const ffxDispatchDescHeader* desc) const override;
+
+ static ffxProvider_FSR3Upscale Instance;
+
+};
diff --git a/Kits/AMDTK/ffx-api/src/resource/ffx_api_dll.rc b/Kits/AMDTK/ffx-api/src/resource/ffx_api_dll.rc
new file mode 100644
index 00000000..81c0df6d
Binary files /dev/null and b/Kits/AMDTK/ffx-api/src/resource/ffx_api_dll.rc differ
diff --git a/Kits/AMDTK/ffx-api/src/resource/resource.h b/Kits/AMDTK/ffx-api/src/resource/resource.h
new file mode 100644
index 00000000..e330b3f3
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/resource/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ffx_api_dll.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Kits/AMDTK/ffx-api/src/validation.cpp b/Kits/AMDTK/ffx-api/src/validation.cpp
new file mode 100644
index 00000000..6c638be2
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/validation.cpp
@@ -0,0 +1,146 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "validation.h"
+
+#ifdef FFX_BACKEND_DX12
+#include
+#endif // FFX_BACKEND_DX12
+#ifdef FFX_BACKEND_VK
+#include
+#endif // #ifdef FFX_BACKEND_VK
+
+#include
+#include
+
+#include
+#include
+#include
+
+#define MAP_ENUM_NAME(_value) {_value, #_value}
+
+#ifdef FFXAPI_VALIDATION
+
+static std::unordered_map EnumNameMap{
+#ifdef FFX_BACKEND_DX12
+ MAP_ENUM_NAME(FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATION),
+ MAP_ENUM_NAME(FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_REGISTERUIRESOURCE_DX12),
+ MAP_ENUM_NAME(FFX_API_CONFIGURE_DESC_TYPE_GLOBALDEBUG1),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATION),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_DX12),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_GET_VERSIONS),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_INTERPOLATIONCOMMANDLIST_DX12),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_INTERPOLATIONTEXTURE_DX12),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTEROFFSET),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTERPHASECOUNT),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_UPSCALE_GETRENDERRESOLUTIONFROMQUALITYMODE),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_UPSCALE_GETUPSCALERATIOFROMQUALITYMODE),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_FRAMEGENERATION),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_FRAMEGENERATION_PREPARE),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_UPSCALE_GENERATEREACTIVEMASK),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_UPSCALE),
+ MAP_ENUM_NAME(FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE),
+#elif FFX_BACKEND_VK
+ MAP_ENUM_NAME(FFX_API_CONFIGURE_DESC_TYPE_FG),
+ MAP_ENUM_NAME(FFX_API_CONFIGURE_DESC_TYPE_FGSWAPCHAIN_REGISTERUIRESOURCE_VK),
+ MAP_ENUM_NAME(FFX_API_CONFIGURE_DESC_TYPE_GLOBALDEBUG1),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_VK),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_FG),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_FGSWAPCHAIN_VK),
+ MAP_ENUM_NAME(FFX_API_CREATE_CONTEXT_DESC_TYPE_FSR_UPSCALE),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_GET_VERSIONS),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FGSWAPCHAIN_FUNCTIONS_VK),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FGSWAPCHAIN_INTERPOLATIONCOMMANDLIST_VK),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FGSWAPCHAIN_INTERPOLATIONTEXTURE_DX12),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FGSWAPCHAIN_INTERPOLATIONTEXTURE_VK),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FSR_GETJITTEROFFSET),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FSR_GETJITTERPHASECOUNT),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FSR_GETRENDERRESOLUTIONFROMQUALITYMODE),
+ MAP_ENUM_NAME(FFX_API_QUERY_DESC_TYPE_FSR_GETUPSCALERATIOFROMQUALITYMODE),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_FG),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_FG_PREPARE),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_FSR_GENERATEREACTIVEMASK),
+ MAP_ENUM_NAME(FFX_API_DISPATCH_DESC_TYPE_FSR_UPSCALE),
+#endif // FFX_BACKEND_VK
+};
+
+static const char* GetEnumName(uint64_t value)
+{
+ auto it = EnumNameMap.find(value);
+ if (it == EnumNameMap.end()) return "INVALID_ENUM";
+ return it->second;
+}
+
+#endif
+
+Validator& Validator::NoExtensions()
+{
+#ifdef FFXAPI_VALIDATION
+ for (auto *it = header->pNext; it; it = it->pNext)
+ {
+ // invalid extension!
+ std::wostringstream message{};
+ message << "After header " << GetEnumName(header->type) << ": ignoring unexpected extension " << GetEnumName(it->type);
+ callback(FFX_API_MESSAGE_TYPE_WARNING, message.str().c_str());
+ }
+#endif
+ return *this;
+}
+
+Validator& Validator::AcceptExtensions(std::initializer_list extensionsOnce, std::initializer_list extensionsMany)
+{
+#ifdef FFXAPI_VALIDATION
+ std::vector seenOnce(extsOnce.size(), false);
+ for (auto *it = header->pNext; it; it = it->pNext)
+ {
+ bool canHave = extsMany.end() == std::find(extsMany.begin(), extsMany.end(), it->type);
+ if (!canHave)
+ {
+ auto it_once = std::find(extsOnce.begin(), extsOnce.end(), it->type);
+ if (it_once != extsOnce.end())
+ {
+ canHave = true; // prevent error further down even if present more than once.
+ auto idx = std::distance(extsOnce.begin(), it_once);
+ if (seenOnce[idx])
+ {
+ // extension present more than once!
+ std::wostringstream message{};
+ message << "After header " << GetEnumName(header->type) << ": extension " << GetEnumName(it->type) << " present more than once";
+ callback(FFX_API_MESSAGE_TYPE_WARNING, message.str().c_str());
+ }
+ seenOnce[idx] = true;
+ }
+ }
+ if (!canHave)
+ {
+ // invalid extension!
+ std::wostringstream message{};
+ message << "After header " << GetEnumName(header->type) << ": ignoring unexpected extension " << GetEnumName(it->type);
+ callback(FFX_API_MESSAGE_TYPE_WARNING, message.str().c_str());
+ }
+ }
+#endif
+
+ return *this;
+}
diff --git a/Kits/AMDTK/ffx-api/src/validation.h b/Kits/AMDTK/ffx-api/src/validation.h
new file mode 100644
index 00000000..93730b90
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/validation.h
@@ -0,0 +1,38 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+
+#include
+#include
+
+class Validator
+{
+ ffxApiMessage callback;
+ const ffxApiHeader* header;
+
+public:
+ Validator(ffxApiMessage callback, const ffxApiHeader* header) : callback(callback), header(header) {}
+
+ Validator& AcceptExtensions(std::initializer_list extensionsOnce, std::initializer_list extensionsMany = {});
+ Validator& NoExtensions();
+};
diff --git a/Kits/AMDTK/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.cpp b/Kits/AMDTK/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.cpp
new file mode 100644
index 00000000..9239318b
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.cpp
@@ -0,0 +1,273 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_provider_framegenerationswapchain_vk.h"
+#include
+#include
+#include
+
+#include
+
+struct InternalFgScContext
+{
+ InternalContextHeader header;
+ VkFrameInterpolationInfoFFX frameInterpolationInfo;
+ VkSwapchainKHR fiSwapChain;
+ FfxSwapchainReplacementFunctions replacementFunctions;
+};
+
+//////////////////////////////////////////////
+/// Vulkan FFX API overridden functions
+//////////////////////////////////////////////
+
+VkResult vkCreateSwapchainFFXAPI(
+ VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain, void* pContext)
+{
+ if (pCreateInfo == nullptr || pContext == nullptr)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ InternalFgScContext* internal_context = reinterpret_cast(pContext);
+
+ if (internal_context->fiSwapChain != VK_NULL_HANDLE)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ VkResult result = VK_ERROR_INITIALIZATION_FAILED;
+ if (internal_context != nullptr && internal_context->replacementFunctions.createSwapchainFFX != nullptr)
+ {
+ result = internal_context->replacementFunctions.createSwapchainFFX(
+ device, pCreateInfo, pAllocator, &internal_context->fiSwapChain, &internal_context->frameInterpolationInfo);
+ }
+
+ if (result == VK_SUCCESS)
+ *pSwapchain = reinterpret_cast(internal_context->fiSwapChain);
+
+ return result;
+}
+
+void vkDestroySwapchainFFXAPI(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator, void* pContext)
+{
+ if (swapchain != VK_NULL_HANDLE)
+ {
+ InternalFgScContext* internal_context = reinterpret_cast(pContext);
+ if (swapchain != internal_context->fiSwapChain)
+ return;
+
+ if (internal_context != nullptr && internal_context->fiSwapChain != VK_NULL_HANDLE &&
+ internal_context->replacementFunctions.destroySwapchainKHR != nullptr)
+ {
+ internal_context->replacementFunctions.destroySwapchainKHR(device, internal_context->fiSwapChain, pAllocator);
+ internal_context->fiSwapChain = VK_NULL_HANDLE;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////
+/// ffxProvider_FrameGenerationSwapChain_VK implementation
+///////////////////////////////////////////////////////////////
+
+bool ffxProvider_FrameGenerationSwapChain_VK::CanProvide(uint64_t type) const
+{
+ return (type & FFX_API_EFFECT_MASK) == FFX_API_EFFECT_ID_FGSC_VK;
+}
+
+uint64_t ffxProvider_FrameGenerationSwapChain_VK::GetId() const
+{
+ // FG SwapChain VK, version 1.1.3
+ return 0xF65D'564B'01'001'003ui64;
+}
+
+const char* ffxProvider_FrameGenerationSwapChain_VK::GetVersionName() const
+{
+ return "1.1.3";
+}
+
+inline VkQueueInfoFFX convertQueueInfo(VkQueueInfoFFXAPI queueInfo)
+{
+ VkQueueInfoFFX info;
+ info.queue = queueInfo.queue;
+ info.familyIndex = queueInfo.familyIndex;
+ info.submitFunc = queueInfo.submitFunc;
+ return info;
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_VK::CreateContext(ffxContext* context, ffxCreateContextDescHeader* header, Allocator& alloc) const
+{
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ InternalFgScContext* internal_context = alloc.construct();
+ VERIFY(internal_context, FFX_API_RETURN_ERROR_MEMORY);
+ internal_context->header.provider = this;
+
+ internal_context->frameInterpolationInfo.physicalDevice = desc->physicalDevice;
+ internal_context->frameInterpolationInfo.device = desc->device;
+ internal_context->frameInterpolationInfo.gameQueue = convertQueueInfo(desc->gameQueue);
+ internal_context->frameInterpolationInfo.asyncComputeQueue = convertQueueInfo(desc->asyncComputeQueue);
+ internal_context->frameInterpolationInfo.presentQueue = convertQueueInfo(desc->presentQueue);
+ internal_context->frameInterpolationInfo.imageAcquireQueue = convertQueueInfo(desc->imageAcquireQueue);
+ internal_context->frameInterpolationInfo.pAllocator = desc->allocator;
+
+ // set the default values
+ internal_context->frameInterpolationInfo.compositionMode = VK_COMPOSITION_MODE_NOT_FORCED_FFX;
+
+ // get the extensions
+ for (auto it = header->pNext; it != nullptr; it = it->pNext)
+ {
+ if (auto mode = ffx::DynamicCast(it))
+ {
+ if (mode->composeOnPresentQueue)
+ internal_context->frameInterpolationInfo.compositionMode = VK_COMPOSITION_MODE_PRESENT_QUEUE_FFX;
+ else
+ internal_context->frameInterpolationInfo.compositionMode = VK_COMPOSITION_MODE_GAME_QUEUE_FFX;
+ }
+ }
+
+ FfxSwapchain swapChain = ffxGetSwapchainVK(*desc->swapchain);
+ TRY2(ffxReplaceSwapchainForFrameinterpolationVK(desc->gameQueue.queue, swapChain, &desc->createInfo, &internal_context->frameInterpolationInfo));
+ internal_context->fiSwapChain = *desc->swapchain = ffxGetVKSwapchain(swapChain);
+
+ internal_context->replacementFunctions = {};
+ TRY2(ffxGetSwapchainReplacementFunctionsVK(internal_context->frameInterpolationInfo.device, &internal_context->replacementFunctions));
+
+ *context = internal_context;
+
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_UNKNOWN_DESCTYPE;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_VK::DestroyContext(ffxContext* context, Allocator& alloc) const
+{
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+
+ // call the correct function to release the frame interpolation swapchain
+ FfxSwapchainReplacementFunctions functions = {};
+ ffxGetSwapchainReplacementFunctionsVK(internal_context->frameInterpolationInfo.device, &functions);
+
+ if (functions.destroySwapchainKHR != nullptr)
+ {
+ functions.destroySwapchainKHR(
+ internal_context->frameInterpolationInfo.device, internal_context->fiSwapChain, internal_context->frameInterpolationInfo.pAllocator);
+ internal_context->fiSwapChain = VK_NULL_HANDLE;
+ }
+ else
+ {
+ vkDestroySwapchainKHR(
+ internal_context->frameInterpolationInfo.device, internal_context->fiSwapChain, internal_context->frameInterpolationInfo.pAllocator);
+ internal_context->fiSwapChain = VK_NULL_HANDLE;
+ }
+
+ alloc.dealloc(internal_context);
+
+ return FFX_API_RETURN_OK;
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_VK::Configure(ffxContext* context, const ffxConfigureDescHeader* header) const
+{
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ TRY2(ffxRegisterFrameinterpolationUiResourceVK(ffxGetSwapchainVK(internal_context->fiSwapChain), Convert(desc->uiResource), desc->flags));
+
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ TRY2(ffxConfigureFrameInterpolationSwapchainVK(ffxGetSwapchainVK(internal_context->fiSwapChain), static_cast (desc->key), desc->ptr));
+
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_PARAMETER;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_VK::Query(ffxContext* context, ffxQueryDescHeader* header) const
+{
+ VERIFY(header, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(context, FFX_API_RETURN_ERROR_PARAMETER);
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ FfxCommandList outCommandList{};
+ TRY2(ffxGetFrameinterpolationCommandlistVK(ffxGetSwapchainVK(internal_context->fiSwapChain), outCommandList));
+ *desc->pOutCommandList = outCommandList;
+
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ *desc->pOutTexture = Convert(ffxGetFrameinterpolationTextureVK(ffxGetSwapchainVK(internal_context->fiSwapChain)));
+
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ TRY2(ffxFrameInterpolationSwapchainGetGpuMemoryUsageVK(ffxGetSwapchainVK(internal_context->fiSwapChain), reinterpret_cast (desc->gpuMemoryUsageFrameGenerationSwapchain)));
+ return FFX_API_RETURN_OK;
+ }
+ else if (auto desc = ffx::DynamicCast(header))
+ {
+ desc->pOutCreateSwapchainFFXAPI = vkCreateSwapchainFFXAPI;
+ desc->pOutDestroySwapchainFFXAPI = vkDestroySwapchainFFXAPI;
+ desc->pOutGetSwapchainImagesKHR = internal_context->replacementFunctions.getSwapchainImagesKHR;
+ desc->pOutAcquireNextImageKHR = internal_context->replacementFunctions.acquireNextImageKHR;
+ desc->pOutQueuePresentKHR = internal_context->replacementFunctions.queuePresentKHR;
+ desc->pOutSetHdrMetadataEXT = internal_context->replacementFunctions.setHdrMetadataEXT;
+ desc->pOutGetLastPresentCountFFXAPI = internal_context->replacementFunctions.getLastPresentCountFFX; // Same signature so no need for indirection
+
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR_PARAMETER;
+ }
+}
+
+ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_VK::Dispatch(ffxContext* context, const ffxDispatchDescHeader* header) const
+{
+ VERIFY(*context, FFX_API_RETURN_ERROR_PARAMETER);
+ InternalFgScContext* internal_context = reinterpret_cast(*context);
+ if (auto desc = ffx::DynamicCast(header))
+ {
+ ffxWaitForPresents(internal_context->fiSwapChain);
+ return FFX_API_RETURN_OK;
+ }
+ else
+ {
+ return FFX_API_RETURN_ERROR;
+ }
+}
+
+ffxProvider_FrameGenerationSwapChain_VK ffxProvider_FrameGenerationSwapChain_VK::Instance;
diff --git a/Kits/AMDTK/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.h b/Kits/AMDTK/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.h
new file mode 100644
index 00000000..dcebf4f6
--- /dev/null
+++ b/Kits/AMDTK/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.h
@@ -0,0 +1,49 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include "../ffx_provider.h"
+
+class ffxProvider_FrameGenerationSwapChain_VK: public ffxProvider
+{
+public:
+ ffxProvider_FrameGenerationSwapChain_VK() = default;
+ virtual ~ffxProvider_FrameGenerationSwapChain_VK() = default;
+
+ virtual bool CanProvide(uint64_t type) const override;
+
+ virtual uint64_t GetId() const override;
+
+ virtual const char* GetVersionName() const override;
+
+ virtual ffxReturnCode_t CreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t DestroyContext(ffxContext* context, Allocator& alloc) const override;
+
+ virtual ffxReturnCode_t Configure(ffxContext* context, const ffxConfigureDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Query(ffxContext* context, ffxQueryDescHeader* desc) const override;
+
+ virtual ffxReturnCode_t Dispatch(ffxContext* context, const ffxDispatchDescHeader* desc) const override;
+
+ static ffxProvider_FrameGenerationSwapChain_VK Instance;
+};
diff --git a/Kits/AMDTK/fidelityfx/BuildFidelityFXSDK.bat b/Kits/AMDTK/fidelityfx/BuildFidelityFXSDK.bat
new file mode 100644
index 00000000..5cb3cbb4
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/BuildFidelityFXSDK.bat
@@ -0,0 +1,84 @@
+:: This file is part of the FidelityFX SDK.
+::
+:: Copyright (C) 2024 Advanced Micro Devices, Inc.
+::
+:: Permission is hereby granted, free of charge, to any person obtaining a copy
+:: of this software and associated documentation files(the "Software"), to deal
+:: in the Software without restriction, including without limitation the rights
+:: to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+:: copies of the Software, and to permit persons to whom the Software is
+:: furnished to do so, subject to the following conditions :
+::
+:: The above copyright notice and this permission notice shall be included in
+:: all copies or substantial portions of the Software.
+::
+:: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+:: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+:: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+:: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+:: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+:: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+:: THE SOFTWARE.
+
+@echo off
+setlocal enabledelayedexpansion
+
+echo ===============================================================
+echo.
+echo FidelityFX Build System
+echo.
+echo ===============================================================
+
+echo Checking pre-requisites...
+
+:: Check if cmake is installed
+cmake --version > nul 2>&1
+if %errorlevel% NEQ 0 (
+ echo Cannot find path to CMake. Is CMake installed? Exiting...
+ exit /b -1
+) else (
+ echo CMake Ready.
+)
+
+echo.
+echo Building FidelityFX SDK (Standalone)
+echo.
+
+:: Check directories exist and create if not
+if not exist build\ (
+ mkdir build
+)
+
+cd build
+
+:: Clear out CMakeCache
+if exist CMakeFiles\ (
+ rmdir /S /Q CMakeFiles
+)
+if exist CMakeCache.txt (
+ del /S /Q CMakeCache.txt
+)
+
+:: determine architecture
+if /i "%PROCESSOR_ARCHITECTURE%" == "ARM64" (
+ set arch=ARM64
+) else (
+ set arch=X64
+)
+echo architecture %arch% detected
+echo.
+
+:: Check if any parameters were passed in and if not, default to DX12 build
+if "%~1"=="" (
+ set cmake_options=-DFFX_API_BACKEND=DX12_%arch% -DFFX_ALL=ON -DFFX_AUTO_COMPILE_SHADERS=1
+) else (
+ set cmake_options=%*
+)
+echo CMake options: %cmake_options%
+cmake .. %cmake_options%
+
+cmake --build ./ --config Debug --parallel 4 -- /p:CL_MPcount=16
+cmake --build ./ --config Release --parallel 4 -- /p:CL_MPcount=16
+cmake --build ./ --config RelWithDebInfo --parallel 4 -- /p:CL_MPcount=16
+
+cd ..
diff --git a/Kits/AMDTK/fidelityfx/BuildFidelityFXSDKSolutionDX12.bat b/Kits/AMDTK/fidelityfx/BuildFidelityFXSDKSolutionDX12.bat
new file mode 100644
index 00000000..9ebb384c
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/BuildFidelityFXSDKSolutionDX12.bat
@@ -0,0 +1,139 @@
+:: This file is part of the FidelityFX SDK.
+::
+:: Copyright (C) 2024 Advanced Micro Devices, Inc.
+::
+:: Permission is hereby granted, free of charge, to any person obtaining a copy
+:: of this software and associated documentation files(the "Software"), to deal
+:: in the Software without restriction, including without limitation the rights
+:: to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+:: copies of the Software, and to permit persons to whom the Software is
+:: furnished to do so, subject to the following conditions :
+::
+:: The above copyright notice and this permission notice shall be included in
+:: all copies or substantial portions of the Software.
+::
+:: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+:: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+:: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+:: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+:: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+:: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+:: THE SOFTWARE.
+
+@echo off
+setlocal enabledelayedexpansion
+
+echo ===============================================================
+echo.
+echo FidelityFX Build System
+echo.
+echo ===============================================================
+echo.
+
+set build_as_dll=
+set /P build_as_dll=Build the SDK as DLL [y/n]?
+
+set sdk_build_options=
+if /i "%build_as_dll%" == "Y" (
+ set sdk_build_options=-DFFX_BUILD_AS_DLL=1
+)
+
+set auto_compile_shaders=
+set /P auto_compile_shaders=Auto-compile shaders [y/n]?
+if /i "%auto_compile_shaders%" == "N" (
+ set auto_compile_shaders=-DFFX_AUTO_COMPILE_SHADERS=0
+) else (
+ set auto_compile_shaders=-DFFX_AUTO_COMPILE_SHADERS=1
+)
+
+ECHO 1. ALL
+ECHO 2. BLUR
+ECHO 3. BREADCRUMBS
+ECHO 4. BRIXELIZER
+ECHO 5. CACAO
+ECHO 6. CAS
+ECHO 7. CLASSIFIER
+ECHO 8. DENOISER
+ECHO 9. DOF
+ECHO 10. FSR 1
+ECHO 11. FSR 2
+ECHO 12. FSR 3
+ECHO 13. LENS
+ECHO 14. LPM
+ECHO 15. PARALLEL SORT
+ECHO 16. SPD
+ECHO 17. SSSR
+ECHO 18. VRS
+ECHO.
+
+set /P samples=Enter numbers of which effects to build [space delimitted]:
+:loop
+for /f "tokens=1*" %%a in ("%samples%") do (
+ if %%a == 1 set sdk_build_options=-DFFX_ALL=ON %sdk_build_options%
+ if %%a == 2 set sdk_build_options=-DFFX_BLUR=ON %sdk_build_options%
+ if %%a == 3 set sdk_build_options=-DFFX_BREADCRUMBS=ON %sdk_build_options%
+ if %%a == 4 set sdk_build_options=-DFFX_BRIXELIZER=ON %sdk_build_options%
+ if %%a == 5 set sdk_build_options=-DFFX_CACAO=ON %sdk_build_options%
+ if %%a == 6 set sdk_build_options=-DFFX_CAS=ON %sdk_build_options%
+ if %%a == 7 set sdk_build_options=-DFFX_CLASSIFIER=ON %sdk_build_options%
+ if %%a == 8 set sdk_build_options=-DFFX_DENOISER=ON %sdk_build_options%
+ if %%a == 9 set sdk_build_options=-DFFX_DOF=ON %sdk_build_options%
+ if %%a == 10 set sdk_build_options=-DFFX_FSR1=ON %sdk_build_options%
+ if %%a == 11 set sdk_build_options=-DFFX_FSR2=ON %sdk_build_options%
+ if %%a == 12 set sdk_build_options=-DFFX_FSR3=ON %sdk_build_options%
+ if %%a == 13 set sdk_build_options=-DFFX_LENS=ON %sdk_build_options%
+ if %%a == 14 set sdk_build_options=-DFFX_LPM=ON %sdk_build_options%
+ if %%a == 15 set sdk_build_options=-DFFX_PARALLEL_SORT=ON %sdk_build_options%
+ if %%a == 16 set sdk_build_options=-DFFX_SPD=ON %sdk_build_options%
+ if %%a == 17 set sdk_build_options=-DFFX_SSSR=ON -DFFX_DENOISER=ON %sdk_build_options%
+ if %%a == 18 set sdk_build_options=-DFFX_VRS=ON %sdk_build_options%
+ set samples=%%b
+)
+if defined samples goto :loop
+
+echo Checking pre-requisites...
+
+:: Check if cmake is installed
+cmake --version > nul 2>&1
+if %errorlevel% NEQ 0 (
+ echo Cannot find path to CMake. Is CMake installed? Exiting...
+ exit /b -1
+) else (
+ echo CMake Ready.
+)
+
+echo.
+echo Building FidelityFX SDK DX12 (Standalone) %sdk_build_options% %auto_compile_shaders%
+echo.
+
+:: Check directories exist and create if not
+if not exist build\ (
+ mkdir build
+)
+
+cd build
+
+:: Clear out CMakeCache
+if exist CMakeFiles\ (
+ rmdir /S /Q CMakeFiles
+)
+if exist CMakeCache.txt (
+ del /S /Q CMakeCache.txt
+)
+
+:: determine architecture
+echo.
+echo architecture %PROCESSOR_ARCHITECTURE% detected
+echo.
+if /i "%PROCESSOR_ARCHITECTURE%" == "ARM64" (
+ set arch=ARM64
+) else (
+ set arch=X64
+)
+
+cmake .. -DFFX_API_BACKEND=DX12_%arch% %sdk_build_options% %auto_compile_shaders%
+
+cd..
+
+:: Pause so the user can acknowledge any errors or other outputs from the build process
+pause
diff --git a/Kits/AMDTK/fidelityfx/BuildFidelityFXSDKSolutionVK.bat b/Kits/AMDTK/fidelityfx/BuildFidelityFXSDKSolutionVK.bat
new file mode 100644
index 00000000..3bdbcd55
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/BuildFidelityFXSDKSolutionVK.bat
@@ -0,0 +1,136 @@
+:: This file is part of the FidelityFX SDK.
+::
+:: Copyright (C) 2024 Advanced Micro Devices, Inc.
+::
+:: Permission is hereby granted, free of charge, to any person obtaining a copy
+:: of this software and associated documentation files(the "Software"), to deal
+:: in the Software without restriction, including without limitation the rights
+:: to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+:: copies of the Software, and to permit persons to whom the Software is
+:: furnished to do so, subject to the following conditions :
+::
+:: The above copyright notice and this permission notice shall be included in
+:: all copies or substantial portions of the Software.
+::
+:: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+:: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+:: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+:: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+:: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+:: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+:: THE SOFTWARE.
+
+@echo off
+setlocal enabledelayedexpansion
+
+echo ===============================================================
+echo.
+echo FidelityFX Build System
+echo.
+echo ===============================================================
+echo.
+
+set build_as_dll=
+set /P build_as_dll=Build the SDK as DLL [y/n]?
+
+set sdk_build_options=
+if /i "%build_as_dll%" == "Y" (
+ set sdk_build_options=-DFFX_BUILD_AS_DLL=1
+)
+
+set auto_compile_shaders=
+set /P auto_compile_shaders=Auto-compile shaders [y/n]?
+if /i "%auto_compile_shaders%" == "N" (
+ set auto_compile_shaders=-DFFX_AUTO_COMPILE_SHADERS=0
+) else (
+ set auto_compile_shaders=-DFFX_AUTO_COMPILE_SHADERS=1
+)
+
+ECHO 1. ALL
+ECHO 2. BLUR
+ECHO 3. BREADCRUMBS
+ECHO 4. BRIXELIZER
+ECHO 5. CACAO
+ECHO 6. CAS
+ECHO 7. CLASSIFIER
+ECHO 8. DENOISER
+ECHO 9. DOF
+ECHO 10. FSR 1
+ECHO 11. FSR 2
+ECHO 12. FSR 3
+ECHO 13. LENS
+ECHO 14. LPM
+ECHO 15. PARALLEL SORT
+ECHO 16. SPD
+ECHO 17. SSSR
+ECHO 18. VRS
+ECHO.
+
+set /P samples=Enter numbers of which effects to build [space delimitted]:
+:loop
+for /f "tokens=1*" %%a in ("%samples%") do (
+ if %%a == 1 set sdk_build_options=-DFFX_ALL=ON %sdk_build_options%
+ if %%a == 2 set sdk_build_options=-DFFX_BLUR=ON %sdk_build_options%
+ if %%a == 3 set sdk_build_options=-DFFX_BREADCRUMBS=ON %sdk_build_options%
+ if %%a == 4 set sdk_build_options=-DFFX_BRIXELIZER=ON %sdk_build_options%
+ if %%a == 5 set sdk_build_options=-DFFX_CACAO=ON %sdk_build_options%
+ if %%a == 6 set sdk_build_options=-DFFX_CAS=ON %sdk_build_options%
+ if %%a == 7 set sdk_build_options=-DFFX_CLASSIFIER=ON %sdk_build_options%
+ if %%a == 8 set sdk_build_options=-DFFX_DENOISER=ON %sdk_build_options%
+ if %%a == 9 set sdk_build_options=-DFFX_DOF=ON %sdk_build_options%
+ if %%a == 10 set sdk_build_options=-DFFX_FSR1=ON %sdk_build_options%
+ if %%a == 11 set sdk_build_options=-DFFX_FSR2=ON %sdk_build_options%
+ if %%a == 12 set sdk_build_options=-DFFX_FSR3=ON %sdk_build_options%
+ if %%a == 13 set sdk_build_options=-DFFX_LENS=ON %sdk_build_options%
+ if %%a == 14 set sdk_build_options=-DFFX_LPM=ON %sdk_build_options%
+ if %%a == 15 set sdk_build_options=-DFFX_PARALLEL_SORT=ON %sdk_build_options%
+ if %%a == 16 set sdk_build_options=-DFFX_SPD=ON %sdk_build_options%
+ if %%a == 17 set sdk_build_options=-DFFX_SSSR=ON -DFFX_DENOISER=ON %sdk_build_options%
+ if %%a == 18 set sdk_build_options=-DFFX_VRS=ON %sdk_build_options%
+ set samples=%%b
+)
+if defined samples goto :loop
+
+echo Checking pre-requisites...
+
+:: Check if cmake is installed
+cmake --version > nul 2>&1
+if %errorlevel% NEQ 0 (
+ echo Cannot find path to CMake. Is CMake installed? Exiting...
+ exit /b -1
+) else (
+ echo CMake Ready.
+)
+
+:: Check if VULKAN_SDK is installed but don't bail out
+if "%VULKAN_SDK%"=="" (
+ echo Vulkan SDK is not installed -Environment variable VULKAN_SDK is not defined- : Please install the latest Vulkan SDK from LunarG.
+) else (
+ echo Vulkan SDK - Ready : %VULKAN_SDK%
+)
+
+echo.
+echo Building FidelityFX SDK VK (Standalone) %sdk_build_options% %auto_compile_shaders%
+echo.
+
+:: Check directories exist and create if not
+if not exist build\ (
+ mkdir build
+)
+
+cd build
+
+:: Clear out CMakeCache
+if exist CMakeFiles\ (
+ rmdir /S /Q CMakeFiles
+)
+if exist CMakeCache.txt (
+ del /S /Q CMakeCache.txt
+)
+
+cmake .. -DFFX_API_BACKEND=VK_X64 %sdk_build_options% %auto_compile_shaders%
+
+cd..
+
+:: Pause so the user can acknowledge any errors or other outputs from the build process
+pause
diff --git a/Kits/AMDTK/fidelityfx/CMakeLists.txt b/Kits/AMDTK/fidelityfx/CMakeLists.txt
new file mode 100644
index 00000000..bfa13493
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/CMakeLists.txt
@@ -0,0 +1,271 @@
+# This file is part of the FidelityFX SDK.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files(the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions :
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+cmake_minimum_required(VERSION 3.23)
+
+if(POLICY CMP0147)
+ # parallel custom command builds (used for shader compilation)
+ cmake_policy(SET CMP0147 NEW)
+endif()
+
+# Clean a bit before
+unset(FFX_GDK CACHE)
+
+message(STATUS "FFX_API_BACKEND is ${FFX_API_BACKEND}")
+
+if(FFX_API_BACKEND STREQUAL VK_X64 OR
+ FFX_API_BACKEND STREQUAL DX12_X64 OR
+ FFX_API_BACKEND STREQUAL DX12_ARM64 OR
+ FFX_API_BACKEND STREQUAL DX12_ARM64EC OR
+ FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64 OR
+ FFX_API_BACKEND STREQUAL GDK_XBOXONE_X64)
+ set(FFX_CUSTOM_API OFF)
+else()
+ set(FFX_CUSTOM_API ON)
+endif()
+
+# Set configuration types based on what we are building for
+if (NOT FFX_CUSTOM_API)
+
+ # Are we buiding the GDK?
+ if (FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64 OR FFX_API_BACKEND STREQUAL GDK_XBOXONE_X64)
+ set(FFX_GDK ON)
+ endif()
+
+ # Pull in tool chain definitions
+ include(toolchain.cmake)
+
+ # If we are NOT building the GDK, queue up DX12/VK solution for building
+ if (NOT FFX_GDK)
+ if (FFX_API_BACKEND STREQUAL DX12_X64 OR
+ FFX_API_BACKEND STREQUAL DX12_ARM64 OR
+ FFX_API_BACKEND STREQUAL DX12_ARM64EC)
+ message(STATUS "Building FidelityFX SDK with DX12 backend")
+ elseif(FFX_API_BACKEND STREQUAL VK_X64)
+ message(STATUS "Building FidelityFX SDK with VK backend")
+ endif()
+ else()
+ # List the API we are building for
+ if(FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64)
+ message(STATUS "Building FidelityFX SDK with GDK Gaming.Scarlett.x64 backend")
+ elseif(FFX_API_BACKEND STREQUAL GDK_XBOXONE_X64)
+ message(STATUS "Building FidelityFX SDK with GDK Gaming.XboxOne.x64 backend")
+ else()
+ message(FATAL_ERROR "Requesting unsupported GDK build of FidelityFX SDK!")
+ endif()
+ endif()
+endif()
+
+# Set platform
+if(CMAKE_GENERATOR_PLATFORM STREQUAL "Gaming.Xbox.Scarlett.x64")
+ set(FFX_PLATFORM_NAME gdk_scarlett_x64)
+elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Gaming.Xbox.XboxOne.x64")
+ set(FFX_PLATFORM_NAME gdk_xboxone_x64)
+elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x64" OR CMAKE_EXE_LINKER_FLAGS STREQUAL "/machine:x64")
+ set(FFX_PLATFORM_NAME x64)
+elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32" OR CMAKE_EXE_LINKER_FLAGS STREQUAL "/machine:X86")
+ set(FFX_PLATFORM_NAME x86)
+elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "arm64" OR CMAKE_EXE_LINKER_FLAGS STREQUAL "/machine:ARM64")
+ set(FFX_PLATFORM_NAME arm64)
+elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "arm64ec" OR CMAKE_EXE_LINKER_FLAGS STREQUAL "/machine:ARM64EC")
+ set(FFX_PLATFORM_NAME arm64ec)
+else()
+ message(FATAL_ERROR "Unsupported target platform \"${CMAKE_GENERATOR_PLATFORM}\"")
+endif()
+
+# Pre-compile shaders
+set(FFX_AUTO_COMPILE_SHADERS ON CACHE BOOL "Compile shaders automatically as a prebuild step.")
+
+if(CMAKE_GENERATOR STREQUAL "Ninja")
+ set(USE_DEPFILE TRUE)
+else()
+ set(USE_DEPFILE FALSE)
+endif()
+
+# Set Visual Studio version
+if(CMAKE_GENERATOR STREQUAL "Visual Studio 14 2015")
+ set(FFX_VS_VERSION 2015)
+elseif(CMAKE_GENERATOR STREQUAL "Visual Studio 15 2017")
+ set(FFX_VS_VERSION 2017)
+elseif(CMAKE_GENERATOR STREQUAL "Visual Studio 16 2019")
+ set(FFX_VS_VERSION 2019)
+elseif(CMAKE_GENERATOR STREQUAL "Visual Studio 17 2022")
+ set(FFX_VS_VERSION 2022)
+endif()
+
+# Set configuration types based on what we are building for
+if (NOT FFX_CUSTOM_API)
+
+ # Embed PDBs in the debug versions of the libs
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7 /Od")
+
+ # Write debug, profile, and release versions of the static libs to the /bin folder as they are uniquely named
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+
+
+ if (FFX_BUILD_AS_DLL)
+ # Write both debug and release versions of the dlls to the /bin folder as they are uniquely named
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS FFX_BUILD_AS_DLL)
+ endif()
+else()
+
+ # Ouput the static libs to the /bin folder as they are uniquely named
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BIN_OUTPUT}/ffx_sdk)
+ foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
+ string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
+ set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${BIN_OUTPUT}/ffx_sdk/ )
+ if (FFX_BUILD_AS_DLL)
+ # Write both debug and release versions of the dlls to the /bin folder as they are uniquely named
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_HOME_DIRECTORY}/bin/ffx_sdk/)
+ endif()
+ endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
+
+endif()
+
+if (FFX_FSR3)
+ option(FFX_FSR3UPSCALER "Build FFX FSR3 Upscaler API" ON)
+ option(FFX_FI "Build FFX Frame Interpolation API" ON)
+ option(FFX_OF "Build FFX Optical Flow API" ON)
+endif()
+
+if (FFX_SSSR)
+ option(FFX_DENOISER "Build FFX Denoiser API" ON)
+endif()
+
+# Add requred compile definitions
+add_compile_definitions(_UNICODE)
+add_compile_definitions(UNICODE)
+add_compile_definitions(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)
+
+if(FFX_VS_VERSION STREQUAL 2015 OR FFX_VS_VERSION STREQUAL 2017)
+ message(NOTICE "Forcing the SDK path for VS 2015 and VS 2017")
+ set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION "10.0.18362.0")
+endif()
+
+# Setup common variables
+set(FFX_SC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/tools/binary_store/FidelityFX_SC.exe)
+set(FFX_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include)
+set(FFX_LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/libs)
+set(FFX_BIN_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/ffx_sdk)
+set(FFX_SHARED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/shared)
+set(FFX_HOST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include/FidelityFX/host)
+set(FFX_GPU_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include/FidelityFX/gpu)
+set(FFX_COMPONENTS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/components)
+set(FFX_HOST_BACKENDS_PATH ${FFX_HOST_PATH}/backends)
+set(FFX_SRC_BACKENDS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/backends)
+
+# ------------------------------------------------------
+# Define common source groupings used by all effects
+
+# Set shared and global public sources
+file(GLOB FFX_SHARED_SOURCES
+ "${FFX_SHARED_PATH}/*.cpp"
+ "${FFX_SHARED_PATH}/*.h")
+
+set(FFX_PUBLIC_SOURCES
+ "${FFX_HOST_PATH}/ffx_assert.h"
+ "${FFX_HOST_PATH}/ffx_message.h"
+ "${FFX_HOST_PATH}/ffx_error.h"
+ "${FFX_HOST_PATH}/ffx_fx.h"
+ "${FFX_HOST_PATH}/ffx_interface.h"
+ "${FFX_HOST_PATH}/ffx_types.h"
+ "${FFX_HOST_PATH}/ffx_util.h")
+
+# Init shader sources (for easy viewing)
+set(FFX_PUBLIC_SHADER_SOURCES
+ "${FFX_GPU_PATH}/ffx_common_types.h"
+ "${FFX_GPU_PATH}/ffx_core.h"
+ "${FFX_GPU_PATH}/ffx_core_cpu.h"
+ "${FFX_GPU_PATH}/ffx_core_glsl.h"
+ "${FFX_GPU_PATH}/ffx_core_gpu_common.h"
+ "${FFX_GPU_PATH}/ffx_core_gpu_common_half.h"
+ "${FFX_GPU_PATH}/ffx_core_hlsl.h"
+ "${FFX_GPU_PATH}/ffx_core_portability.h")
+
+if(FFX_API_BACKEND STREQUAL DX12_X64)
+ message(STATUS "Creating project FidelityFX-SDK_DX12_x64")
+ project(FidelityFX-SDK_DX12_x64)
+elseif(FFX_API_BACKEND STREQUAL DX12_ARM64)
+ message(STATUS "Creating project FidelityFX-SDK_DX12_arm64")
+ project (FidelityFX-SDK_DX12_arm64)
+elseif(FFX_API_BACKEND STREQUAL DX12_ARM64EC)
+ message(STATUS "Creating project FidelityFX-SDK_DX12_arm64ec")
+ project (FidelityFX-SDK_DX12_arm64ec)
+elseif (FFX_API_BACKEND STREQUAL VK_X64)
+ message(STATUS "Creating project FidelityFX-SDK_VK_x64")
+ project(FidelityFX-SDK_VK_x64)
+elseif(FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64)
+ message(STATUS "Creating project FidelityFX-SDK_GDK_Scarlett_x64")
+ project(FidelityFX-SDK_GDK_Scarlett_x64)
+elseif(FFX_API_BACKEND STREQUAL GDK_XBOXONE_X64)
+ message(STATUS "Creating project FidelityFX-SDK_GDK_XboxOne_x64")
+ project (FidelityFX-SDK_GDK_XboxOne_x64)
+else()
+ # This is likely a custom include
+ project (FidelityFX-SDK)
+endif()
+
+# Components
+add_subdirectory(${FFX_COMPONENTS_PATH}/opticalflow)
+add_subdirectory(${FFX_COMPONENTS_PATH}/frameinterpolation)
+add_subdirectory(${FFX_COMPONENTS_PATH}/fsr3)
+add_subdirectory(${FFX_COMPONENTS_PATH}/fsr3upscaler)
+add_subdirectory(${FFX_COMPONENTS_PATH}/fsr2)
+add_subdirectory(${FFX_COMPONENTS_PATH}/fsr1)
+add_subdirectory(${FFX_COMPONENTS_PATH}/spd)
+add_subdirectory(${FFX_COMPONENTS_PATH}/cacao)
+add_subdirectory(${FFX_COMPONENTS_PATH}/lpm)
+add_subdirectory(${FFX_COMPONENTS_PATH}/blur)
+add_subdirectory(${FFX_COMPONENTS_PATH}/vrs)
+add_subdirectory(${FFX_COMPONENTS_PATH}/cas)
+add_subdirectory(${FFX_COMPONENTS_PATH}/dof)
+add_subdirectory(${FFX_COMPONENTS_PATH}/lens)
+add_subdirectory(${FFX_COMPONENTS_PATH}/parallelsort)
+add_subdirectory(${FFX_COMPONENTS_PATH}/denoiser)
+add_subdirectory(${FFX_COMPONENTS_PATH}/sssr)
+add_subdirectory(${FFX_COMPONENTS_PATH}/brixelizer)
+add_subdirectory(${FFX_COMPONENTS_PATH}/brixelizergi)
+add_subdirectory(${FFX_COMPONENTS_PATH}/classifier)
+add_subdirectory(${FFX_COMPONENTS_PATH}/breadcrumbs)
+
+# Add appropriate graphics backend if requested
+if(FFX_API_BACKEND STREQUAL DX12_X64 OR
+ FFX_API_BACKEND STREQUAL DX12_ARM64 OR
+ FFX_API_BACKEND STREQUAL DX12_ARM64EC)
+ add_subdirectory(${FFX_LIB_PATH}/pix)
+ add_subdirectory(${FFX_SRC_BACKENDS_PATH}/dx12)
+endif()
+
+if (FFX_API_BACKEND STREQUAL VK_X64)
+ add_subdirectory(${FFX_SRC_BACKENDS_PATH}/vk)
+endif()
+
+if(FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64 OR FFX_API_BACKEND STREQUAL GDK_XBOXONE_X64)
+ add_subdirectory(${FFX_SRC_BACKENDS_PATH}/gdk)
+endif()
diff --git a/Kits/AMDTK/fidelityfx/LICENSE.txt b/Kits/AMDTK/fidelityfx/LICENSE.txt
new file mode 100644
index 00000000..3712e34a
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/LICENSE.txt
@@ -0,0 +1,21 @@
+This file is part of the FidelityFX SDK.
+
+Copyright (C) 2024 Advanced Micro Devices, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files(the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions :
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/CMakeCompileShaders.txt b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/CMakeCompileShaders.txt
new file mode 100644
index 00000000..ac1088d0
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/CMakeCompileShaders.txt
@@ -0,0 +1,141 @@
+# This file is part of the FidelityFX SDK.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files(the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions :
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+# Function to compile a set of shaders using the FidelityFX shader compiler driver.
+#
+# EXECUTABLE Path to the FidelityFX SC tool executable.
+# BASE_ARGS The base arguments for the compiler.
+# API_BASE_ARGS API (DX12 or Vulkan) specific base args.
+# PERMUTATION_ARGS Permutation set to compile for.
+# SHADER_FILES A list of shader files to compile using the permutation matrix expanded from SC_PERMUTATION_ARGS.
+# OUTPUT_PATH Path to store compiled shader output.
+#
+# Returns
+# A list of header files generated by the FidelityFX Shader Compiler driver.
+function(compile_shaders_with_depfile
+ EXECUTABLE BASE_ARGS API_BASE_ARGS
+ PERMUTATION_ARGS INCLUDES_ARGS
+ SHADER_FILES OUTPUT_PATH
+ PERMUTATION_OUTPUTS)
+
+ #message(STATUS "OUTPUT_PATH=${OUTPUT_PATH}")
+ #message(STATUS "EXE=${EXECUTABLE}")
+ #message(STATUS "BASE=${BASE_ARGS}")
+ #message(STATUS "API=${API_BASE_ARGS}")
+ #message(STATUS "PERMS=${PERMUTATION_ARGS}")
+ #message(STATUS "INCLUDES=${INCLUDES_ARGS}")
+ #message(STATUS "SHADER_FILES=${SHADER_FILES}")
+
+ # Figure out if this HLSL or GLSL
+ list(GET SHADER_FILES 0 FIRST_SHADER_FILE)
+ get_filename_component(SHADER_EXT "${FIRST_SHADER_FILE}" LAST_EXT)
+ string(TOUPPER "${SHADER_EXT}" SHADER_EXT)
+ set(INCLUDE_SPACE )
+ set(HLSL_WAVE64_ARGS )
+ set(HLSL_WAVE32_ARGS )
+ set(HLSL_16BIT_ARGS )
+ if (SHADER_EXT STREQUAL ".HLSL")
+ set(INCLUDE_SPACE " ")
+ set(HLSL_WAVE64_ARGS "-DFFX_PREFER_WAVE64=\"[WaveSize(64)]\"" "-DFFX_HLSL_SM=66" -T cs_6_6)
+ set(HLSL_WAVE32_ARGS "-DFFX_HLSL_SM=62" -T cs_6_2)
+ set(HLSL_16BIT_ARGS "-enable-16bit-types")
+ endif()
+ # GLSL requires no spaces: -I -I etc.
+ # HLSL requires spaces: -I -I etc.
+ set(COMPILE_INCLUDE_ARGS )
+ foreach(INC ${INCLUDES_ARGS})
+ list(APPEND COMPILE_INCLUDE_ARGS "-I${INCLUDE_SPACE}${INC}")
+ endforeach(INC)
+
+ if (FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64)
+ set(FFX_GDK_OPTION -compiler=gdk.desktop.x64)
+ elseif (FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64)
+ set(FFX_GDK_OPTION -compiler=gdk.scarlett.x64)
+ else()
+ set(FFX_GDK_OPTION )
+ endif()
+
+ foreach(PASS_SHADER ${SHADER_FILES})
+ get_filename_component(PASS_SHADER_FILENAME ${PASS_SHADER} NAME_WE)
+ get_filename_component(PASS_SHADER_TARGET ${PASS_SHADER} NAME_WLE)
+
+ set(WAVE32_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_permutations.h)
+ set(WAVE64_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_wave64_permutations.h)
+ set(WAVE32_16BIT_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_16bit_permutations.h)
+ set(WAVE64_16BIT_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_wave64_16bit_permutations.h)
+
+ # combine base and permutation args
+ set(SC_ARGS ${BASE_ARGS} ${API_BASE_ARGS} ${PERMUTATION_ARGS})
+
+ # Wave32
+ add_custom_command(
+ OUTPUT ${WAVE32_PERMUTATION_HEADER}
+ COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME} -DFFX_HALF=0 ${HLSL_WAVE32_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ DEPENDS ${PASS_SHADER}
+ DEPFILE ${WAVE32_PERMUTATION_HEADER}.d
+ )
+ list(APPEND PERMUTATION_OUTPUTS ${WAVE32_PERMUTATION_HEADER})
+
+ # Wave64
+ add_custom_command(
+ OUTPUT ${WAVE64_PERMUTATION_HEADER}
+ COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME}_wave64 -DFFX_HALF=0 ${HLSL_WAVE64_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ DEPENDS ${PASS_SHADER}
+ DEPFILE ${WAVE64_PERMUTATION_HEADER}.d
+ )
+ list(APPEND PERMUTATION_OUTPUTS ${WAVE64_PERMUTATION_HEADER})
+
+ # Wave32 16-bit
+ add_custom_command(
+ OUTPUT ${WAVE32_16BIT_PERMUTATION_HEADER}
+ COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME}_16bit -DFFX_HALF=1 ${HLSL_16BIT_ARGS} ${HLSL_WAVE32_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ DEPENDS ${PASS_SHADER}
+ DEPFILE ${WAVE32_16BIT_PERMUTATION_HEADER}.d
+ )
+ list(APPEND PERMUTATION_OUTPUTS ${WAVE32_16BIT_PERMUTATION_HEADER})
+
+ # Wave64 16-bit
+ add_custom_command(
+ OUTPUT ${WAVE64_16BIT_PERMUTATION_HEADER}
+ COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME}_wave64_16bit -DFFX_HALF=1 ${HLSL_16BIT_ARGS} ${HLSL_WAVE64_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ DEPENDS ${PASS_SHADER}
+ DEPFILE ${WAVE64_16BIT_PERMUTATION_HEADER}.d
+ )
+ list(APPEND PERMUTATION_OUTPUTS ${WAVE64_16BIT_PERMUTATION_HEADER})
+ endforeach(PASS_SHADER)
+
+ set(${PERMUTATION_OUTPUTS} ${PERMUTATION_OUTPUTS} PARENT_SCOPE)
+endfunction()
+
+# macro to add shader output files to a list for dependencies
+macro (add_shader_output)
+ foreach (_SHADER_SRC ${ARGN})
+ #message (STATUS ${_SHADER_SRC})
+ list (APPEND FFX_SC_PERMUTATION_OUTPUTS "${_SHADER_SRC}")
+ endforeach()
+
+ set (FFX_SC_PERMUTATION_OUTPUTS ${FFX_SC_PERMUTATION_OUTPUTS} PARENT_SCOPE)
+endmacro()
\ No newline at end of file
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/CMakeCompileBlurShaders.txt b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/CMakeCompileBlurShaders.txt
new file mode 100644
index 00000000..7fe0d7ae
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/CMakeCompileBlurShaders.txt
@@ -0,0 +1,48 @@
+# This file is part of the FidelityFX SDK.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files(the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions :
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+set(BLUR_BASE_ARGS
+ -reflection -deps=gcc -DFFX_GPU=1)
+
+set(BLUR_PERMUTATION_ARGS
+ -DFFX_BLUR_OPTION_KERNEL_DIMENSION={3,5,7,9,11,13,15,17,19,21}
+ -DFFX_BLUR_OPTION_KERNEL_PERMUTATION={0,1,2})
+
+set(BLUR_INCLUDE_ARGS
+ "${FFX_GPU_PATH}"
+ "${FFX_GPU_PATH}/blur")
+
+if (NOT BLUR_SHADER_EXT)
+ set(BLUR_SHADER_EXT *)
+endif()
+
+file(GLOB BLUR_SHADERS
+ "shaders/blur/ffx_blur_pass.${BLUR_SHADER_EXT}")
+
+# compile all the shaders
+compile_shaders_with_depfile(
+ "${FFX_SC_EXECUTABLE}"
+ "${BLUR_BASE_ARGS}" "${BLUR_API_BASE_ARGS}" "${BLUR_PERMUTATION_ARGS}" "${BLUR_INCLUDE_ARGS}"
+ "${BLUR_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" BLUR_PERMUTATION_OUTPUTS)
+
+# add the header files they generate to the main list of dependencies
+add_shader_output("${BLUR_PERMUTATION_OUTPUTS}")
\ No newline at end of file
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur.h
new file mode 100644
index 00000000..f982b99e
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur.h
@@ -0,0 +1,937 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFX_BLUR_H
+#define FFX_BLUR_H
+//_____________________________________________________________/\_______________________________________________________________
+//==============================================================================================================================
+//
+// [FFX BLUR] Blur
+//
+//==============================================================================================================================
+//
+/// @defgroup FfxGPUBlur FidelityFX BLUR
+/// FidelityFX Blur GPU documentation
+///
+/// @ingroup FfxGPUEffects
+
+//------------------------------------------------------------------------------------------------------------------------------
+//
+// ABOUT
+// =====
+// AMD FidelityFX Blur is a collection of blurring effects implemented on compute shaders, hand-optimized for maximum performance.
+// FFX-Blur includes
+// - Gaussian Blur w/ large kernel support (up to 21x21)
+//
+//==============================================================================================================================
+
+//==============================================================================================================================
+// BLUR SETUP
+//==============================================================================================================================
+
+
+/// FFX_BLUR_TILE_SIZE_Y: Tile Y dimensions that the local threadgroup will work on.
+/// Note: each threadgroup is responsible for blurring a tile of the input image.
+///
+/// @ingroup FfxGPUBlur
+#ifndef FFX_BLUR_TILE_SIZE_Y
+#define FFX_BLUR_TILE_SIZE_Y 8
+#endif
+
+/// FFX_BLUR_TILE_SIZE_X: Tile X dimensions that the local threadgroup will work on.
+/// Note: each threadgroup is responsible for blurring a tile of the input image.
+///
+/// @ingroup FfxGPUBlur
+#ifndef FFX_BLUR_TILE_SIZE_X
+#define FFX_BLUR_TILE_SIZE_X 8
+#endif
+
+/// FFX_BLUR_DISPATCH_Y: Y dimension of the Blur compute dispatch.
+/// The compute dispatch on the CPU side uses this value when invoking Dispatch.
+///
+/// @ingroup FfxGPUBlur
+#define FFX_BLUR_DISPATCH_Y 8
+
+#ifndef FFX_CPU
+
+/// FFX_BLUR_OPTION_KERNEL_DIMENSION needs to be defined by the client application
+/// App should define e.g the following for 5x5 blur:
+/// #define FFX_BLUR_OPTION_KERNEL_DIMENSION 5
+///
+/// @ingroup FfxGPUBlur
+#ifndef FFX_BLUR_OPTION_KERNEL_DIMENSION
+#error Please define FFX_BLUR_OPTION_KERNEL_DIMENSION
+#endif
+
+/// FFX_BLUR_KERNEL_RANGE is defined relative to FFX_BLUR_OPTION_KERNEL_DIMENSION
+/// See ffx_blur_callbacks_*.h for details.
+///
+/// @ingroup FfxGPUBlur
+#ifndef FFX_BLUR_KERNEL_RANGE
+#error Please define FFX_BLUR_KERNEL_RANGE
+#endif
+
+//--------------------------------------------------------------------------------------
+// BLUR CONFIG
+//--------------------------------------------------------------------------------------
+// hardcoded variants
+#define BLUR_DEBUG_PREFILL_OUTPUT_CACHE_WITH_COLOR 0
+#define BLUR_GROUPSHARED_MEMORY_SOA 0 // [Deprecated] improves LDS but too high traffic still
+#define BLUR_GROUPSHARED_MEMORY_HALF 0 // [Deprecated] LOTS of LDS traffic (1x ds_read per channel), need to pack with FfxUInt32
+#define BLUR_GROUPSHARED_MEMORY_PK_UINT 1 // 1x ds_read2st64_b32 for all three channels
+#define BLUR_FP16_KERNEL_LOOPS 1 // use fp16 for kernel loop counters and lds indexing (increases VGPR due to sdwa)
+#define BLUR_FP16_CLAMP 1 // ensure fp16 min/max is used for clamp()
+// cpu-driven variants
+#ifndef BLUR_ENABLE_INPUT_CACHE
+#define BLUR_ENABLE_INPUT_CACHE 0 // currently only slows the algorithm :(
+#endif
+#ifndef BLUR_DISABLE_CLAMP
+#define BLUR_DISABLE_CLAMP 0 // Generates incorrect image at the image borders (no clamp), for testing theoretical speed
+#endif
+#ifndef BLUR_OPTIMIZED_CLAMP
+#define BLUR_OPTIMIZED_CLAMP 0 // [Experimental] Testing a new optimized clamp ISA
+#endif
+
+// constants
+#define BLUR_TILE_SIZE_Y_INV (1.0 / FFX_BLUR_TILE_SIZE_Y)
+
+//--------------------------------------------------------------------------------------
+// GROUPSHARED MEMORY
+//--------------------------------------------------------------------------------------
+// Define CacheTypes
+#if BLUR_GROUPSHARED_MEMORY_SOA
+ #if BLUR_GROUPSHARED_MEMORY_HALF
+ #ifdef FFX_HLSL
+ #define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat16
+ #else
+ #define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat16
+ #endif
+ #else
+ #ifdef FFX_HLSL
+ #define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat32
+ #else
+ #define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat32
+ #endif
+ #endif
+#else // BLUR_GROUPSHARED_MEMORY_SOA
+ #if BLUR_GROUPSHARED_MEMORY_HALF
+ #ifdef FFX_HLSL
+ #define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat16x3
+ #else
+ #define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat16x3
+ #endif
+ #else
+ #ifdef FFX_HLSL
+ #define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat32x3
+ #else
+ #define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat32x3
+ #endif
+ #endif
+#endif // BLUR_GROUPSHARED_MEMORY_SOA
+
+//==============================================================================================================================
+// MATH HELPERS
+//==============================================================================================================================
+#define DIV_AND_ROUND_UP(x, y) (((x) + ((y)-1)) / ((y)))
+// Fast modulo operator for powers of two values for Y: x % y == x & (y-1)
+#define FAST_MOD(x, y) ((x) & (y - 1))
+#if FFX_HALF
+#define FAST_MOD16(x, y) ((x) & (y - FfxInt16(1)))
+#endif
+
+// OUTPUT CACHE ########################################
+/*
+# Notes from Jordan's Presentation
+src: https://gpuopen.com/gdc-presentations/2019/gdc-2019-s5-blend-of-gcn-optimization-and-color-processing.pdf
+Use 2^n tiles to use bitwise AND in place of the more ALU-expensive % operator, see #define FAST_MOD above
+MinTiles -> Ceil(HalfKernel / TileSize) * 2 + 1
+*/
+#if FFX_BLUR_OPTION_KERNEL_DIMENSION > 7
+#define NUM_TILES_OUTPUT_CACHE 8
+#else
+#define NUM_TILES_OUTPUT_CACHE 4
+#endif
+
+#define NUM_PIXELS_OUTPUT_CACHE (FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_TILE_SIZE_X * NUM_TILES_OUTPUT_CACHE)
+
+
+#if BLUR_GROUPSHARED_MEMORY_PK_UINT
+#ifdef FFX_HLSL
+ groupshared FfxUInt32 OutputCacheRG[NUM_PIXELS_OUTPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
+ groupshared FfxFloat32 OutputCacheB [NUM_PIXELS_OUTPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
+#else
+ shared FfxUInt32 OutputCacheRG[NUM_PIXELS_OUTPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
+ shared FfxFloat32 OutputCacheB [NUM_PIXELS_OUTPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
+#endif
+#else
+ #if BLUR_GROUPSHARED_MEMORY_SOA
+ BLUR_GROUPSHARED_MEMORY_TYPE OutputCache[NUM_PIXELS_OUTPUT_CACHE * 3]; // stores rrrrrr...ggggggg...bbbbb...
+ #else
+ BLUR_GROUPSHARED_MEMORY_TYPE OutputCache[NUM_PIXELS_OUTPUT_CACHE]; // stores rgbrgbrgbrgbrgbrgbrgbrgb...
+ #endif // BLUR_GROUPSHARED_MEMORY_SOA
+#endif // BLUR_GROUPSHARED_MEMORY_PK_UINT
+
+// Based on the FFX_BLUR_OPTION_KERNEL_DIMENSION, we will need to pre-fill a number of tiles.
+// e.g. TILE_SIZE_Y=8
+// -----------------------------------------
+// kernel = 3 | NUM_PREFILL_TILES_OUTPUT_CACHE = 1 |
+// kernel = 5 | NUM_PREFILL_TILES_OUTPUT_CACHE = 1 |
+// kernel = 7 | NUM_PREFILL_TILES_OUTPUT_CACHE = 1 |
+// kernel = 9* | NUM_PREFILL_TILES_OUTPUT_CACHE = 2*|
+// kernel = 11 | NUM_PREFILL_TILES_OUTPUT_CACHE = 2 |
+// kernel = 13 | NUM_PREFILL_TILES_OUTPUT_CACHE = 2 |
+// kernel = 15 | NUM_PREFILL_TILES_OUTPUT_CACHE = 2 |
+// kernel = 17*| NUM_PREFILL_TILES_OUTPUT_CACHE = 3*|
+// kernel = 19 | NUM_PREFILL_TILES_OUTPUT_CACHE = 3 |
+// kernel = 21 | NUM_PREFILL_TILES_OUTPUT_CACHE = 3 |
+// kernel = 23 | NUM_PREFILL_TILES_OUTPUT_CACHE = 3 |
+// -----------------------------------------
+#define NUM_PREFILL_TILES_OUTPUT_CACHE DIV_AND_ROUND_UP(FFX_BLUR_OPTION_KERNEL_DIMENSION, FFX_BLUR_TILE_SIZE_Y)
+
+
+// INPUT CACHE ########################################
+#if BLUR_ENABLE_INPUT_CACHE
+ #define INPUT_CACHE_TILE_SIZE_X (FFX_BLUR_TILE_SIZE_X + FFX_BLUR_OPTION_KERNEL_DIMENSION - 1)
+ #define NUM_TILES_INPUT_CACHE 1
+ #define NUM_PIXELS_INPUT_CACHE ((INPUT_CACHE_TILE_SIZE_X * FFX_BLUR_TILE_SIZE_Y) * NUM_TILES_INPUT_CACHE)
+
+ #if BLUR_GROUPSHARED_MEMORY_PK_UINT
+ #ifdef FFX_HLSL
+ groupshared FfxUInt32 InputCacheRG[NUM_PIXELS_INPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
+ groupshared FfxFloat32 InputCacheB [NUM_PIXELS_INPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
+ #else
+ shared FfxUInt32 InputCacheRG[NUM_PIXELS_INPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
+ shared FfxFloat32 InputCacheB [NUM_PIXELS_INPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
+ #endif
+ #else
+ #if BLUR_GROUPSHARED_MEMORY_SOA
+ BLUR_GROUPSHARED_MEMORY_TYPE InputCache[NUM_PIXELS_INPUT_CACHE * 3]; // stores rrrrrr...ggggggg...bbbbb...
+ #else
+ BLUR_GROUPSHARED_MEMORY_TYPE InputCache[NUM_PIXELS_INPUT_CACHE]; // stores rgbrgbrgbrgbrgbrgbrgbrgb...
+ #endif // BLUR_GROUPSHARED_MEMORY_SOA
+ #endif //BLUR_GROUPSHARED_MEMORY_PK_UINT
+#endif // BLUR_ENABLE_INPUT_CACHE
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//==============================================================================================================================
+// GROUPSHARED MEMORY MAPPING FUNCTIONS
+//==============================================================================================================================
+// LDS ops ----------------------------------------------------------------------------------
+// LDS TILES : FFX_BLUR_TILE_SIZE_X * FFX_BLUR_TILE_SIZE_Y sized tiles
+// e.g. FFX_BLUR_TILE_SIZE_X = 8
+//
+// <------------ FFX_BLUR_TILE_SIZE_X -------------->
+// ^ OutputCache[0-7]
+// | OutputCache[8-15]
+// |
+// | // TILE #1
+// |
+// |
+// v OutputCache[56-63]
+// <------------------------------------------------>
+// |
+// <------------ FFX_BLUR_TILE_SIZE_X -------------->
+// ^ OutputCache[64-71]
+// |
+// |
+// | // TILE #2
+// |
+// |
+// v
+// <------------------------------------------------>
+// |
+//...
+FfxUInt32 PackF2(FfxFloat32x2 c) { return (ffxF32ToF16(c.r) << 16) | ffxF32ToF16(c.g); }
+FfxFloat32x2 UnpackToF2(FfxUInt32 packedRG)
+{
+#ifdef FFX_HLSL
+ return f16tof32(FfxUInt32x2(packedRG >> 16, packedRG & 0xFFFF));
+#else
+ return unpackHalf2x16(packedRG).yx;
+#endif
+}
+#if FFX_HALF
+FfxUInt32 PackH2(FfxFloat16x2 c) { return (ffxF32ToF16(FfxFloat32(c.r)) << 16) | ffxF32ToF16(FfxFloat32(c.g)); } // TODO: is there a cast fp16->FfxUInt32 and skip fp16->fp32 promotion?
+FfxFloat16x2 UnpackToH2(FfxUInt32 packedRG){ return FfxFloat16x2(UnpackToF2(packedRG)); }
+#endif
+
+#ifdef FFX_HLSL
+inline FfxUInt32 FlattenIndex(FfxInt32x2 Index, FfxInt32 ElementStride)
+#else
+FfxUInt32 FlattenIndex(FfxInt32x2 Index, FfxInt32 ElementStride)
+#endif
+{
+ return Index.x + Index.y * ElementStride;
+}
+
+#if BLUR_GROUPSHARED_MEMORY_SOA
+ void SetOutputCache(FfxInt32x2 index, FfxFloat32x3 value)
+ {
+ FfxInt32 iLDS = index.x + index.y * BLUR_TILE_SIZE_X;
+ OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 0] = value.r;
+ OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 1] = value.g;
+ OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 2] = value.b;
+ }
+ FfxFloat32x3 GetOutputCache(FfxInt32x2 index)
+ {
+ FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
+ FfxFloat32x3 c;
+ c.r = OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 0];
+ c.g = OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 1];
+ c.b = OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 2];
+ return c;
+ }
+ #if BLUR_ENABLE_INPUT_CACHE
+ void SetInputCache(FfxInt32x2 index, FfxFloat32x3 value)
+ {
+ FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
+ InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 0] = value.r;
+ InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 1] = value.g;
+ InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 2] = value.b;
+ }
+ FfxFloat32x3 GetInputCache(FfxInt32x2 index)
+ {
+ FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
+ FfxFloat32x3 c;
+ c.r = InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 0];
+ c.g = InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 1];
+ c.b = InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 2];
+ return c;
+ }
+ #endif // BLUR_ENABLE_INPUT_CACHE
+#else
+ #if BLUR_GROUPSHARED_MEMORY_PK_UINT
+ #if FFX_HALF
+ void SetOutputCache(FfxInt32x2 index, FfxFloat16x3 value)
+ {
+ FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
+ OutputCacheRG[iLDS] = PackH2(value.rg);
+ OutputCacheB[iLDS] = value.b;
+ }
+ FfxFloat16x3 GetOutputCache(FfxInt32x2 index)
+ {
+ FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
+ FfxFloat16x2 RG = UnpackToH2(OutputCacheRG[iLDS]);
+ return FfxFloat16x3(RG.r, RG.g, OutputCacheB[iLDS]);
+ }
+ #else
+ void SetOutputCache(FfxInt32x2 index, FfxFloat32x3 value)
+ {
+ FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
+ OutputCacheRG[iLDS] = PackF2(value.rg);
+ OutputCacheB[iLDS] = value.b;
+ }
+ FfxFloat32x3 GetOutputCache(FfxInt32x2 index)
+ {
+ FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
+ FfxFloat32x2 RG = UnpackToF2(OutputCacheRG[iLDS]);
+ return FfxFloat32x3(RG.r, RG.g, OutputCacheB[iLDS]);
+ }
+ #endif // FFX_HALF
+ #else
+ #if FFX_HALF
+ void SetOutputCache(FfxInt32x2 index, FfxFloat16x3 value)
+ {
+ const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
+ OutputCache[iLDS] = value;
+ }
+ FfxFloat16x3 GetOutputCache(FfxInt32x2 index)
+ {
+ const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
+ return OutputCache[iLDS];
+ }
+ #else
+ void SetOutputCache(FfxInt32x2 index, FfxFloat32x3 value)
+ {
+ const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
+ OutputCache[iLDS] = value;
+ }
+ FfxFloat32x3 GetOutputCache(FfxInt32x2 index)
+ {
+ const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
+ return OutputCache[iLDS];
+ }
+ #endif // FFX_HALF
+ #endif // BLUR_GROUPSHARED_MEMORY_PK_UINT
+
+
+ #if BLUR_ENABLE_INPUT_CACHE
+ #if BLUR_GROUPSHARED_MEMORY_PK_UINT
+ #if FFX_HALF
+ void SetInputCache(FfxInt32x2 index, FfxFloat16x3 value)
+ {
+ FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
+ InputCacheRG[iLDS] = PackH2(value.rg);
+ InputCacheB[iLDS] = value.b;
+ }
+ FfxFloat16x3 GetInputCache(FfxInt32x2 index)
+ {
+ FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
+ FfxFloat16x2 RG = UnpackToH2(InputCacheRG[iLDS]);
+ return FfxFloat16x3(RG.r, RG.g, InputCacheB[iLDS]);
+ }
+ #else
+ void SetInputCache(FfxInt32x2 index, FfxFloat32x3 value)
+ {
+ //FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
+ FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
+ InputCacheRG[iLDS] = PackF2(value.rg);
+ InputCacheB[iLDS] = value.b;
+ }
+ FfxFloat32x3 GetInputCache(FfxInt32x2 index)
+ {
+ //FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
+ FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
+
+ FfxFloat32x2 RG = UnpackToF2(InputCacheRG[iLDS]);
+ return FfxFloat32x3(RG.r, RG.g, InputCacheB[iLDS]);
+ }
+ #endif // FFX_HALF
+ #else
+ void SetInputCache(FfxInt32x2 index, FfxFloat32x3 value) { InputCache[index.x + index.y * INPUT_CACHE_TILE_SIZE_X].rgb = value; }
+ FfxFloat32x3 GetInputCache(FfxInt32x2 index) { return InputCache[index.x + index.y * INPUT_CACHE_TILE_SIZE_X].rgb; }
+ #endif // BLUR_GROUPSHARED_MEMORY_PK_UINT
+ #endif // BLUR_ENABLE_INPUT_CACHE
+
+#endif // BLUR_GROUPSHARED_MEMORY_SOA
+
+
+void LDSBarrier()
+{
+ FFX_GROUP_MEMORY_BARRIER;
+}
+
+// index of the LDS tile in the ring buffer
+#if FFX_HALF
+ #if BLUR_FP16_KERNEL_LOOPS
+ FfxInt16 GetOutputCacheTile(FfxInt16 iTile) { return FAST_MOD16(iTile, FfxInt16(NUM_TILES_OUTPUT_CACHE)); }
+ void CacheInOutputTile(FfxInt32x2 threadID, FfxInt16 iTile, FfxFloat16x3 color)
+ {
+ FfxInt16 iLDSTile = GetOutputCacheTile(iTile);
+ FfxInt16x2 TileOffset = FfxInt16x2(0, FfxInt16(FFX_BLUR_TILE_SIZE_Y) * iLDSTile);
+ FfxInt16x2 iLDS = FfxInt16x2(threadID) + TileOffset;
+ SetOutputCache(iLDS, color);
+ }
+ FfxFloat16x3 LoadFromCachedOutputTile(FfxInt32x2 threadID, FfxInt16 iTile)
+ {
+ FfxInt16 iLDSTile = GetOutputCacheTile(iTile);
+ FfxInt16x2 TileOffset = FfxInt16x2(0, FfxInt16(FFX_BLUR_TILE_SIZE_Y) * iLDSTile);
+ FfxInt16x2 iLDS = FfxInt16x2(threadID) + TileOffset;
+ return GetOutputCache(iLDS);
+ }
+ #else // BLUR_FP16_KERNEL_LOOPS
+ FfxInt32 GetOutputCacheTile(FfxInt32 iTile) { return FAST_MOD(iTile, NUM_TILES_OUTPUT_CACHE); }
+ void CacheInOutputTile(FfxInt32x2 threadID, FfxInt32 iTile, FfxFloat16x3 color)
+ {
+ FfxInt32 iLDSTile = GetOutputCacheTile(iTile);
+ FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile);
+ FfxInt32x2 iLDS = threadID + TileOffset;
+ SetOutputCache(iLDS, color);
+ }
+ FfxFloat32x3 LoadFromCachedOutputTile(FfxInt32x2 threadID, FfxInt32 iTile)
+ {
+ FfxInt32 iLDSTile = GetOutputCacheTile(iTile);
+ FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile);
+ FfxInt32x2 iLDS = threadID + TileOffset;
+ return GetOutputCache(iLDS);
+ }
+ #endif // BLUR_FP16_KERNEL_LOOPS
+
+#else
+ FfxInt32 GetOutputCacheTile(FfxInt32 iTile) { return FAST_MOD(iTile, NUM_TILES_OUTPUT_CACHE); }
+ void CacheInOutputTile(FfxInt32x2 threadID, FfxInt32 iTile, FfxFloat32x3 color)
+ {
+ FfxInt32 iLDSTile = GetOutputCacheTile(iTile); // map image tile to LDS ring buffered tiles
+ FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile); // pixel offset for this tile
+ FfxInt32x2 iLDS = threadID + TileOffset; // 2D LDS coord based on local thread ID
+ SetOutputCache(iLDS, color);
+ }
+ FfxFloat32x3 LoadFromCachedOutputTile(FfxInt32x2 threadID, FfxInt32 iTile)
+ {
+ FfxInt32 iLDSTile = GetOutputCacheTile(iTile); // map image tile to LDS ring buffered tiles
+ FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile); // pixel offset for this tile
+ FfxInt32x2 iLDS = threadID + TileOffset; // 2D LDS coord based on local thread ID
+ return GetOutputCache(iLDS);
+ }
+#endif // FFX_HALF
+
+#if BLUR_ENABLE_INPUT_CACHE
+ #if FFX_HALF
+ void CacheInInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset, FfxFloat16x3 c)
+ #else
+ void CacheInInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset, FfxFloat32x3 c)
+ #endif
+ {
+ FfxInt32x2 InputCacheCoord = threadID + FfxInt32x2(KernelOffset, 0) + FfxInt32x2(FFX_BLUR_KERNEL_RANGE-1, 0);
+ SetInputCache(InputCacheCoord, c);
+ }
+
+ #if FFX_HALF
+ FfxFloat16x3 LoadFromCachedInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset)
+ #else
+ FfxFloat32x3 LoadFromCachedInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset)
+ #endif
+ {
+ FfxInt32x2 InputCacheCoord = threadID + FfxInt32x2(KernelOffset,0) + FfxInt32x2(FFX_BLUR_KERNEL_RANGE-1, 0);
+ return GetInputCache(InputCacheCoord);
+ }
+#endif // BLUR_ENABLE_INPUT_CACHE
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//==============================================================================================================================
+// BLUR FUNCTIONS
+//==============================================================================================================================
+#if FFX_HALF
+FfxFloat16x3 HorizontalBlurFromTexture(FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
+{
+#if BLUR_FP16_CLAMP // this uses 4 less VGPRs but not faster
+ const FfxInt16 ImageSizeClampValueX = FfxInt16(ImageSize.x - 1);
+ FfxFloat16x3 BlurredImage = BlurLoadInput(FfxInt16x2(CenterPixelLocation)) * BlurLoadKernelWeight(0);
+ for (FfxInt32 i = 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
+ {
+ FfxInt32x2 Offset = FfxInt32x2(i, 0);
+ FfxInt16x2 SampleCoordXX = FfxInt16x2(CenterPixelLocation.x + i, CenterPixelLocation.x - i);
+#if !BLUR_DISABLE_CLAMP
+ SampleCoordXX = clamp(SampleCoordXX, FfxInt16x2(0, 0), FfxInt16x2(ImageSizeClampValueX, ImageSizeClampValueX));
+#endif
+ BlurredImage += BlurLoadInput(FfxInt16x2(SampleCoordXX[0], CenterPixelLocation.y)) * BlurLoadKernelWeight(i);
+ BlurredImage += BlurLoadInput(FfxInt16x2(SampleCoordXX[1], CenterPixelLocation.y)) * BlurLoadKernelWeight(i);
+ }
+#else
+ FfxFloat16x3 BlurredImage = FfxFloat16x3(0.f, 0.f, 0.f);
+ for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
+ {
+ FfxInt32x2 SampleCoord = CenterPixelLocation + FfxInt32x2(i, 0); // horizontal blur
+#if !BLUR_DISABLE_CLAMP
+ SampleCoord.x = clamp(SampleCoord.x, 0, ImageSize.x-1); // clamp
+#endif
+ FfxFloat16x3 c = BlurLoadInput(SampleCoord);
+ BlurredImage += c * BlurLoadKernelWeight(abs(i));
+ }
+#endif // BLUR_FP16_CLAMP
+ return BlurredImage;
+}
+#else // FFX_HALF
+FfxFloat32x3 HorizontalBlurFromTexture(FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
+{
+ FfxFloat32x3 BlurredImage = FfxFloat32x3(0.f, 0.f, 0.f);
+ for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
+ {
+ FfxInt32x2 SampleCoord = CenterPixelLocation + FfxInt32x2(i, 0); // horizontal blur
+#if !BLUR_DISABLE_CLAMP
+ SampleCoord.x = clamp(SampleCoord.x, 0, ImageSize.x-1); // clamp
+#endif
+ FfxFloat32x3 c = BlurLoadInput(SampleCoord);
+ BlurredImage += c * BlurLoadKernelWeight(abs(i));
+ }
+ return BlurredImage;
+}
+#endif // FFX_HALF
+
+#if BLUR_ENABLE_INPUT_CACHE
+#if FFX_HALF
+FfxFloat16x3 HorizontalBlurFromCachedInput(FfxInt32x2 threadID)
+#else
+FfxFloat32x3 HorizontalBlurFromCachedInput(FfxInt32x2 threadID)
+#endif
+{
+ #if FFX_HALF
+ FfxFloat16x3 BlurredImage = FfxFloat16x3(0.f, 0.f, 0.f);
+ #else
+ FfxFloat32x3 BlurredImage = FfxFloat32x3(0.f, 0.f, 0.f);
+ #endif // FFX_HALF
+
+ for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
+ {
+ BlurredImage += LoadFromCachedInputTile(threadID, i) * BlurLoadKernelWeight(abs(i));
+ }
+ return BlurredImage;
+}
+#endif // BLUR_ENABLE_INPUT_CACHE
+
+#if FFX_HALF
+ #if BLUR_FP16_KERNEL_LOOPS
+ FfxFloat16x3 VerticalBlurFromCachedOutput(FfxInt32x2 ThreadID, FfxInt32x2 WorkGroupID,FfxInt16x2 CenterPixelLocation, FfxInt16x2 ImageSize)
+ {
+ const FfxInt16x2 ImageSizeClampValueXY = ImageSize.xy - FfxInt16x2(1, 1);
+ const FfxUInt32 iTileCount = DIV_AND_ROUND_UP(FfxUInt32(ImageSize.y), FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
+ FfxFloat16x3 value = FfxFloat16x3(0, 0, 0);
+ #ifndef FFX_HLSL
+ // For some reason using 16 bit integer for this loop in glsl does not work. It seems to be due to the use of
+ // a negative value as a starting value that is compared to a positive value, which seems to incorrectly cause
+ // the condition to always be false.
+ for (FfxInt32 i = (FfxInt32(-FFX_BLUR_KERNEL_RANGE) + FfxInt32(1)); i < FfxInt32(FFX_BLUR_KERNEL_RANGE); ++i)
+ #else
+ for (FfxInt16 i = (FfxInt16(-FFX_BLUR_KERNEL_RANGE) + FfxInt16(1)); i < FfxInt16(FFX_BLUR_KERNEL_RANGE); ++i)
+ #endif
+ {
+ FfxInt16x2 KernelSampleLocation = CenterPixelLocation + FfxInt16x2(0, i);
+#if !BLUR_DISABLE_CLAMP
+ KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, FfxInt16x2(0, 0), ImageSizeClampValueXY);
+#endif
+
+ const FfxInt16 iTile_ImageSpace = FfxInt16(KernelSampleLocation.y * BLUR_TILE_SIZE_Y_INV);
+ const FfxInt16 iTile = FfxInt16(iTile_ImageSpace - iTileCount * WorkGroupID.y);
+ FfxInt16x2 TileThreadID = FfxInt16x2(ThreadID.x, FAST_MOD16(KernelSampleLocation.y, FfxInt16(FFX_BLUR_TILE_SIZE_Y)));
+
+ FfxFloat16x3 c = LoadFromCachedOutputTile(TileThreadID, iTile);
+ value += c * BlurLoadKernelWeight(abs(i));
+ }
+ return value;
+ }
+ #else
+ FfxFloat16x3 VerticalBlurFromCachedOutput(FfxInt32x2 ThreadID, FfxInt32x2 WorkGroupID, FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
+ {
+ const FfxUInt32 iTileCount = DIV_AND_ROUND_UP(ImageSize.y, FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
+ FfxFloat16x3 value = FfxFloat16x3(0, 0, 0);
+ #if BLUR_FP16_CLAMP
+ const FfxInt16x2 ClampUpperLimitXY = ImageSize.xy - 1;
+ for (FfxInt16 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
+ {
+ FfxInt16x2 KernelSampleLocation = CenterPixelLocation + FfxInt16x2(0, i);
+#if !BLUR_DISABLE_CLAMP
+#if BLUR_OPTIMIZED_CLAMP
+ bool bNegative = firstbithigh(KernelSampleLocation.x) == 31;
+ KernelSampleLocation.y = bNegative ? 0 : KernelSampleLocation.y;
+#else
+ KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, FfxInt16x2(0, 0), ClampUpperLimitXY);
+#endif // BLUR_OPTIMIZED_CLAMP
+#endif
+ const FfxInt16 iTile_ImageSpace = FfxInt16(KernelSampleLocation.y * FFX_BLUR_TILE_SIZE_Y_INV);
+ const FfxInt16 iTile = iTile_ImageSpace - iTileCount * WorkGroupID.y;
+ FfxInt16x2 TileThreadID = FfxInt16x2(ThreadID.x, FAST_MOD16(KernelSampleLocation.y, FfxInt16(FFX_BLUR_TILE_SIZE_Y)));
+
+ FfxFloat16x3 c = LoadFromCachedOutputTile(TileThreadID, iTile);
+ value += c * BlurLoadKernelWeight(abs(i));
+ }
+ #else
+ for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
+ {
+ FfxInt32x2 KernelSampleLocation = CenterPixelLocation + FfxInt32x2(0, i);
+#if !BLUR_DISABLE_CLAMP
+#if BLUR_OPTIMIZED_CLAMP
+ bool bNegative = firstbithigh(KernelSampleLocation.x) == 31;
+ KernelSampleLocation.y = bNegative ? 0 : KernelSampleLocation.y;
+#else
+ KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, 0, ImageSize.xy-1);
+#endif // BLUR_OPTIMIZED_CLAMP
+#endif
+
+ const FfxInt32 iTile_ImageSpace = FfxInt32(KernelSampleLocation.y * FFX_BLUR_TILE_SIZE_Y_INV);
+ const FfxInt32 iTile = iTile_ImageSpace - (iTileCountPerWorkgroup * WorkGroupID.y);
+
+ FfxInt32x2 TileThreadID = FfxInt32x2(ThreadID.x, FAST_MOD(KernelSampleLocation.y, FFX_BLUR_TILE_SIZE_Y));
+
+ FfxFloat16x3 c = LoadFromCachedOutputTile(TileThreadID, iTile);
+ value += c * BlurLoadKernelWeight(abs(i));
+ }
+ #endif // BLUR_FP16_CLAMP
+ return value;
+ }
+ #endif // BLUR_FP16_KERNEL_LOOPS
+#else // FFX_HALF
+ FfxFloat32x3 VerticalBlurFromCachedOutput(FfxInt32x2 ThreadID, FfxInt32x2 WorkGroupID,FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
+ {
+ const FfxInt32 iTileCountPerWorkgroup = DIV_AND_ROUND_UP(ImageSize.y, FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
+
+ FfxFloat32x3 value = FfxFloat32x3(0,0,0);
+ for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
+ {
+ FfxInt32x2 KernelSampleLocation = CenterPixelLocation + FfxInt32x2(0, i);
+#if !BLUR_DISABLE_CLAMP
+ KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, FfxInt32x2(0, 0), ImageSize.xy-1);
+#endif
+
+ // which 'global' tile in the image space
+ const FfxInt32 iTile_ImageSpace = FfxInt32(KernelSampleLocation.y * BLUR_TILE_SIZE_Y_INV);
+
+ // local tile in this workgroup - apply the offset to convert to local space tile coordinates
+ // this is needed for workgroups that have WorkgroupID.y > 0: the previous workgroup's
+ // tile mapping doesn't have to align with the current one's depending on the FFX_BLUR_TILE_SIZE_XY.
+ // e.g. WorkGroupID=1's first tile will map to 0 in local space, but could be some non-0 index
+ // in the local space of the previous workgroup (WorkGroupID=0).
+ // Not correcting for this mapping will result in a chopped image on the workgroup borders.
+ const FfxInt32 iTile = iTile_ImageSpace - (iTileCountPerWorkgroup * WorkGroupID.y);
+
+ FfxInt32x2 TileThreadID = FfxInt32x2(ThreadID.x, FAST_MOD(KernelSampleLocation.y, FFX_BLUR_TILE_SIZE_Y));
+ //FfxInt32x2 TileThreadID = FfxInt32x2(ThreadID.x, KernelSampleLocation.y % BLUR_TILE_SIZE_Y);
+
+ value += LoadFromCachedOutputTile(TileThreadID, iTile) * BlurLoadKernelWeight(abs(i));
+ }
+ return value;
+ }
+#endif // FFX_HALF
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//==============================================================================================================================
+// INPUT/OUTPUT CACHE HELPERS
+//==============================================================================================================================
+//
+#if BLUR_ENABLE_INPUT_CACHE
+// Fills the input cache with the corresponding rgion from the image + kernel extents
+ void FillInputCache(in FfxInt32x2 lxy, FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
+ {
+#if FFX_HALF
+ FfxFloat16x3 c = FfxFloat16x3(0, 0, 0);
+#else
+ FfxFloat32x3 c = FfxFloat32x3(0, 0, 0);
+#endif
+
+ // slide the thread group over the InputCache
+ const FfxInt32 iNumLoops = DIV_AND_ROUND_UP(INPUT_CACHE_TILE_SIZE_X, FFX_BLUR_TILE_SIZE_X);
+ for (FfxInt32 i = 0; i < iNumLoops; ++i)
+ {
+ FfxInt32x2 LDSCoord = lxy - FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0) + FfxInt32x2(i * FFX_BLUR_TILE_SIZE_X, 0);
+ FfxInt32x2 SamplePosition = CenterPixelLocation - FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0) + FfxInt32x2(i * FFX_BLUR_TILE_SIZE_X, 0);
+#if !BLUR_DISABLE_CLAMP
+ SamplePosition.x = clamp(SamplePosition.x, 0, ImageSize.x - 1);
+#endif
+ c = BlurLoadInput(SamplePosition);
+
+ // clamp to LDS bounds if we're on the last iteration of the loop
+ if (i == iNumLoops - 1)
+ {
+ // faster than 'if (LDSCoord.x < INPUT_CACHE_TILE_SIZE_X)', avoids a vmem sync at the cost of some ALU
+ LDSCoord.x = clamp(LDSCoord.x, -FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0), (INPUT_CACHE_TILE_SIZE_X - 1) - FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0));
+ }
+ CacheInInputTile(LDSCoord, 0, c);
+ }
+ LDSBarrier();
+ }
+#endif // BLUR_ENABLE_INPUT_CACHE
+// Fills the output cache with the horizontally-blurred image.
+void PreFillOutputCache(in FfxInt32x2 gxy, in FfxInt32x2 lxy, in FfxInt32x2 WorkGroupID, FfxInt32x2 ImageSize)
+{
+#if BLUR_DEBUG_PREFILL_OUTPUT_CACHE_WITH_COLOR
+ FfxFloat32x3 FillColor = FfxFloat32x3(0, 0, 0); // black border color
+ [unroll]
+ for (FfxInt32 iTile = 0; iTile < NUM_TILES_OUTPUT_CACHE; ++iTile)
+ {
+ CacheInOutputTile(lxy, iTile, FillColor);
+ }
+ LDSBarrier();
+#endif
+
+ // load from VMEM the first NUM_PREFILL_TILES_OUTPUT_CACHE tiles
+ // while doing the horizontal blur, going top down
+#if FFX_HALF
+ for (FfxInt16 j = FfxInt16(0); j < FfxInt16(NUM_PREFILL_TILES_OUTPUT_CACHE); ++j)
+#else
+ for (FfxInt32 j = 0; j < NUM_PREFILL_TILES_OUTPUT_CACHE; ++j)
+#endif
+ {
+ const FfxInt32x2 ImageCoordinate = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * j);
+#if FFX_HALF
+ FfxFloat16x3 c = HorizontalBlurFromTexture(ImageCoordinate, ImageSize);
+#else
+ FfxFloat32x3 c = HorizontalBlurFromTexture(ImageCoordinate, ImageSize);
+#endif
+ CacheInOutputTile(lxy, j, c);
+ }
+
+#if FFX_BLUR_DISPATCH_Y != 1
+ // for any workgroup that doesn't start frop the top of the image,
+ // fill the cache from the tail, going upwards in the image space
+ if (WorkGroupID.y != 0)
+ {
+
+#if FFX_HALF
+ FfxFloat16x3 c = FfxFloat16x3(0, 0, 0);
+#else
+ FfxFloat32x3 c = FfxFloat32x3(0, 0, 0);
+#endif
+#if FFX_HALF
+ for (FfxInt16 j = FfxInt16(1); j < FfxInt16(NUM_PREFILL_TILES_OUTPUT_CACHE+1 + (DIV_AND_ROUND_UP(FFX_BLUR_KERNEL_RANGE, FFX_BLUR_TILE_SIZE_Y))); ++j)
+#else
+ for (FfxInt32 j = 1; j < NUM_PREFILL_TILES_OUTPUT_CACHE+1 + (DIV_AND_ROUND_UP(FFX_BLUR_KERNEL_RANGE, FFX_BLUR_TILE_SIZE_Y)); ++j)
+#endif
+ {
+ const FfxInt32x2 ImageCoordinate = gxy - FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * j);
+
+ #if BLUR_ENABLE_INPUT_CACHE
+ FillInputCache(lxy, ImageCoordinate, ImageSize);
+ c = HorizontalBlurFromCachedInput(lxy);
+ #else
+ c = HorizontalBlurFromTexture(ImageCoordinate, ImageSize);
+ #endif
+
+#if FFX_HALF
+ CacheInOutputTile(lxy, (FfxInt16(NUM_TILES_OUTPUT_CACHE) - j), c);
+#else
+ CacheInOutputTile(lxy, (NUM_TILES_OUTPUT_CACHE - j), c);
+#endif
+ }
+ }
+#endif
+
+ LDSBarrier(); // OutputCache Sync: Read -> Write =========================================
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//==============================================================================================================================
+// BLUR GAUSSIAN BLUR ALGORITHM
+//==============================================================================================================================
+
+/// ffxBlur: The main idea of the algorithm is to utilize a number of tiles (8x8) that are cached on the groupshared memory
+/// in a ring-buffer fashion to speed up texture lookups in a hand-optimized compute shader.
+/// The tiles are defined by the FFX_BLUR_TILE_SIZE_X and FFX_BLUR_TILE_SIZE_Y defines, and are typically 8x8 pixels.
+/// The image is horizontally blurred while being cached on the groupshared memory,
+/// and when all the groupshared tiles are filled, a vertical blur pass is done on the groupshared memory
+/// and the result is stored in the UAV as the final destination.
+///
+/// The algorithm is as follows:
+/// - Pre-fill LDS with 8x8 tiles, storing vertical tiles, containing horizontally blurred color
+/// - Loop until the entire image is covered:
+/// - Run a vertical blur pass on the LDS and output to final destination UAV
+/// - Re-fill LDS with horizontally-blurred data
+/// - Finish off the remaining last row/section of the image
+///
+/// @param [in] GlobalThreadID The SV_DispatchThreadID.xy or gl_GlobalInvocationID.xy.
+/// @param [in] WorkGroupLocalThreadID The SV_GroupThreadID.xy or gl_LocalInvocationID.xy.
+/// @param [in] WorkGroupID The SV_GroupID.xy or gl_WorkGroupID.xy.
+/// @param [in] ImageSize The two dimensional size of the input and output image.
+///
+/// @ingroup FfxGPUBlur
+void ffxBlur(
+ in FfxInt32x2 GlobalThreadID,
+ in FfxInt32x2 WorkGroupLocalThreadID,
+ in FfxInt32x2 WorkGroupID,
+ FfxInt32x2 ImageSize)
+{
+ // Each threadgroup processes a number of tiles of size FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_TILE_SIZE_X
+ // This number depends on the image height and the vertical dimension (_Y) of the FFX_BLUR_TILE_SIZE
+ //const FfxUInt32 iTileCount = DIV_AND_ROUND_UP(ImageSize.y, FFX_BLUR_TILE_SIZE_Y);
+ const FfxUInt32 iTileCount =
+ DIV_AND_ROUND_UP(
+ ImageSize.y,
+ FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
+
+ FfxInt32x2 gxy = FfxInt32x2(
+ WorkGroupID.x * FFX_BLUR_TILE_SIZE_X + WorkGroupLocalThreadID.x
+ , WorkGroupLocalThreadID.y + WorkGroupID.y * iTileCount * FFX_BLUR_TILE_SIZE_Y
+ );
+ FfxInt32x2 lxy = WorkGroupLocalThreadID;
+
+ if (gxy.x >= ImageSize.x)
+ return;
+
+ //-------------------------------------------------------------------------------------------------
+ // STEP #1
+ //-------------------------------------------------------------------------------------------------
+ // Pre-fill the output cache with a few tiles of horizontally blurred image.
+ // The tile count to pre-fill is a function of kernel width and TileSizeY.
+ PreFillOutputCache(gxy, lxy, WorkGroupID, ImageSize); // doesn't sync waves
+
+
+ //-------------------------------------------------------------------------------------------------
+ // STEP #2
+ //-------------------------------------------------------------------------------------------------
+ // loop through the tiles and write out to UAV as we go from top to down
+ FfxInt32 iTileOutput = 0;
+
+#if FFX_HALF
+ FfxFloat16x3 c = FfxFloat16x3(0, 0, 0);
+#else
+ FfxFloat32x3 c = FfxFloat32x3(0, 0, 0);
+#endif
+ for (; iTileOutput < iTileCount - NUM_PREFILL_TILES_OUTPUT_CACHE; ++iTileOutput)
+ {
+ // index of next tile that we'll cache the output to
+ // It runs ahead of the tile we will be writing out to UAV by NUM_PREFILL_TILES_OUTPUT_CACHE tiles
+ FfxInt32 iNextTileOutputCache = iTileOutput + NUM_PREFILL_TILES_OUTPUT_CACHE;
+ const FfxInt32x2 HorizontalBlurInputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iNextTileOutputCache);
+
+ // run horizontal blur & cache the next output tile
+ #if BLUR_ENABLE_INPUT_CACHE
+ FillInputCache(lxy, HorizontalBlurInputCoord, ImageSize);
+ c = HorizontalBlurFromCachedInput(lxy);
+ #else
+ // Number of image_load instructions will scale with FFX_BLUR_OPTION_KERNEL_DIMENSION.
+ c = HorizontalBlurFromTexture(HorizontalBlurInputCoord, ImageSize);
+ #endif // BLUR_ENABLE_INPUT_CACHE
+
+#if FFX_HALF
+ CacheInOutputTile(lxy, FfxInt16(iNextTileOutputCache), c);
+#else
+ CacheInOutputTile(lxy, iNextTileOutputCache, c);
+#endif
+
+ LDSBarrier(); // OutputCache Sync: Write -> Read =========================================
+
+ // Start writing out the pixel value which has its final value
+ // convolved from the pixels aready in the LDS section.
+ const FfxInt32x2 OutputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iTileOutput);
+#if FFX_HALF
+ c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, FfxInt16x2(OutputCoord), FfxInt16x2(ImageSize));
+#else
+ c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, OutputCoord, ImageSize);
+#endif
+ BlurStoreOutput(OutputCoord, c);
+ LDSBarrier(); // OutputCache Sync: Read -> Write =========================================
+ }
+
+
+ //-------------------------------------------------------------------------------------------------
+ // STEP #3
+ //-------------------------------------------------------------------------------------------------
+ // fill in the remaining last tiles (= loop for NUM_PREFILL_TILES_OUTPUT_CACHE)
+ for (; iTileOutput < iTileCount; ++iTileOutput)
+ {
+ const FfxInt32x2 OutputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iTileOutput);
+ if (iTileOutput >= iTileCount - NUM_PREFILL_TILES_OUTPUT_CACHE)
+ {
+ FfxInt32 iNextTileOutputCache = iTileOutput + NUM_PREFILL_TILES_OUTPUT_CACHE;
+ const FfxInt32x2 HorizontalBlurInputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iNextTileOutputCache);
+
+ // run horizontal blur & cache the next output tile
+#if BLUR_ENABLE_INPUT_CACHE
+ FillInputCache(lxy, HorizontalBlurInputCoord, ImageSize);
+ c = HorizontalBlurFromCachedInput(lxy);
+#else
+ // Number of image_load instructions will scale with FFX_BLUR_OPTION_KERNEL_DIMENSION.
+ c = HorizontalBlurFromTexture(HorizontalBlurInputCoord, ImageSize);
+#endif // BLUR_ENABLE_INPUT_CACHE
+
+#if FFX_HALF
+ CacheInOutputTile(lxy, FfxInt16(iNextTileOutputCache), c);
+#else
+ CacheInOutputTile(lxy, iNextTileOutputCache, c);
+#endif
+
+ LDSBarrier(); // OutputCache Sync: Write -> Read =========================================
+ }
+#if FFX_HALF
+ c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, FfxInt16x2(OutputCoord), FfxInt16x2(ImageSize));
+#else
+ c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, OutputCoord, ImageSize);
+#endif
+ BlurStoreOutput(OutputCoord, c);
+ }
+}
+
+#endif // !FFX_CPU
+#endif // FFX_BLUR_H
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_blur.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_blur.h
new file mode 100644
index 00000000..225fbe0f
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_blur.h
@@ -0,0 +1,65 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_core.h"
+
+FFX_BLUR_KERNEL_TYPE BlurLoadKernelWeight(FfxInt32 iKernelIndex)
+{
+ return FfxBlurLoadKernelWeight(iKernelIndex);
+}
+
+#if FFX_HALF
+
+void BlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat16x3 color)
+{
+ FfxBlurStoreOutput(outPxCoord, color);
+}
+
+FfxFloat16x3 BlurLoadInput(FfxInt16x2 inPxCoord)
+{
+ return FfxBlurLoadInput(inPxCoord);
+}
+
+#else // FFX_HALF
+
+void BlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color)
+{
+ FfxBlurStoreOutput(outPxCoord, color);
+}
+
+// DXIL generates load/sync/store blocks for each channel, ticket open: https://ontrack-internal.amd.com/browse/SWDEV-303837
+// this is 10x times slower!!!
+//void Blur_StoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color) { texColorOutput[outPxCoord].rgb = color; }
+FfxFloat32x3 BlurLoadInput(FfxInt32x2 inPxCoord)
+{
+ return FfxBlurLoadInput(inPxCoord);
+}
+
+#endif // !FFX_HALF
+
+#include "blur/ffx_blur.h"
+
+
+void ffxBlurPass(FfxInt32x2 DispatchThreadID, FfxInt32x2 LocalThreadId, FfxInt32x2 WorkGroupId)
+{
+ ffxBlur(DispatchThreadID, LocalThreadId, WorkGroupId, ImageSize());
+}
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_callbacks_glsl.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_callbacks_glsl.h
new file mode 100644
index 00000000..3f8bcd9b
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_callbacks_glsl.h
@@ -0,0 +1,216 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_blur_resources.h"
+
+#if defined(FFX_GPU)
+#include "ffx_core.h"
+
+#ifndef FFX_PREFER_WAVE64
+#define FFX_PREFER_WAVE64
+#endif // #if defined(FFX_PREFER_WAVE64)
+
+#pragma warning(disable: 3205) // conversion from larger type to smaller
+
+#if defined(FFX_BLUR_BIND_CB_BLUR)
+ layout (set = 0, binding = FFX_BLUR_BIND_CB_BLUR, std140) uniform cbBLUR_t
+ {
+ FfxInt32x2 imageSize;
+ } cbBLUR;
+#endif
+
+FfxInt32x2 ImageSize()
+{
+ return cbBLUR.imageSize;
+}
+
+// SRVs
+#if defined FFX_BLUR_BIND_SRV_INPUT_SRC
+ layout (set = 0, binding = FFX_BLUR_BIND_SRV_INPUT_SRC) uniform texture2D r_input_src;
+#endif
+
+// UAV declarations
+#if defined FFX_BLUR_BIND_UAV_OUTPUT
+ layout (set = 0, binding = FFX_BLUR_BIND_UAV_OUTPUT, rgba32f) uniform image2D rw_output;
+#endif
+
+// FFX_BLUR_OPTION_KERNEL_DIMENSION to be defined by the client application
+// App should define e.g the following for 5x5 blur:
+// #define FFX_BLUR_OPTION_KERNEL_DIMENSION 5
+#ifndef FFX_BLUR_OPTION_KERNEL_DIMENSION
+#error Please define FFX_BLUR_OPTION_KERNEL_DIMENSION
+#endif
+
+// FFX_BLUR_KERNEL_RANGE is center + half width of the kernel
+//
+// consider a blur kernel 5x5 - '*' indicates the center of the kernel
+// FFX_BLUR_OPTION_KERNEL_DIMENSION=5
+// |---------------|
+// x x x x x
+// x x x x x
+// x x x* x x
+// x x x x x
+// x x x x x
+//
+//
+// as separate 1D kernels
+//
+// x x x* x x
+// |-------|
+// FFX_BLUR_KERNEL_RANGE
+//
+#define FFX_BLUR_KERNEL_RANGE (((FFX_BLUR_OPTION_KERNEL_DIMENSION - 1) / 2) + 1)
+#define FFX_BLUR_KERNEL_RANGE_MINUS1 (FFX_BLUR_KERNEL_RANGE - 1)
+
+//
+// FFX-Blur Callback definitions
+//
+#if FFX_HALF
+#define FFX_BLUR_KERNEL_TYPE FfxFloat16
+#else
+#define FFX_BLUR_KERNEL_TYPE FfxFloat32
+#endif
+
+FFX_BLUR_KERNEL_TYPE FfxBlurLoadKernelWeight(FfxInt32 iKernelIndex)
+{
+// GAUSSIAN BLUR 1D KERNELS
+//
+//----------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------------------
+// Kernel Size: [3, 21]: odd numbers
+// Kernels are pregenerated using three different sigma values.
+// Larger sigmas are better for larger kernels.
+ const FFX_BLUR_KERNEL_TYPE kernel_weights[FFX_BLUR_KERNEL_RANGE] =
+#if FFX_BLUR_OPTION_KERNEL_PERMUTATION == 0
+// Sigma: 1.6
+#if FFX_BLUR_KERNEL_RANGE == 2
+ { FFX_BLUR_KERNEL_TYPE(0.3765770884), FFX_BLUR_KERNEL_TYPE(0.3117114558) };
+#elif FFX_BLUR_KERNEL_RANGE == 3
+ { FFX_BLUR_KERNEL_TYPE(0.2782163289), FFX_BLUR_KERNEL_TYPE(0.230293397), FFX_BLUR_KERNEL_TYPE(0.1305984385) };
+#elif FFX_BLUR_KERNEL_RANGE == 4
+ { FFX_BLUR_KERNEL_TYPE(0.2525903052), FFX_BLUR_KERNEL_TYPE(0.2090814714), FFX_BLUR_KERNEL_TYPE(0.1185692428), FFX_BLUR_KERNEL_TYPE(0.0460541333) };
+#elif FFX_BLUR_KERNEL_RANGE == 5
+ { FFX_BLUR_KERNEL_TYPE(0.2465514351), FFX_BLUR_KERNEL_TYPE(0.2040828004), FFX_BLUR_KERNEL_TYPE(0.115734517), FFX_BLUR_KERNEL_TYPE(0.0449530818), FFX_BLUR_KERNEL_TYPE(0.0119538834) };
+#elif FFX_BLUR_KERNEL_RANGE == 6
+ { FFX_BLUR_KERNEL_TYPE(0.245483563), FFX_BLUR_KERNEL_TYPE(0.2031988699), FFX_BLUR_KERNEL_TYPE(0.1152332436), FFX_BLUR_KERNEL_TYPE(0.0447583794), FFX_BLUR_KERNEL_TYPE(0.0119021083), FFX_BLUR_KERNEL_TYPE(0.0021656173) };
+#elif FFX_BLUR_KERNEL_RANGE == 7
+ { FFX_BLUR_KERNEL_TYPE(0.2453513488), FFX_BLUR_KERNEL_TYPE(0.2030894296), FFX_BLUR_KERNEL_TYPE(0.1151711805), FFX_BLUR_KERNEL_TYPE(0.0447342732), FFX_BLUR_KERNEL_TYPE(0.011895698), FFX_BLUR_KERNEL_TYPE(0.0021644509), FFX_BLUR_KERNEL_TYPE(0.0002692935) };
+#elif FFX_BLUR_KERNEL_RANGE == 8
+ { FFX_BLUR_KERNEL_TYPE(0.2453401155), FFX_BLUR_KERNEL_TYPE(0.2030801313), FFX_BLUR_KERNEL_TYPE(0.1151659074), FFX_BLUR_KERNEL_TYPE(0.044732225), FFX_BLUR_KERNEL_TYPE(0.0118951533), FFX_BLUR_KERNEL_TYPE(0.0021643518), FFX_BLUR_KERNEL_TYPE(0.0002692811), FFX_BLUR_KERNEL_TYPE(2.28922E-05) };
+#elif FFX_BLUR_KERNEL_RANGE == 9
+ { FFX_BLUR_KERNEL_TYPE(0.2453394635), FFX_BLUR_KERNEL_TYPE(0.2030795916), FFX_BLUR_KERNEL_TYPE(0.1151656014), FFX_BLUR_KERNEL_TYPE(0.0447321061), FFX_BLUR_KERNEL_TYPE(0.0118951217), FFX_BLUR_KERNEL_TYPE(0.0021643461), FFX_BLUR_KERNEL_TYPE(0.0002692804), FFX_BLUR_KERNEL_TYPE(2.28922E-05), FFX_BLUR_KERNEL_TYPE(1.3287E-06) };
+#elif FFX_BLUR_KERNEL_RANGE == 10
+ { FFX_BLUR_KERNEL_TYPE(0.2453394377), FFX_BLUR_KERNEL_TYPE(0.2030795703), FFX_BLUR_KERNEL_TYPE(0.1151655892), FFX_BLUR_KERNEL_TYPE(0.0447321014), FFX_BLUR_KERNEL_TYPE(0.0118951205), FFX_BLUR_KERNEL_TYPE(0.0021643458), FFX_BLUR_KERNEL_TYPE(0.0002692804), FFX_BLUR_KERNEL_TYPE(2.28922E-05), FFX_BLUR_KERNEL_TYPE(1.3287E-06), FFX_BLUR_KERNEL_TYPE(5.26E-08) };
+#elif FFX_BLUR_KERNEL_RANGE == 11
+ { FFX_BLUR_KERNEL_TYPE(0.2453394371), FFX_BLUR_KERNEL_TYPE(0.2030795697), FFX_BLUR_KERNEL_TYPE(0.1151655889), FFX_BLUR_KERNEL_TYPE(0.0447321013), FFX_BLUR_KERNEL_TYPE(0.0118951204), FFX_BLUR_KERNEL_TYPE(0.0021643458), FFX_BLUR_KERNEL_TYPE(0.0002692804), FFX_BLUR_KERNEL_TYPE(2.28922E-05), FFX_BLUR_KERNEL_TYPE(1.3287E-06), FFX_BLUR_KERNEL_TYPE(5.26E-08), FFX_BLUR_KERNEL_TYPE(1.4E-09) };
+#endif
+#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 1
+// Sigma: 2.8
+#if FFX_BLUR_KERNEL_RANGE == 2
+ { FFX_BLUR_KERNEL_TYPE(0.3474999743), FFX_BLUR_KERNEL_TYPE(0.3262500129) };
+#elif FFX_BLUR_KERNEL_RANGE == 3
+ { FFX_BLUR_KERNEL_TYPE(0.2256541468), FFX_BLUR_KERNEL_TYPE(0.2118551763), FFX_BLUR_KERNEL_TYPE(0.1753177504) };
+#elif FFX_BLUR_KERNEL_RANGE == 4
+ { FFX_BLUR_KERNEL_TYPE(0.1796953063), FFX_BLUR_KERNEL_TYPE(0.1687067636), FFX_BLUR_KERNEL_TYPE(0.1396108926), FFX_BLUR_KERNEL_TYPE(0.1018346906) };
+#elif FFX_BLUR_KERNEL_RANGE == 5
+ { FFX_BLUR_KERNEL_TYPE(0.1588894947), FFX_BLUR_KERNEL_TYPE(0.1491732476), FFX_BLUR_KERNEL_TYPE(0.1234462081), FFX_BLUR_KERNEL_TYPE(0.0900438796), FFX_BLUR_KERNEL_TYPE(0.0578919173) };
+#elif FFX_BLUR_KERNEL_RANGE == 6
+ { FFX_BLUR_KERNEL_TYPE(0.1491060676), FFX_BLUR_KERNEL_TYPE(0.1399880866), FFX_BLUR_KERNEL_TYPE(0.1158451582), FFX_BLUR_KERNEL_TYPE(0.0844995374), FFX_BLUR_KERNEL_TYPE(0.054327293), FFX_BLUR_KERNEL_TYPE(0.0307868909) };
+#elif FFX_BLUR_KERNEL_RANGE == 7
+ { FFX_BLUR_KERNEL_TYPE(0.1446570603), FFX_BLUR_KERNEL_TYPE(0.1358111404), FFX_BLUR_KERNEL_TYPE(0.1123885856), FFX_BLUR_KERNEL_TYPE(0.0819782513), FFX_BLUR_KERNEL_TYPE(0.0527062824), FFX_BLUR_KERNEL_TYPE(0.0298682757), FFX_BLUR_KERNEL_TYPE(0.0149189344) };
+#elif FFX_BLUR_KERNEL_RANGE == 8
+ { FFX_BLUR_KERNEL_TYPE(0.1427814521), FFX_BLUR_KERNEL_TYPE(0.1340502275), FFX_BLUR_KERNEL_TYPE(0.110931367), FFX_BLUR_KERNEL_TYPE(0.0809153299), FFX_BLUR_KERNEL_TYPE(0.0520228983), FFX_BLUR_KERNEL_TYPE(0.0294810068), FFX_BLUR_KERNEL_TYPE(0.0147254971), FFX_BLUR_KERNEL_TYPE(0.0064829474) };
+#elif FFX_BLUR_KERNEL_RANGE == 9
+ { FFX_BLUR_KERNEL_TYPE(0.1420666821), FFX_BLUR_KERNEL_TYPE(0.1333791663), FFX_BLUR_KERNEL_TYPE(0.1103760399), FFX_BLUR_KERNEL_TYPE(0.0805102644), FFX_BLUR_KERNEL_TYPE(0.0517624694), FFX_BLUR_KERNEL_TYPE(0.0293334236), FFX_BLUR_KERNEL_TYPE(0.0146517806), FFX_BLUR_KERNEL_TYPE(0.0064504935), FFX_BLUR_KERNEL_TYPE(0.0025030212) };
+#elif FFX_BLUR_KERNEL_RANGE == 10
+ { FFX_BLUR_KERNEL_TYPE(0.1418238658), FFX_BLUR_KERNEL_TYPE(0.1331511984), FFX_BLUR_KERNEL_TYPE(0.1101873883), FFX_BLUR_KERNEL_TYPE(0.0803726585), FFX_BLUR_KERNEL_TYPE(0.0516739985), FFX_BLUR_KERNEL_TYPE(0.0292832877), FFX_BLUR_KERNEL_TYPE(0.0146267382), FFX_BLUR_KERNEL_TYPE(0.0064394685), FFX_BLUR_KERNEL_TYPE(0.0024987432), FFX_BLUR_KERNEL_TYPE(0.0008545858) };
+#elif FFX_BLUR_KERNEL_RANGE == 11
+ { FFX_BLUR_KERNEL_TYPE(0.1417508359), FFX_BLUR_KERNEL_TYPE(0.1330826344), FFX_BLUR_KERNEL_TYPE(0.1101306491), FFX_BLUR_KERNEL_TYPE(0.0803312719), FFX_BLUR_KERNEL_TYPE(0.0516473898), FFX_BLUR_KERNEL_TYPE(0.0292682088), FFX_BLUR_KERNEL_TYPE(0.0146192064), FFX_BLUR_KERNEL_TYPE(0.0064361526), FFX_BLUR_KERNEL_TYPE(0.0024974565), FFX_BLUR_KERNEL_TYPE(0.0008541457), FFX_BLUR_KERNEL_TYPE(0.0002574667) };
+#endif
+#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 2
+// Sigma: 4
+#if FFX_BLUR_KERNEL_RANGE == 2
+ { FFX_BLUR_KERNEL_TYPE(0.3402771036), FFX_BLUR_KERNEL_TYPE(0.3298614482) };
+#elif FFX_BLUR_KERNEL_RANGE == 3
+ { FFX_BLUR_KERNEL_TYPE(0.2125433723), FFX_BLUR_KERNEL_TYPE(0.2060375614), FFX_BLUR_KERNEL_TYPE(0.1876907525) };
+#elif FFX_BLUR_KERNEL_RANGE == 4
+ { FFX_BLUR_KERNEL_TYPE(0.1608542243), FFX_BLUR_KERNEL_TYPE(0.1559305837), FFX_BLUR_KERNEL_TYPE(0.1420455978), FFX_BLUR_KERNEL_TYPE(0.1215967064) };
+#elif FFX_BLUR_KERNEL_RANGE == 5
+ { FFX_BLUR_KERNEL_TYPE(0.1345347233), FFX_BLUR_KERNEL_TYPE(0.1304167051), FFX_BLUR_KERNEL_TYPE(0.1188036266), FFX_BLUR_KERNEL_TYPE(0.1017006505), FFX_BLUR_KERNEL_TYPE(0.0818116562) };
+#elif FFX_BLUR_KERNEL_RANGE == 6
+ { FFX_BLUR_KERNEL_TYPE(0.1197258568), FFX_BLUR_KERNEL_TYPE(0.1160611281), FFX_BLUR_KERNEL_TYPE(0.1057263555), FFX_BLUR_KERNEL_TYPE(0.090505984), FFX_BLUR_KERNEL_TYPE(0.0728062644), FFX_BLUR_KERNEL_TYPE(0.0550373395) };
+#elif FFX_BLUR_KERNEL_RANGE == 7
+ { FFX_BLUR_KERNEL_TYPE(0.1110429695), FFX_BLUR_KERNEL_TYPE(0.1076440182), FFX_BLUR_KERNEL_TYPE(0.0980587551), FFX_BLUR_KERNEL_TYPE(0.0839422118), FFX_BLUR_KERNEL_TYPE(0.0675261302), FFX_BLUR_KERNEL_TYPE(0.0510458624), FFX_BLUR_KERNEL_TYPE(0.0362615375) };
+#elif FFX_BLUR_KERNEL_RANGE == 8
+ { FFX_BLUR_KERNEL_TYPE(0.1059153311), FFX_BLUR_KERNEL_TYPE(0.1026733334), FFX_BLUR_KERNEL_TYPE(0.0935306896), FFX_BLUR_KERNEL_TYPE(0.0800660068), FFX_BLUR_KERNEL_TYPE(0.0644079717), FFX_BLUR_KERNEL_TYPE(0.0486887143), FFX_BLUR_KERNEL_TYPE(0.0345870861), FFX_BLUR_KERNEL_TYPE(0.0230885324) };
+#elif FFX_BLUR_KERNEL_RANGE == 9
+ { FFX_BLUR_KERNEL_TYPE(0.1029336421), FFX_BLUR_KERNEL_TYPE(0.0997829119), FFX_BLUR_KERNEL_TYPE(0.0908976484), FFX_BLUR_KERNEL_TYPE(0.0778120183), FFX_BLUR_KERNEL_TYPE(0.0625947824), FFX_BLUR_KERNEL_TYPE(0.0473180477), FFX_BLUR_KERNEL_TYPE(0.0336134033), FFX_BLUR_KERNEL_TYPE(0.0224385526), FFX_BLUR_KERNEL_TYPE(0.0140758142) };
+#elif FFX_BLUR_KERNEL_RANGE == 10
+ { FFX_BLUR_KERNEL_TYPE(0.1012533395), FFX_BLUR_KERNEL_TYPE(0.0981540422), FFX_BLUR_KERNEL_TYPE(0.089413823), FFX_BLUR_KERNEL_TYPE(0.0765418045), FFX_BLUR_KERNEL_TYPE(0.0615729768), FFX_BLUR_KERNEL_TYPE(0.0465456216), FFX_BLUR_KERNEL_TYPE(0.0330646936), FFX_BLUR_KERNEL_TYPE(0.0220722627), FFX_BLUR_KERNEL_TYPE(0.0138460388), FFX_BLUR_KERNEL_TYPE(0.0081620671) };
+#elif FFX_BLUR_KERNEL_RANGE == 11
+ { FFX_BLUR_KERNEL_TYPE(0.1003459368), FFX_BLUR_KERNEL_TYPE(0.0972744146), FFX_BLUR_KERNEL_TYPE(0.0886125226), FFX_BLUR_KERNEL_TYPE(0.0758558594), FFX_BLUR_KERNEL_TYPE(0.0610211779), FFX_BLUR_KERNEL_TYPE(0.0461284934), FFX_BLUR_KERNEL_TYPE(0.0327683775), FFX_BLUR_KERNEL_TYPE(0.0218744576), FFX_BLUR_KERNEL_TYPE(0.0137219546), FFX_BLUR_KERNEL_TYPE(0.008088921), FFX_BLUR_KERNEL_TYPE(0.0044808529) };
+#endif
+#else
+#error FFX_BLUR_OPTION_KERNEL_PERMUTATION is not a valid value.
+#endif // FFX_BLUR_OPTION_KERNEL_PERMUTATIONs
+
+ return kernel_weights[iKernelIndex];
+}
+
+#if FFX_HALF
+
+#if defined (FFX_BLUR_BIND_UAV_OUTPUT)
+void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat16x3 color)
+{
+ imageStore(rw_output, outPxCoord, FfxFloat16x4(color, 1));
+}
+#endif // #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
+
+#if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
+FfxFloat16x3 FfxBlurLoadInput(FfxInt16x2 inPxCoord)
+{
+ return FfxFloat16x3(texelFetch(r_input_src, inPxCoord, 0).rgb);
+}
+#endif // #if defined FFX_BLUR_BIND_SRV_INPUT_SRC
+
+#else // FFX_HALF
+
+#if defined (FFX_BLUR_BIND_UAV_OUTPUT)
+void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color)
+{
+ imageStore(rw_output, outPxCoord, FfxFloat32x4(color, 1));
+}
+#endif // #if defined FFX_BLUR_BIND_UAV_OUTPUT
+
+// DXIL generates load/sync/store blocks for each channel, ticket open: https://ontrack-internal.amd.com/browse/SWDEV-303837
+// this is 10x times slower!!!
+//void Blur_StoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color) { texColorOutput[outPxCoord].rgb = color; }
+#if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
+FfxFloat32x3 FfxBlurLoadInput(FfxInt32x2 inPxCoord)
+{
+ return texelFetch(r_input_src, inPxCoord, 0).rgb;
+}
+#endif // #if defined FFX_BLUR_BIND_SRV_INPUT_SRC
+
+#endif // !FFX_HALF
+
+#endif // #if defined(FFX_GPU)
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_callbacks_hlsl.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_callbacks_hlsl.h
new file mode 100644
index 00000000..f74c42ff
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_callbacks_hlsl.h
@@ -0,0 +1,254 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ffx_blur_resources.h"
+
+#if defined(FFX_GPU)
+
+#ifdef __hlsl_dx_compiler
+#pragma dxc diagnostic push
+#pragma dxc diagnostic ignored "-Wambig-lit-shift"
+#endif //__hlsl_dx_compiler
+
+#include "ffx_core.h"
+
+#ifdef __hlsl_dx_compiler
+#pragma dxc diagnostic pop
+#endif //__hlsl_dx_compiler
+
+#ifndef FFX_PREFER_WAVE64
+#define FFX_PREFER_WAVE64
+#endif // #ifndef FFX_PREFER_WAVE64
+
+#if defined(FFX_GPU)
+#pragma warning(disable: 3205) // conversion from larger type to smaller
+#endif // #if defined(FFX_GPU)
+
+#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
+#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
+#define DECLARE_CB_REGISTER(regIndex) b##regIndex
+#define FFX_BLUR_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
+#define FFX_BLUR_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
+#define FFX_BLUR_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
+
+#if defined(FFX_BLUR_BIND_CB_BLUR)
+ cbuffer cbBLUR : FFX_BLUR_DECLARE_CB(FFX_BLUR_BIND_CB_BLUR)
+ {
+ FfxInt32x2 imageSize;
+ #define FFX_BLUR_CONSTANT_BUFFER_1_SIZE 2 // Number of 32-bit values. This must be kept in sync with the cbBLUR size.
+ };
+#else
+ #define imageSize 0
+#endif
+
+#define FFX_BLUR_ROOTSIG_STRINGIFY(p) FFX_BLUR_ROOTSIG_STR(p)
+#define FFX_BLUR_ROOTSIG_STR(p) #p
+#define FFX_BLUR_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_BLUR_ROOTSIG_STRINGIFY(FFX_BLUR_RESOURCE_IDENTIFIER_COUNT) ")), " \
+ "DescriptorTable(SRV(t0, numDescriptors = " FFX_BLUR_ROOTSIG_STRINGIFY(FFX_BLUR_RESOURCE_IDENTIFIER_COUNT) ")), " \
+ "CBV(b0)" )]
+
+#if defined(FFX_BLUR_EMBED_ROOTSIG)
+#define FFX_BLUR_EMBED_ROOTSIG_CONTENT FFX_BLUR_ROOTSIG
+#else
+#define FFX_BLUR_EMBED_ROOTSIG_CONTENT
+#endif // #if FFX_BLUR_EMBED_ROOTSIG
+
+FfxInt32x2 ImageSize()
+{
+ return imageSize;
+}
+
+// SRVs
+#if defined FFX_BLUR_BIND_SRV_INPUT_SRC
+ #if FFX_HALF
+ Texture2D r_input_src : FFX_BLUR_DECLARE_SRV(FFX_BLUR_BIND_SRV_INPUT_SRC);
+ #else
+ Texture2D r_input_src : FFX_BLUR_DECLARE_SRV(FFX_BLUR_BIND_SRV_INPUT_SRC);
+ #endif // FFX_HALF
+#endif
+
+ // UAV declarations
+#if defined FFX_BLUR_BIND_UAV_OUTPUT
+ #if FFX_HALF
+ RWTexture2D rw_output : FFX_BLUR_DECLARE_UAV(FFX_BLUR_BIND_UAV_OUTPUT);
+ #else
+ RWTexture2D rw_output : FFX_BLUR_DECLARE_UAV(FFX_BLUR_BIND_UAV_OUTPUT);
+ #endif // FFX_HALF
+#endif
+
+// FFX_BLUR_OPTION_KERNEL_DIMENSION to be defined by the client application
+// App should define e.g the following for 5x5 blur:
+// #define FFX_BLUR_OPTION_KERNEL_DIMENSION 5
+#ifndef FFX_BLUR_OPTION_KERNEL_DIMENSION
+#error Please define FFX_BLUR_OPTION_KERNEL_DIMENSION
+#endif
+
+// FFX_BLUR_KERNEL_RANGE is center + half width of the kernel
+//
+// consider a blur kernel 5x5 - '*' indicates the center of the kernel
+// FFX_BLUR_OPTION_KERNEL_DIMENSION=5
+// |---------------|
+// x x x x x
+// x x x x x
+// x x x* x x
+// x x x x x
+// x x x x x
+//
+//
+// as separate 1D kernels
+//
+// x x x* x x
+// |-------|
+// FFX_BLUR_KERNEL_RANGE
+//
+#define FFX_BLUR_KERNEL_RANGE (((FFX_BLUR_OPTION_KERNEL_DIMENSION - 1) / 2) + 1)
+#define FFX_BLUR_KERNEL_RANGE_MINUS1 (FFX_BLUR_KERNEL_RANGE - 1)
+
+//
+// FFX-Blur Callback definitions
+//
+#if FFX_HALF
+ #define FFX_BLUR_KERNEL_TYPE FfxFloat16
+#else
+ #define FFX_BLUR_KERNEL_TYPE FfxFloat32
+#endif
+
+inline FFX_BLUR_KERNEL_TYPE FfxBlurLoadKernelWeight(FfxInt32 iKernelIndex)
+{
+// GAUSSIAN BLUR 1D KERNELS
+//
+//----------------------------------------------------------------------------------------------------------------------------------
+// Kernel Size: [3, 21]: odd numbers
+// Kernels are pregenerated using three different sigma values.
+// Larger sigmas are better for larger kernels.
+ const FFX_BLUR_KERNEL_TYPE kernel_weights[FFX_BLUR_KERNEL_RANGE] =
+#if FFX_BLUR_OPTION_KERNEL_PERMUTATION == 0
+// Sigma: 1.6
+#if FFX_BLUR_KERNEL_RANGE == 2
+ { 0.3765770884, 0.3117114558 };
+#elif FFX_BLUR_KERNEL_RANGE == 3
+ { 0.2782163289, 0.230293397, 0.1305984385 };
+#elif FFX_BLUR_KERNEL_RANGE == 4
+ { 0.2525903052, 0.2090814714, 0.1185692428, 0.0460541333 };
+#elif FFX_BLUR_KERNEL_RANGE == 5
+ { 0.2465514351, 0.2040828004, 0.115734517, 0.0449530818, 0.0119538834 };
+#elif FFX_BLUR_KERNEL_RANGE == 6
+ { 0.245483563, 0.2031988699, 0.1152332436, 0.0447583794, 0.0119021083, 0.0021656173 };
+#elif FFX_BLUR_KERNEL_RANGE == 7
+ { 0.2453513488, 0.2030894296, 0.1151711805, 0.0447342732, 0.011895698, 0.0021644509, 0.0002692935 };
+#elif FFX_BLUR_KERNEL_RANGE == 8
+ { 0.2453401155, 0.2030801313, 0.1151659074, 0.044732225, 0.0118951533, 0.0021643518, 0.0002692811, 2.28922E-05 };
+#elif FFX_BLUR_KERNEL_RANGE == 9
+ { 0.2453394635, 0.2030795916, 0.1151656014, 0.0447321061, 0.0118951217, 0.0021643461, 0.0002692804, 2.28922E-05, 1.3287E-06 };
+#elif FFX_BLUR_KERNEL_RANGE == 10
+ { 0.2453394377, 0.2030795703, 0.1151655892, 0.0447321014, 0.0118951205, 0.0021643458, 0.0002692804, 2.28922E-05, 1.3287E-06, 5.26E-08 };
+#elif FFX_BLUR_KERNEL_RANGE == 11
+ { 0.2453394371, 0.2030795697, 0.1151655889, 0.0447321013, 0.0118951204, 0.0021643458, 0.0002692804, 2.28922E-05, 1.3287E-06, 5.26E-08, 1.4E-09 };
+#endif
+#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 1
+// Sigma: 2.8
+#if FFX_BLUR_KERNEL_RANGE == 2
+ { 0.3474999743, 0.3262500129 };
+#elif FFX_BLUR_KERNEL_RANGE == 3
+ { 0.2256541468, 0.2118551763, 0.1753177504 };
+#elif FFX_BLUR_KERNEL_RANGE == 4
+ { 0.1796953063, 0.1687067636, 0.1396108926, 0.1018346906 };
+#elif FFX_BLUR_KERNEL_RANGE == 5
+ { 0.1588894947, 0.1491732476, 0.1234462081, 0.0900438796, 0.0578919173 };
+#elif FFX_BLUR_KERNEL_RANGE == 6
+ { 0.1491060676, 0.1399880866, 0.1158451582, 0.0844995374, 0.054327293, 0.0307868909 };
+#elif FFX_BLUR_KERNEL_RANGE == 7
+ { 0.1446570603, 0.1358111404, 0.1123885856, 0.0819782513, 0.0527062824, 0.0298682757, 0.0149189344 };
+#elif FFX_BLUR_KERNEL_RANGE == 8
+ { 0.1427814521, 0.1340502275, 0.110931367, 0.0809153299, 0.0520228983, 0.0294810068, 0.0147254971, 0.0064829474 };
+#elif FFX_BLUR_KERNEL_RANGE == 9
+ { 0.1420666821, 0.1333791663, 0.1103760399, 0.0805102644, 0.0517624694, 0.0293334236, 0.0146517806, 0.0064504935, 0.0025030212 };
+#elif FFX_BLUR_KERNEL_RANGE == 10
+ { 0.1418238658, 0.1331511984, 0.1101873883, 0.0803726585, 0.0516739985, 0.0292832877, 0.0146267382, 0.0064394685, 0.0024987432, 0.0008545858 };
+#elif FFX_BLUR_KERNEL_RANGE == 11
+ { 0.1417508359, 0.1330826344, 0.1101306491, 0.0803312719, 0.0516473898, 0.0292682088, 0.0146192064, 0.0064361526, 0.0024974565, 0.0008541457, 0.0002574667 };
+#endif
+#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 2
+// Sigma: 4
+#if FFX_BLUR_KERNEL_RANGE == 2
+ { 0.3402771036, 0.3298614482 };
+#elif FFX_BLUR_KERNEL_RANGE == 3
+ { 0.2125433723, 0.2060375614, 0.1876907525 };
+#elif FFX_BLUR_KERNEL_RANGE == 4
+ { 0.1608542243, 0.1559305837, 0.1420455978, 0.1215967064 };
+#elif FFX_BLUR_KERNEL_RANGE == 5
+ { 0.1345347233, 0.1304167051, 0.1188036266, 0.1017006505, 0.0818116562 };
+#elif FFX_BLUR_KERNEL_RANGE == 6
+ { 0.1197258568, 0.1160611281, 0.1057263555, 0.090505984, 0.0728062644, 0.0550373395 };
+#elif FFX_BLUR_KERNEL_RANGE == 7
+ { 0.1110429695, 0.1076440182, 0.0980587551, 0.0839422118, 0.0675261302, 0.0510458624, 0.0362615375 };
+#elif FFX_BLUR_KERNEL_RANGE == 8
+ { 0.1059153311, 0.1026733334, 0.0935306896, 0.0800660068, 0.0644079717, 0.0486887143, 0.0345870861, 0.0230885324 };
+#elif FFX_BLUR_KERNEL_RANGE == 9
+ { 0.1029336421, 0.0997829119, 0.0908976484, 0.0778120183, 0.0625947824, 0.0473180477, 0.0336134033, 0.0224385526, 0.0140758142 };
+#elif FFX_BLUR_KERNEL_RANGE == 10
+ { 0.1012533395, 0.0981540422, 0.089413823, 0.0765418045, 0.0615729768, 0.0465456216, 0.0330646936, 0.0220722627, 0.0138460388, 0.0081620671 };
+#elif FFX_BLUR_KERNEL_RANGE == 11
+ { 0.1003459368, 0.0972744146, 0.0886125226, 0.0758558594, 0.0610211779, 0.0461284934, 0.0327683775, 0.0218744576, 0.0137219546, 0.008088921, 0.0044808529 };
+#endif
+#else
+#error FFX_BLUR_OPTION_KERNEL_PERMUTATION is not a valid value.
+#endif // FFX_BLUR_OPTION_KERNEL_PERMUTATIONs
+
+ return kernel_weights[iKernelIndex];
+}
+
+#if FFX_HALF
+
+ #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
+ void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat16x3 color)
+ {
+ rw_output[outPxCoord] = FfxFloat16x4(color, 1);
+ }
+ #endif // #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
+
+ #if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
+ FfxFloat16x3 FfxBlurLoadInput(FfxInt16x2 inPxCoord)
+ {
+ return r_input_src[inPxCoord].rgb;
+ }
+ #endif // #if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
+
+#else // FFX_HALF
+
+ #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
+ void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color)
+ {
+ rw_output[outPxCoord] = FfxFloat32x4(color, 1);
+ }
+ #endif // #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
+
+ #if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
+ FfxFloat32x3 FfxBlurLoadInput(FfxInt32x2 inPxCoord)
+ {
+ return r_input_src[inPxCoord].rgb;
+ }
+ #endif // #if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
+
+#endif // !FFX_HALF
+
+#endif // #if defined(FFX_GPU)
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_resources.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_resources.h
new file mode 100644
index 00000000..636de9b6
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/blur/ffx_blur_resources.h
@@ -0,0 +1,39 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFX_BLUR_RESOURCES_H
+#define FFX_BLUR_RESOURCES_H
+
+#if defined(FFX_CPU) || defined(FFX_GPU)
+
+#define FFX_BLUR_RESOURCE_IDENTIFIER_NULL 0
+#define FFX_BLUR_RESOURCE_IDENTIFIER_INPUT_SRC 1
+#define FFX_BLUR_RESOURCE_IDENTIFIER_OUTPUT 2
+
+#define FFX_BLUR_RESOURCE_IDENTIFIER_COUNT 3
+
+// CBV resource definitions
+#define FFX_BLUR_CONSTANTBUFFER_IDENTIFIER_BLUR 0
+
+#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
+
+#endif // FFX_BLUR_RESOURCES_H
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/CMakeCompileBrixelizerShaders.txt b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/CMakeCompileBrixelizerShaders.txt
new file mode 100644
index 00000000..c361b207
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/CMakeCompileBrixelizerShaders.txt
@@ -0,0 +1,74 @@
+# This file is part of the FidelityFX SDK.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files(the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions :
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+set(BRIXELIZER_BASE_ARGS
+ -reflection -deps=gcc -DFFX_GPU=1)
+
+set(BRIXELIZER_INCLUDE_ARGS
+ "${FFX_GPU_PATH}"
+ "${FFX_GPU_PATH}/brixelizer")
+
+if (NOT BRIXELIZER_SHADER_EXT)
+ set(BRIXELIZER_SHADER_EXT *)
+endif()
+
+file(GLOB BRIXELIZER_SHADERS
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_build_tree_aabb_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_brick_storage_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_build_counters_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_job_counter_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_ref_counters_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_coarse_culling_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_compact_references_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_compress_brick_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_emit_sdf_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_free_cascade_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_initialize_cascade_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_invalidate_job_areas_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_mark_cascade_uninitialized_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_reset_cascade_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_scan_jobs_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_scan_references_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_scroll_cascade_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_cascade_ops_voxelize_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_clear_brick_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_clear_counters_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_collect_clear_bricks_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_collect_dirty_bricks_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_eikonal_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_merge_bricks_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_merge_cascades_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_prepare_clear_bricks_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_prepare_eikonal_args_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_context_ops_prepare_merge_bricks_args_pass.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_debug_draw_aabb_tree.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_debug_draw_instance_aabbs.${BRIXELIZER_SHADER_EXT}"
+ "shaders/brixelizer/ffx_brixelizer_debug_visualization_pass.${BRIXELIZER_SHADER_EXT}")
+
+# compile all the shaders
+compile_shaders_with_depfile(
+ "${FFX_SC_EXECUTABLE}"
+ "${BRIXELIZER_BASE_ARGS}" "${BRIXELIZER_API_BASE_ARGS}" "" "${BRIXELIZER_INCLUDE_ARGS}"
+ "${BRIXELIZER_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" BRIXELIZER_PERMUTATION_OUTPUTS)
+
+# add the header files they generate to the main list of dependencies
+add_shader_output("${BRIXELIZER_PERMUTATION_OUTPUTS}")
\ No newline at end of file
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common.h
new file mode 100644
index 00000000..ee1f6283
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common.h
@@ -0,0 +1,117 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFX_BRIXELIZER_BRICK_COMMON_H
+#define FFX_BRIXELIZER_BRICK_COMMON_H
+
+#include "ffx_brixelizer_common.h"
+
+FfxUInt32 FfxBrixelizerBrickGetIndex(FfxUInt32 brick_id)
+{
+ return brick_id & FFX_BRIXELIZER_BRICK_ID_MASK;
+}
+
+FfxUInt32x3 FfxBrixelizerWrapCoords(FfxInt32x3 clipmap_offset, FfxUInt32 wrap_mask, FfxUInt32x3 voxel_coord)
+{
+ return (voxel_coord + FfxUInt32x3(clipmap_offset)) & FfxUInt32x3(wrap_mask, wrap_mask, wrap_mask);
+}
+
+FfxUInt32x3 FfxBrixelizerWrapCoords(FfxBrixelizerCascadeInfo cinfo, FfxUInt32x3 voxel_coord)
+{
+ return (voxel_coord + cinfo.clipmap_offset) & FfxUInt32x3(FFX_BRIXELIZER_CASCADE_WRAP_MASK, FFX_BRIXELIZER_CASCADE_WRAP_MASK, FFX_BRIXELIZER_CASCADE_WRAP_MASK);
+}
+
+FfxUInt32 FfxBrixelizerLoadBrickIDUniform(FfxUInt32 voxel_flat_id, FfxUInt32 cascade_id)
+{
+ return LoadCascadeBrickMapArrayUniform(cascade_id, voxel_flat_id);
+}
+
+FfxUInt32x3 FfxBrixelizerGetSDFAtlasOffset(FfxUInt32 brick_id)
+{
+ FfxUInt32 dim = 8;
+ FfxUInt32 offset = FfxBrixelizerBrickGetIndex(brick_id);
+ FfxUInt32 bperdim = FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / dim;
+ FfxUInt32 xoffset = offset % bperdim;
+ FfxUInt32 yoffset = (offset / bperdim) % bperdim;
+ FfxUInt32 zoffset = (offset / bperdim / bperdim);
+ return FfxUInt32x3(xoffset, yoffset, zoffset) * dim;
+}
+
+struct FfxBxAtlasBounds
+{
+ FfxUInt32 brick_dim;
+ FfxFloat32x3 uvw_min;
+ FfxFloat32x3 uvw_max;
+};
+
+FfxBxAtlasBounds FfxBrixelizerGetAtlasBounds(FfxUInt32 brick_id)
+{
+ FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
+ FfxBxAtlasBounds bounds;
+ bounds.brick_dim = FfxUInt32(8);
+ bounds.uvw_min = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(0.5)) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
+ bounds.uvw_max = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(float(8.0 - 0.5))) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
+ return bounds;
+}
+
+FfxFloat32 FfxBrixelizerSampleBrixelDistance(FfxUInt32 brick_id, FfxFloat32x3 uvw)
+{
+ FfxUInt32 brick_dim = FfxUInt32(8);
+ FfxFloat32 idim = FfxFloat32(1.0) / FfxFloat32(brick_dim);
+ FfxUInt32 texture_offset = FfxBrixelizerBrickGetIndex(brick_id);
+
+ // Offset for 7x7x7 region
+
+ FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
+ FfxFloat32x3 uvw_min = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(0.5)) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
+ FfxFloat32x3 uvw_max = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(FfxFloat32(brick_dim - FfxFloat32(0.5)))) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
+ uvw = ffxLerp(uvw_min, uvw_max, uvw);
+
+ return SampleSDFAtlas(uvw);
+}
+
+FfxFloat32 FfxBrixelizerSampleBrixelDistance(FfxFloat32x3 uvw_min, FfxFloat32x3 uvw_max, FfxFloat32x3 uvw)
+{
+ uvw = ffxLerp(uvw_min, uvw_max, uvw);
+ return SampleSDFAtlas(uvw);
+}
+
+FfxFloat32x3 FfxBrixelizerGetBrixelGrad(FfxFloat32x3 uvw_min, FfxFloat32x3 uvw_max, FfxFloat32x3 uvw) {
+ FfxFloat32 EPS = FfxFloat32(0.25) / (FfxFloat32(8.0) - FfxFloat32(1.0));
+
+ FfxFloat32x4 k = FfxFloat32x4(1.0, 1.0, 1.0, 0.0);
+ if (uvw.x > FfxFloat32(0.5)) k.x = -k.x;
+ if (uvw.y > FfxFloat32(0.5)) k.y = -k.y;
+ if (uvw.z > FfxFloat32(0.5)) k.z = -k.z;
+ FfxFloat32 fcenter = FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw);
+ FfxFloat32x3 grad = normalize(
+ k.xww * (FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw + k.xww * EPS) - fcenter) +
+ k.wyw * (FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw + k.wyw * EPS) - fcenter) +
+ k.wwz * (FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw + k.wwz * EPS) - fcenter)
+ );
+ if (any(isnan(grad))) {
+ return normalize(uvw - FFX_BROADCAST_FLOAT32X3(0.5));
+ }
+ return grad;
+}
+
+#endif // FFX_BRIXELIZER_BRICK_COMMON_H
\ No newline at end of file
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common_private.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common_private.h
new file mode 100644
index 00000000..7cc6e1f0
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common_private.h
@@ -0,0 +1,58 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFX_BRIXELIZER_BRICK_COMMON_PRIVATE_H
+#define FFX_BRIXELIZER_BRICK_COMMON_PRIVATE_H
+
+#include "ffx_brixelizer_common_private.h"
+#include "ffx_brixelizer_brick_common.h"
+
+FfxUInt32 FfxBrixelizerVoxelGetIndex(FfxUInt32 voxel_id)
+{
+ return voxel_id & FFX_BRIXELIZER_VOXEL_ID_MASK;
+}
+
+FfxUInt32 FfxBrixelizerGetVoxelCascade(FfxUInt32 voxel_id)
+{
+ return voxel_id >> FFX_BRIXELIZER_CASCADE_ID_SHIFT;
+}
+
+FfxUInt32 WrapFlatCoords(FfxBrixelizerCascadeInfo CINFO, FfxUInt32 voxel_idx)
+{
+ return FfxBrixelizerFlattenPOT((FfxBrixelizerUnflattenPOT(voxel_idx, FFX_BRIXELIZER_CASCADE_DEGREE) + CINFO.clipmap_offset) & FFX_BROADCAST_UINT32X3(FFX_BRIXELIZER_CASCADE_WRAP_MASK), FFX_BRIXELIZER_CASCADE_DEGREE);
+}
+
+FfxUInt32 FfxBrixelizerMakeBrickID(FfxUInt32 offset)
+{
+ return offset;
+}
+
+FfxFloat32x3 FfxBrixelizerGetBrixelGrad(FfxUInt32 brick_id, FfxFloat32x3 uvw)
+{
+ FfxFloat32 EPS = FfxFloat32(0.1) / (FfxFloat32(8.0) - FfxFloat32(1.0));
+ FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
+ FfxFloat32x3 uvw_min = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(0.5)) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
+ FfxFloat32x3 uvw_max = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(float(8.0 - float(0.5)))) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
+ return FfxBrixelizerGetBrixelGrad(uvw_min, uvw_max, uvw);
+}
+
+#endif // FFX_BRIXELIZER_BRICK_COMMON_PRIVATE_H
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_build_common.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_build_common.h
new file mode 100644
index 00000000..31ee3559
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_build_common.h
@@ -0,0 +1,39 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFX_BRIXELIZER_BUILD_COMMON_H
+#define FFX_BRIXELIZER_BUILD_COMMON_H
+
+#include "ffx_brixelizer_common_private.h"
+
+void FfxBrixelizerMarkBrickFree(FfxUInt32 brick_id)
+{
+ StoreBricksVoxelMap(FfxBrixelizerBrickGetIndex(brick_id), FFX_BRIXELIZER_INVALID_ID);
+}
+
+FfxUInt32 FfxBrixelizerLoadBrickVoxelID(FfxUInt32 brick_id)
+{
+ return LoadBricksVoxelMap(FfxBrixelizerBrickGetIndex(brick_id));
+}
+// FfxUInt32 FfxBrixelizerLoadBrickCascadeID(FfxUInt32 brick_id) { return LoadBricksVoxelMap(FfxBrixelizerBrickGetIndex(brick_id)) >> FFX_BRIXELIZER_CASCADE_ID_SHIFT; }
+
+#endif // FFX_BRIXELIZER_BUILD_COMMON_H
\ No newline at end of file
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_glsl.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_glsl.h
new file mode 100644
index 00000000..18ec5a2f
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_glsl.h
@@ -0,0 +1,1287 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFX_BRIXELIZER_CALLBACKS_GLSL_H
+#define FFX_BRIXELIZER_CALLBACKS_GLSL_H
+
+#include "ffx_brixelizer_resources.h"
+#include "ffx_brixelizer_host_gpu_shared.h"
+#include "ffx_brixelizer_host_gpu_shared_private.h"
+
+#if defined(FFX_GPU)
+#ifndef FFX_PREFER_WAVE64
+#define FFX_PREFER_WAVE64
+#endif // #ifndef FFX_PREFER_WAVE64
+
+#define FFX_BRIXELIZER_SIZEOF_UINT 4
+
+// CBVs
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+ layout (set = 0, binding = BRIXELIZER_BIND_CB_CASCADE_INFO, std140) uniform BrixelizerCascadeInfo_t
+ {
+ FfxBrixelizerCascadeInfo data;
+ } cbBrixelizerCascadeInfo;
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CONTEXT_INFO
+ layout (set = 0, binding = BRIXELIZER_BIND_CB_CONTEXT_INFO, std140) uniform BrixelizerContextInfo_t
+ {
+ FfxBrixelizerContextInfo data;
+ } cbBrixelizerContextInfo;
+#endif
+
+#if defined BRIXELIZER_BIND_CB_BUILD_INFO
+ layout (set = 0, binding = BRIXELIZER_BIND_CB_BUILD_INFO, std140) uniform BrixelizerBuildInfo_t
+ {
+ FfxBrixelizerBuildInfo data;
+ } cbBrixelizerBuildInfo;
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+ layout (set = 0, binding = BRIXELIZER_BIND_CB_DEBUG_INFO, std140) uniform BrixelizerDebugInfo_t
+ {
+ FfxBrixelizerDebugInfo data;
+ } cbBrixelizerDebugInfo;
+#endif
+
+// SRVs
+
+#if defined BRIXELIZER_BIND_SRV_DEBUG_INSTANCE_ID_BUFFER
+ layout (set = 0, binding = BRIXELIZER_BIND_SRV_DEBUG_INSTANCE_ID_BUFFER, std430) readonly buffer BrixelizerDebugInstanceID_t
+ {
+ FfxUInt32 data[];
+ } r_debug_instance_id;
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_JOB_BUFFER
+ layout (set = 0, binding = BRIXELIZER_BIND_SRV_JOB_BUFFER, std430) readonly buffer BrixelizerJob_t
+ {
+ FfxBrixelizerBrixelizationJob data[];
+ } r_job_buffer;
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_JOB_INDEX_BUFFER
+ layout (set = 0, binding = BRIXELIZER_BIND_SRV_JOB_INDEX_BUFFER, std430) readonly buffer BrixelizerJobIndex_t
+ {
+ FfxUInt32 data[];
+ } r_job_index_buffer;
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_INSTANCE_INFO_BUFFER
+ layout (set = 0, binding = BRIXELIZER_BIND_SRV_INSTANCE_INFO_BUFFER, std430) readonly buffer BrixelizerInstanceInfo_t
+ {
+ FfxBrixelizerInstanceInfo data[];
+ } r_instance_info_buffer;
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_INSTANCE_TRANSFORM_BUFFER
+ layout (set = 0, binding = BRIXELIZER_BIND_SRV_INSTANCE_TRANSFORM_BUFFER, std430) readonly buffer BrixelizerInstanceTransform_t
+ {
+ FfxFloat32x4 data[];
+ } r_instance_transform_buffer;
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+ layout (set = 1, binding = BRIXELIZER_BIND_SRV_VERTEX_BUFFERS, std430) readonly buffer BrixelizerVertexBuffer_t
+ {
+ FfxUInt32 data[];
+ } r_vertex_buffers[FFX_BRIXELIZER_STATIC_CONFIG_MAX_VERTEX_BUFFERS];
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_SDF_ATLAS
+ layout (set = 0, binding = BRIXELIZER_BIND_SRV_SDF_ATLAS) uniform texture3D r_sdf_atlas;
+#endif
+
+// UAVs
+
+#if defined BRIXELIZER_BIND_UAV_DEBUG_AABBS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_DEBUG_AABBS, std430) buffer BrixelizerDebugAABBs_t
+ {
+ FfxBrixelizerDebugAABB data[];
+ } rw_debug_aabbs;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE, std430) buffer BrixelizerCascadeAABBTree_t
+ {
+ FfxUInt32 data[];
+ } rw_cascade_aabbtree;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAP
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAP, std430) buffer BrixelizerCascadeBrickMap_t
+ {
+ FfxUInt32 data[];
+ } rw_cascade_brick_map;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_COUNTERS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_COUNTERS, std430) buffer BrixelizerScratchCounters_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_counters;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP, std430) buffer BrixelizerScratchIndexSwap_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_index_swap;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_VOXEL_ALLOCATION_FAIL_COUNTER
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_VOXEL_ALLOCATION_FAIL_COUNTER, std430) buffer BrixelizerScratchVoxelAllocationFailCounter_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_voxel_allocation_fail_counter;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE, std430) buffer BrixelizerScratchBricksStorage_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_bricks_storage;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE_OFFSETS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE_OFFSETS, std430) buffer BrixelizerScratchBricksStorageOffsets_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_bricks_storage_offsets;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_COMPRESSION_LIST
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_COMPRESSION_LIST, std430) buffer BrixelizerScratchBricksCompressionList_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_bricks_compression_list;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_CLEAR_LIST
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_CLEAR_LIST, std430) buffer BrixelizerScratchBricksClearList_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_bricks_clear_list;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS, std430) buffer BrixelizerScratchJobCounters_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_job_counters;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS_SCAN
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS_SCAN, std430) buffer BrixelizerScratchJobCountersScan_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_job_counters_scan;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_GLOBAL_COUNTERS_SCAN
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_JOB_GLOBAL_COUNTERS_SCAN, std430) buffer BrixelizerScratchJobGlobalCountersScan_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_job_global_counters_scan;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REFERENCES
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_REFERENCES, std430) buffer BrixelizerScratchCR1References_t
+ {
+ FfxBrixelizerTriangleReference data[];
+ } rw_scratch_cr1_references;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_COMPACTED_REFERENCES
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_COMPACTED_REFERENCES, std430) buffer BrixelizerScratchCR1CompactedReferences_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_cr1_compacted_references;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTERS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTERS, std430) buffer BrixelizerScratchCR1RefCounters_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_cr1_ref_counters;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_INSTANCE_REF_COUNTERS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_INSTANCE_REF_COUNTERS, std430) buffer BrixelizerScratchCR1InstanceRefCounters_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_cr1_instance_ref_counters;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTER_SCAN
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTER_SCAN, std430) buffer BrixelizerScratchCR1RefCounterScan_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_cr1_ref_counter_scan;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_GLOBAL_SCAN
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_GLOBAL_SCAN, std430) buffer BrixelizerScratchCR1RefGlobalScan_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_cr1_ref_global_scan;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_SCAN
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_SCAN, std430) buffer BrixelizerScratchCR1StampScan_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_cr1_stamp_scan;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_GLOBAL_SCAN
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_GLOBAL_SCAN, std430) buffer BrixelizerScratchCR1StampGlobalScan_t
+ {
+ FfxUInt32 data[];
+ } rw_scratch_cr1_stamp_global_scan;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_INDIRECT_ARGS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_INDIRECT_ARGS, std430) buffer BrixelizerIndirectArgs_t
+ {
+ FfxUInt32 data[];
+ } rw_indirect_args_1;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_VOXEL_MAP
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_VOXEL_MAP, std430) buffer BrixelizerContextBricksVoxelMap_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_bricks_voxel_map;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_AABB
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_AABB, std430) buffer BrixelizerContextBricksAABB_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_bricks_aabb;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_FREE_LIST
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_FREE_LIST, std430) buffer BrixelizerContextBricksFreeList_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_bricks_free_list;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_CLEAR_LIST
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_CLEAR_LIST, std430) buffer BrixelizerContextBricksClearList_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_bricks_clear_list;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_LIST
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_LIST, std430) buffer BrixelizerContextBricksEikonalList_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_bricks_eikonal_list;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_MERGE_LIST
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_MERGE_LIST, std430) buffer BrixelizerContextBricksMergeList_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_bricks_merge_list;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_COUNTERS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_COUNTERS, std430) buffer BrixelizerContextBricksEikonalCounters_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_bricks_eikonal_counters;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_COUNTERS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CONTEXT_COUNTERS, std430) buffer BrixelizerContextCounters_t
+ {
+ FfxUInt32 data[];
+ } rw_bctx_counters;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAPS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAPS, std430) buffer BrixelizerCascadeBrickMaps_t
+ {
+ FfxUInt32 data[];
+ } rw_cascade_brick_maps[24];
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREES
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_CASCADE_AABB_TREES, std430) buffer BrixelizerCascadeAABBTrees_t
+ {
+ FfxUInt32 data[];
+ } rw_cascade_aabbtrees[24];
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SDF_ATLAS
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_SDF_ATLAS, r8) uniform image3D rw_sdf_atlas;
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_DEBUG_OUTPUT
+ layout (set = 0, binding = BRIXELIZER_BIND_UAV_DEBUG_OUTPUT, rgba16f) uniform image2D rw_debug_output;
+#endif
+
+layout (set = 0, binding = 1000) uniform sampler g_wrap_linear_sampler;
+
+FfxBrixelizerDebugAABB GetDebugAABB(FfxUInt32 idx);
+void StoreDebugAABB(FfxUInt32 idx, FfxBrixelizerDebugAABB aabb);
+FfxUInt32 GetDebugInstanceID(FfxUInt32 idx);
+FfxBrixelizerCascadeInfo GetCascadeInfo();
+FfxUInt32x3 GetCascadeInfoClipmapOffset();
+FfxUInt32 GetCascadeInfoIndex();
+FfxFloat32x3 GetCascadeInfoGridMin();
+FfxFloat32x3 GetCascadeInfoGridMax();
+FfxFloat32 GetCascadeInfoVoxelSize();
+FfxInt32x3 GetCascadeInfoClipmapInvalidationOffset();
+FfxBrixelizerCascadeInfo GetCascadeInfo(FfxUInt32 idx);
+FfxUInt32 GetContextInfoNumBricks();
+FfxUInt32x3 GetContextInfoCascadeClipmapOffset(FfxUInt32 cascade_index);
+FfxBrixelizerBuildInfo GetBuildInfo();
+FfxUInt32 GetBuildInfoDoInitialization();
+FfxInt32 GetBuildInfoTreeIteration();
+FfxUInt32 GetBuildInfoNumJobs();
+FfxUInt32 GetDebugInfoMaxAABBs();
+FfxFloat32x4x4 GetDebugInfoInvView();
+FfxFloat32x4x4 GetDebugInfoInvProj();
+FfxFloat32 GetDebugInfoPreviewSDFSolveEpsilon();
+FfxUInt32 GetDebugInfoStartCascadeIndex();
+FfxUInt32 GetDebugInfoEndCascadeIndex();
+FfxFloat32 GetDebugInfoTMin();
+FfxFloat32 GetDebugInfoTMax();
+FfxUInt32 GetDebugInfoDebugState();
+FfxBrixelizerBrixelizationJob LoadBrixelizationJob(FfxUInt32 idx);
+FfxUInt32 LoadJobIndex(FfxUInt32 idx);
+FfxBrixelizerInstanceInfo LoadInstanceInfo(FfxUInt32 index);
+FfxFloat32x3x4 LoadInstanceTransform(FfxUInt32 idx);
+FfxUInt32 LoadVertexBufferUInt(FfxUInt32 bufferIdx, FfxUInt32 elementIdx);
+FfxUInt32x2 LoadVertexBufferUInt2(FfxUInt32 bufferIdx, FfxUInt32 elementIdx);
+FfxUInt32x3 LoadVertexBufferUInt3(FfxUInt32 bufferIdx, FfxUInt32 elementIdx);
+FfxFloat32x2 LoadVertexBufferFloat2(FfxUInt32 bufferIdx, FfxUInt32 elementIdx);
+FfxFloat32x3 LoadVertexBufferFloat3(FfxUInt32 bufferIdx, FfxUInt32 elementIdx);
+FfxFloat32x4 LoadVertexBufferFloat4(FfxUInt32 bufferIdx, FfxUInt32 elementIdx);
+FfxFloat32 SampleSDFAtlas(FfxFloat32x3 uvw);
+FfxUInt32 LoadCascadeBrickMap(FfxUInt32 elementIdx);
+void StoreCascadeBrickMap(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadCascadeBrickMapArrayUniform(FfxUInt32 bufferIdx, FfxUInt32 elementIdx);
+void StoreCascadeBrickMapArrayUniform(FfxUInt32 bufferIdx, FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchCounter(FfxUInt32 counter);
+void StoreScratchCounter(FfxUInt32 counter, FfxUInt32 value);
+void IncrementScratchCounter(FfxUInt32 counter, FfxUInt32 value, inout FfxUInt32 originalValue);
+FfxUInt32x2 LoadScratchIndexSwapUInt2(FfxUInt32 elementIdx);
+FfxFloat32x3 LoadScratchIndexSwapFloat3(FfxUInt32 elementIdx);
+void StoreScratchIndexSwapUInt2(FfxUInt32 elementIdx, FfxUInt32x2 value);
+void StoreScratchIndexSwapFloat3(FfxUInt32 elementIdx, FfxFloat32x3 value);
+void GetScratchIndexSwapDimensions(inout FfxUInt32 size);
+FfxUInt32 LoadScratchVoxelAllocationFailCounter(FfxUInt32 elementIdx);
+void StoreScratchVoxelAllocationFailCounter(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchBricksStorage(FfxUInt32 elementIdx);
+void StoreScratchBricksStorage(FfxUInt32 elementIdx, FfxUInt32 value);
+void GetScratchBricksStorageDimensions(inout FfxUInt32 size);
+void MinScratchBricksStorage(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchBricksStorageOffsets(FfxUInt32 elementIdx);
+void StoreScratchBricksStorageOffsets(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchBricksCompressionList(FfxUInt32 elementIdx);
+void StoreScratchBricksCompressionList(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchBricksClearList(FfxUInt32 elementIdx);
+void StoreScratchBricksClearList(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchJobCounter(FfxUInt32 counterIdx);
+void StoreScratchJobCounter(FfxUInt32 counterIdx, FfxUInt32 value);
+void IncrementScratchJobCounter(FfxUInt32 counterIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchJobCountersScan(FfxUInt32 elementIdx);
+void StoreScratchJobCountersScan(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadGlobalJobTriangleCounterScan(FfxUInt32 elementIdx);
+void StoreGlobalJobTriangleCounterScan(FfxUInt32 elementIdx, FfxUInt32 scan);
+FfxBrixelizerTriangleReference LoadScratchCR1Reference(FfxUInt32 elementIdx);
+void StoreScratchCR1Reference(FfxUInt32 elementIdx, FfxBrixelizerTriangleReference ref);
+void GetScratchMaxReferences(inout FfxUInt32 size);
+FfxUInt32 LoadScratchCR1CompactedReferences(FfxUInt32 elementIdx);
+void StoreScratchCR1CompactedReferences(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchCR1RefCounter(FfxUInt32 elementIdx);
+void StoreScratchCR1RefCounter(FfxUInt32 elementIdx, FfxUInt32 value);
+void IncrementScratchCR1RefCounter(FfxUInt32 elementIdx, FfxUInt32 value, inout FfxUInt32 originalValue);
+FfxUInt32 LoadScratchCR1RefCounterScan(FfxUInt32 elementIdx);
+void StoreScratchCR1RefCounterScan(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadVoxelReferenceGroupSum(FfxUInt32 elementIdx);
+void StoreVoxelReferenceGroupSum(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadScratchCR1StampScan(FfxUInt32 elementIdx);
+void StoreScratchCR1StampScan(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadStampGroupSum(FfxUInt32 elementIdx);
+void StoreStampGroupSum(FfxUInt32 elementIdx, FfxUInt32 value);
+void StoreIndirectArgs(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadBricksVoxelMap(FfxUInt32 elementIdx);
+void StoreBricksVoxelMap(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadBricksAABB(FfxUInt32 elementIdx);
+void StoreBricksAABB(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadBricksFreeList(FfxUInt32 elementIdx);
+void StoreBricksFreeList(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadBricksClearList(FfxUInt32 elementIdx);
+void StoreBricksClearList(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadBricksDirtyList(FfxUInt32 elementIdx);
+void StoreBricksDirtyList(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadBricksMergeList(FfxUInt32 elementIdx);
+void StoreBricksMergeList(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadBricksEikonalCounters(FfxUInt32 elementIdx);
+void StoreBricksEikonalCounters(FfxUInt32 elementIdx, FfxUInt32 value);
+FfxUInt32 LoadContextCounter(FfxUInt32 elementIdx);
+void StoreContextCounter(FfxUInt32 elementIdx, FfxUInt32 value);
+void IncrementContextCounter(FfxUInt32 elementIdx, FfxUInt32 value, inout FfxUInt32 originalValue);
+FfxFloat32x3 LoadCascadeAABBTreeFloat3(FfxUInt32 elementIdx);
+FfxUInt32 LoadCascadeAABBTreeUInt(FfxUInt32 elementIdx);
+void StoreCascadeAABBTreeUInt(FfxUInt32 elementIdx, FfxUInt32 value);
+void StoreCascadeAABBTreeFloat3(FfxUInt32 elementIdx, FfxFloat32x3 value);
+FfxFloat32x3 LoadCascadeAABBTreesFloat3(FfxUInt32 cascadeID, FfxUInt32 elementIdx);
+FfxUInt32 LoadCascadeAABBTreesUInt(FfxUInt32 cascadeID, FfxUInt32 elementIdx);
+FfxFloat32 LoadSDFAtlas(FfxUInt32x3 coord);
+void StoreSDFAtlas(FfxUInt32x3 coord, FfxFloat32 value);
+void StoreDebugOutput(FfxUInt32x2 coord, FfxFloat32x3 outputValue);
+void GetDebugOutputDimensions(inout FfxUInt32 width, inout FfxUInt32 height);
+
+#if defined BRIXELIZER_BIND_UAV_DEBUG_AABBS
+FfxBrixelizerDebugAABB GetDebugAABB(FfxUInt32 idx)
+{
+ return rw_debug_aabbs.data[idx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_DEBUG_AABBS
+void StoreDebugAABB(FfxUInt32 idx, FfxBrixelizerDebugAABB aabb)
+{
+ rw_debug_aabbs.data[idx] = aabb;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_DEBUG_INSTANCE_ID_BUFFER
+FfxUInt32 GetDebugInstanceID(FfxUInt32 idx)
+{
+ return r_debug_instance_id.data[idx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+FfxBrixelizerCascadeInfo GetCascadeInfo()
+{
+ return cbBrixelizerCascadeInfo.data;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+FfxUInt32x3 GetCascadeInfoClipmapOffset()
+{
+ return cbBrixelizerCascadeInfo.data.clipmap_offset;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+FfxUInt32 GetCascadeInfoIndex()
+{
+ return cbBrixelizerCascadeInfo.data.index;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+FfxFloat32x3 GetCascadeInfoGridMin()
+{
+ return cbBrixelizerCascadeInfo.data.grid_min;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+FfxFloat32x3 GetCascadeInfoGridMax()
+{
+ return cbBrixelizerCascadeInfo.data.grid_max;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+FfxFloat32 GetCascadeInfoVoxelSize()
+{
+ return cbBrixelizerCascadeInfo.data.voxel_size;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+FfxInt32x3 GetCascadeInfoClipmapInvalidationOffset()
+{
+ return cbBrixelizerCascadeInfo.data.clipmap_invalidation_offset;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CONTEXT_INFO
+FfxBrixelizerCascadeInfo GetCascadeInfo(FfxUInt32 idx)
+{
+ return cbBrixelizerContextInfo.data.cascades[idx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CONTEXT_INFO
+FfxUInt32 GetContextInfoNumBricks()
+{
+ return cbBrixelizerContextInfo.data.num_bricks;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CONTEXT_INFO
+FfxUInt32x3 GetContextInfoCascadeClipmapOffset(FfxUInt32 cascade_index)
+{
+ return cbBrixelizerContextInfo.data.cascades[cascade_index].clipmap_offset;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_BUILD_INFO
+FfxBrixelizerBuildInfo GetBuildInfo()
+{
+ return cbBrixelizerBuildInfo.data;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_BUILD_INFO
+FfxUInt32 GetBuildInfoDoInitialization()
+{
+ return cbBrixelizerBuildInfo.data.do_initialization;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_BUILD_INFO
+FfxInt32 GetBuildInfoTreeIteration()
+{
+ return cbBrixelizerBuildInfo.data.tree_iteration;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_BUILD_INFO
+FfxUInt32 GetBuildInfoNumJobs()
+{
+ return cbBrixelizerBuildInfo.data.num_jobs;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxUInt32 GetDebugInfoMaxAABBs()
+{
+ return cbBrixelizerDebugInfo.data.max_aabbs;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxFloat32x4x4 GetDebugInfoInvView()
+{
+ return cbBrixelizerDebugInfo.data.inv_view;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxFloat32x4x4 GetDebugInfoInvProj()
+{
+ return cbBrixelizerDebugInfo.data.inv_proj;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxFloat32 GetDebugInfoPreviewSDFSolveEpsilon()
+{
+ return cbBrixelizerDebugInfo.data.preview_sdf_solve_eps;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxUInt32 GetDebugInfoStartCascadeIndex()
+{
+ return cbBrixelizerDebugInfo.data.start_cascade_idx;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxUInt32 GetDebugInfoEndCascadeIndex()
+{
+ return cbBrixelizerDebugInfo.data.end_cascade_idx;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxFloat32 GetDebugInfoTMin()
+{
+ return cbBrixelizerDebugInfo.data.t_min;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxFloat32 GetDebugInfoTMax()
+{
+ return cbBrixelizerDebugInfo.data.t_max;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+FfxUInt32 GetDebugInfoDebugState()
+{
+ return cbBrixelizerDebugInfo.data.debug_state;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_JOB_BUFFER
+FfxBrixelizerBrixelizationJob LoadBrixelizationJob(FfxUInt32 idx)
+{
+ return r_job_buffer.data[idx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_JOB_INDEX_BUFFER
+FfxUInt32 LoadJobIndex(FfxUInt32 idx)
+{
+ return r_job_index_buffer.data[idx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_INSTANCE_INFO_BUFFER
+FfxBrixelizerInstanceInfo LoadInstanceInfo(FfxUInt32 index)
+{
+ return r_instance_info_buffer.data[index];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_INSTANCE_TRANSFORM_BUFFER
+FfxFloat32x3x4 LoadInstanceTransform(FfxUInt32 idx)
+{
+ // Instance transforms as stored in rows, so load in the 3 rows for this matrix.
+ FfxFloat32x4 M0 = r_instance_transform_buffer.data[idx * FfxUInt32(3) + FfxUInt32(0)];
+ FfxFloat32x4 M1 = r_instance_transform_buffer.data[idx * FfxUInt32(3) + FfxUInt32(1)];
+ FfxFloat32x4 M2 = r_instance_transform_buffer.data[idx * FfxUInt32(3) + FfxUInt32(2)];
+
+ // A GLSL mat4x3 is constructed using 4xvec3 columns so we need to reshuffle the 3 rows that we loaded into 4 columns.
+
+ return FfxFloat32x3x4(FfxFloat32x3(M0.x, M1.x, M2.x),
+ FfxFloat32x3(M0.y, M1.y, M2.y),
+ FfxFloat32x3(M0.z, M1.z, M2.z),
+ FfxFloat32x3(M0.w, M1.w, M2.w));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+FfxUInt32 LoadVertexBufferUInt(FfxUInt32 bufferIdx, FfxUInt32 elementIdx)
+{
+ return r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+FfxUInt32x2 LoadVertexBufferUInt2(FfxUInt32 bufferIdx, FfxUInt32 elementIdx)
+{
+ return FfxUInt32x2(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 0],
+ r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 1]);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+FfxUInt32x3 LoadVertexBufferUInt3(FfxUInt32 bufferIdx, FfxUInt32 elementIdx)
+{
+ return FfxUInt32x3(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 0],
+ r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 1],
+ r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 2]);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+FfxFloat32x2 LoadVertexBufferFloat2(FfxUInt32 bufferIdx, FfxUInt32 elementIdx)
+{
+ return FfxFloat32x2(uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 0]),
+ uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 1]));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+FfxFloat32x3 LoadVertexBufferFloat3(FfxUInt32 bufferIdx, FfxUInt32 elementIdx)
+{
+ return FfxFloat32x3(uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 0]),
+ uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 1]),
+ uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 2]));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+FfxFloat32x4 LoadVertexBufferFloat4(FfxUInt32 bufferIdx, FfxUInt32 elementIdx)
+{
+ return FfxFloat32x4(uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 0]),
+ uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 1]),
+ uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 2]),
+ uintBitsToFloat(r_vertex_buffers[nonuniformEXT(bufferIdx)].data[elementIdx + 3]));
+}
+#endif
+
+#if defined(BRIXELIZER_BIND_SRV_SDF_ATLAS)
+FfxFloat32 SampleSDFAtlas(FfxFloat32x3 uvw)
+{
+ return textureLod(sampler3D(r_sdf_atlas, g_wrap_linear_sampler), uvw, FfxFloat32(0.0f)).r;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAP
+FfxUInt32 LoadCascadeBrickMap(FfxUInt32 elementIdx)
+{
+ return rw_cascade_brick_map.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAP
+void StoreCascadeBrickMap(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_cascade_brick_map.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAPS
+FfxUInt32 LoadCascadeBrickMapArrayUniform(FfxUInt32 bufferIdx, FfxUInt32 elementIdx)
+{
+ return rw_cascade_brick_maps[bufferIdx].data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAPS
+void StoreCascadeBrickMapArrayUniform(FfxUInt32 bufferIdx, FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_cascade_brick_maps[bufferIdx].data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_COUNTERS
+FfxUInt32 LoadScratchCounter(FfxUInt32 counter)
+{
+ return rw_scratch_counters.data[counter];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_COUNTERS
+void StoreScratchCounter(FfxUInt32 counter, FfxUInt32 value)
+{
+ rw_scratch_counters.data[counter] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_COUNTERS
+void IncrementScratchCounter(FfxUInt32 counter, FfxUInt32 value, inout FfxUInt32 originalValue)
+{
+ originalValue = atomicAdd(rw_scratch_counters.data[counter], value);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP
+FfxUInt32x2 LoadScratchIndexSwapUInt2(FfxUInt32 elementIdx)
+{
+ return FfxUInt32x2(rw_scratch_index_swap.data[elementIdx + 0],
+ rw_scratch_index_swap.data[elementIdx + 1]);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP
+FfxFloat32x3 LoadScratchIndexSwapFloat3(FfxUInt32 elementIdx)
+{
+ return FfxFloat32x3(uintBitsToFloat(rw_scratch_index_swap.data[elementIdx + 0]),
+ uintBitsToFloat(rw_scratch_index_swap.data[elementIdx + 1]),
+ uintBitsToFloat(rw_scratch_index_swap.data[elementIdx + 2]));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP
+void StoreScratchIndexSwapUInt2(FfxUInt32 elementIdx, FfxUInt32x2 value)
+{
+ rw_scratch_index_swap.data[elementIdx + 0] = value.x;
+ rw_scratch_index_swap.data[elementIdx + 1] = value.y;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP
+void StoreScratchIndexSwapFloat3(FfxUInt32 elementIdx, FfxFloat32x3 value)
+{
+ rw_scratch_index_swap.data[elementIdx + 0] = floatBitsToUint(value.x);
+ rw_scratch_index_swap.data[elementIdx + 1] = floatBitsToUint(value.y);
+ rw_scratch_index_swap.data[elementIdx + 2] = floatBitsToUint(value.z);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP
+void GetScratchIndexSwapDimensions(inout FfxUInt32 size)
+{
+ FfxUInt32 numStructs = rw_scratch_index_swap.data.length();
+ FfxUInt32 stride = 4;
+ size = numStructs * stride;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_VOXEL_ALLOCATION_FAIL_COUNTER
+FfxUInt32 LoadScratchVoxelAllocationFailCounter(FfxUInt32 elementIdx)
+{
+ return rw_scratch_voxel_allocation_fail_counter.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_VOXEL_ALLOCATION_FAIL_COUNTER
+void StoreScratchVoxelAllocationFailCounter(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_voxel_allocation_fail_counter.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE
+FfxUInt32 LoadScratchBricksStorage(FfxUInt32 elementIdx)
+{
+ return rw_scratch_bricks_storage.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE
+void StoreScratchBricksStorage(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_bricks_storage.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE
+void GetScratchBricksStorageDimensions(inout FfxUInt32 size)
+{
+ FfxUInt32 numStructs = rw_scratch_bricks_storage.data.length();
+ FfxUInt32 stride = 4;
+ size = numStructs * stride;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE
+void MinScratchBricksStorage(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ atomicMin(rw_scratch_bricks_storage.data[elementIdx], value);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE_OFFSETS
+FfxUInt32 LoadScratchBricksStorageOffsets(FfxUInt32 elementIdx)
+{
+ return rw_scratch_bricks_storage_offsets.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE_OFFSETS
+void StoreScratchBricksStorageOffsets(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_bricks_storage_offsets.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_COMPRESSION_LIST
+FfxUInt32 LoadScratchBricksCompressionList(FfxUInt32 elementIdx)
+{
+ return rw_scratch_bricks_compression_list.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_COMPRESSION_LIST
+void StoreScratchBricksCompressionList(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_bricks_compression_list.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_CLEAR_LIST
+FfxUInt32 LoadScratchBricksClearList(FfxUInt32 elementIdx)
+{
+ return rw_scratch_bricks_clear_list.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_CLEAR_LIST
+void StoreScratchBricksClearList(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_bricks_clear_list.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS
+FfxUInt32 LoadScratchJobCounter(FfxUInt32 counterIdx)
+{
+ return rw_scratch_job_counters.data[counterIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS
+void StoreScratchJobCounter(FfxUInt32 counterIdx, FfxUInt32 value)
+{
+ rw_scratch_job_counters.data[counterIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS
+void IncrementScratchJobCounter(FfxUInt32 counterIdx, FfxUInt32 value)
+{
+ atomicAdd(rw_scratch_job_counters.data[counterIdx], value);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS_SCAN
+FfxUInt32 LoadScratchJobCountersScan(FfxUInt32 elementIdx)
+{
+ return rw_scratch_job_counters_scan.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS_SCAN
+void StoreScratchJobCountersScan(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_job_counters_scan.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_GLOBAL_COUNTERS_SCAN
+FfxUInt32 LoadGlobalJobTriangleCounterScan(FfxUInt32 elementIdx)
+{
+ return rw_scratch_job_global_counters_scan.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_GLOBAL_COUNTERS_SCAN
+void StoreGlobalJobTriangleCounterScan(FfxUInt32 elementIdx, FfxUInt32 scan)
+{
+ rw_scratch_job_global_counters_scan.data[elementIdx] = scan;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REFERENCES
+FfxBrixelizerTriangleReference LoadScratchCR1Reference(FfxUInt32 elementIdx)
+{
+ return rw_scratch_cr1_references.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REFERENCES
+void StoreScratchCR1Reference(FfxUInt32 elementIdx, FfxBrixelizerTriangleReference ref)
+{
+ rw_scratch_cr1_references.data[elementIdx] = ref;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REFERENCES
+void GetScratchMaxReferences(inout FfxUInt32 size)
+{
+ size = rw_scratch_cr1_references.data.length();
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_COMPACTED_REFERENCES
+FfxUInt32 LoadScratchCR1CompactedReferences(FfxUInt32 elementIdx)
+{
+ return rw_scratch_cr1_compacted_references.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_COMPACTED_REFERENCES
+void StoreScratchCR1CompactedReferences(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_cr1_compacted_references.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTERS
+FfxUInt32 LoadScratchCR1RefCounter(FfxUInt32 elementIdx)
+{
+ return rw_scratch_cr1_ref_counters.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTERS
+void StoreScratchCR1RefCounter(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_cr1_ref_counters.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTERS
+void IncrementScratchCR1RefCounter(FfxUInt32 elementIdx, FfxUInt32 value, inout FfxUInt32 originalValue)
+{
+ originalValue = atomicAdd(rw_scratch_cr1_ref_counters.data[elementIdx], value);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTER_SCAN
+FfxUInt32 LoadScratchCR1RefCounterScan(FfxUInt32 elementIdx)
+{
+ return rw_scratch_cr1_ref_counter_scan.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTER_SCAN
+void StoreScratchCR1RefCounterScan(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_cr1_ref_counter_scan.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_GLOBAL_SCAN
+FfxUInt32 LoadVoxelReferenceGroupSum(FfxUInt32 elementIdx)
+{
+ return rw_scratch_cr1_ref_global_scan.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_GLOBAL_SCAN
+void StoreVoxelReferenceGroupSum(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_cr1_ref_global_scan.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_SCAN
+FfxUInt32 LoadScratchCR1StampScan(FfxUInt32 elementIdx)
+{
+ return rw_scratch_cr1_stamp_scan.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_SCAN
+void StoreScratchCR1StampScan(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_cr1_stamp_scan.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_GLOBAL_SCAN
+FfxUInt32 LoadStampGroupSum(FfxUInt32 elementIdx)
+{
+ return rw_scratch_cr1_stamp_global_scan.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_GLOBAL_SCAN
+void StoreStampGroupSum(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_scratch_cr1_stamp_global_scan.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_INDIRECT_ARGS
+void StoreIndirectArgs(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_indirect_args_1.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_VOXEL_MAP
+FfxUInt32 LoadBricksVoxelMap(FfxUInt32 elementIdx)
+{
+ return rw_bctx_bricks_voxel_map.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_VOXEL_MAP
+void StoreBricksVoxelMap(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_bricks_voxel_map.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_AABB
+FfxUInt32 LoadBricksAABB(FfxUInt32 elementIdx)
+{
+ return rw_bctx_bricks_aabb.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_AABB
+void StoreBricksAABB(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_bricks_aabb.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_FREE_LIST
+FfxUInt32 LoadBricksFreeList(FfxUInt32 elementIdx)
+{
+ return rw_bctx_bricks_free_list.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_FREE_LIST
+void StoreBricksFreeList(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_bricks_free_list.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_CLEAR_LIST
+FfxUInt32 LoadBricksClearList(FfxUInt32 elementIdx)
+{
+ return rw_bctx_bricks_clear_list.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_CLEAR_LIST
+void StoreBricksClearList(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_bricks_clear_list.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_LIST
+FfxUInt32 LoadBricksDirtyList(FfxUInt32 elementIdx)
+{
+ return rw_bctx_bricks_eikonal_list.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_LIST
+void StoreBricksDirtyList(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_bricks_eikonal_list.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_MERGE_LIST
+FfxUInt32 LoadBricksMergeList(FfxUInt32 elementIdx)
+{
+ return rw_bctx_bricks_merge_list.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_MERGE_LIST
+void StoreBricksMergeList(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_bricks_merge_list.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_COUNTERS
+FfxUInt32 LoadBricksEikonalCounters(FfxUInt32 elementIdx)
+{
+ return rw_bctx_bricks_eikonal_counters.data[elementIdx & FFX_BRIXELIZER_BRICK_ID_MASK];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_BRICKS_EIKONAL_COUNTERS
+void StoreBricksEikonalCounters(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_bricks_eikonal_counters.data[elementIdx & FFX_BRIXELIZER_BRICK_ID_MASK] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_COUNTERS
+FfxUInt32 LoadContextCounter(FfxUInt32 elementIdx)
+{
+ return rw_bctx_counters.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_COUNTERS
+void StoreContextCounter(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_bctx_counters.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CONTEXT_COUNTERS
+void IncrementContextCounter(FfxUInt32 elementIdx, FfxUInt32 value, inout FfxUInt32 originalValue)
+{
+ originalValue = atomicAdd(rw_bctx_counters.data[elementIdx], value);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE
+FfxFloat32x3 LoadCascadeAABBTreeFloat3(FfxUInt32 elementIdx)
+{
+ return FfxFloat32x3(uintBitsToFloat(rw_cascade_aabbtree.data[elementIdx + 0]),
+ uintBitsToFloat(rw_cascade_aabbtree.data[elementIdx + 1]),
+ uintBitsToFloat(rw_cascade_aabbtree.data[elementIdx + 2]));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE
+FfxUInt32 LoadCascadeAABBTreeUInt(FfxUInt32 elementIdx)
+{
+ return rw_cascade_aabbtree.data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE
+void StoreCascadeAABBTreeUInt(FfxUInt32 elementIdx, FfxUInt32 value)
+{
+ rw_cascade_aabbtree.data[elementIdx] = value;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE
+void StoreCascadeAABBTreeFloat3(FfxUInt32 elementIdx, FfxFloat32x3 value)
+{
+ rw_cascade_aabbtree.data[elementIdx + 0] = floatBitsToUint(value.x);
+ rw_cascade_aabbtree.data[elementIdx + 1] = floatBitsToUint(value.y);
+ rw_cascade_aabbtree.data[elementIdx + 2] = floatBitsToUint(value.z);
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREES
+FfxFloat32x3 LoadCascadeAABBTreesFloat3(FfxUInt32 cascadeID, FfxUInt32 elementIdx)
+{
+ return FfxFloat32x3(uintBitsToFloat(rw_cascade_aabbtrees[cascadeID].data[elementIdx + 0]),
+ uintBitsToFloat(rw_cascade_aabbtrees[cascadeID].data[elementIdx + 1]),
+ uintBitsToFloat(rw_cascade_aabbtrees[cascadeID].data[elementIdx + 2]));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREES
+FfxUInt32 LoadCascadeAABBTreesUInt(FfxUInt32 cascadeID, FfxUInt32 elementIdx)
+{
+ return rw_cascade_aabbtrees[cascadeID].data[elementIdx];
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SDF_ATLAS
+FfxFloat32 LoadSDFAtlas(FfxUInt32x3 coord)
+{
+ return imageLoad(rw_sdf_atlas, FfxInt32x3(coord)).x;
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SDF_ATLAS
+void StoreSDFAtlas(FfxUInt32x3 coord, FfxFloat32 value)
+{
+ imageStore(rw_sdf_atlas, FfxInt32x3(coord), FfxFloat32x4(value, 0.0f, 0.0f, 0.0f));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_DEBUG_OUTPUT
+void StoreDebugOutput(FfxUInt32x2 coord, FfxFloat32x3 outputValue)
+{
+ imageStore(rw_debug_output, FfxInt32x2(coord), FfxFloat32x4(outputValue, 1.0f));
+}
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_DEBUG_OUTPUT
+void GetDebugOutputDimensions(inout FfxUInt32 width, inout FfxUInt32 height)
+{
+ FfxInt32x2 size = imageSize(rw_debug_output);
+ width = FfxUInt32(size.x);
+ height = FfxUInt32(size.y);
+}
+#endif
+
+#endif // #if defined(FFX_GPU)
+
+#endif // FFX_BRIXELIZER_CALLBACKS_GLSL_H
\ No newline at end of file
diff --git a/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_hlsl.h b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_hlsl.h
new file mode 100644
index 00000000..91a4ccc4
--- /dev/null
+++ b/Kits/AMDTK/fidelityfx/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_hlsl.h
@@ -0,0 +1,1188 @@
+// This file is part of the FidelityFX SDK.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFX_BRIXELIZER_CALLBACKS_HLSL_H
+#define FFX_BRIXELIZER_CALLBACKS_HLSL_H
+
+#include "ffx_brixelizer_resources.h"
+#include "ffx_brixelizer_host_gpu_shared.h"
+#include "ffx_brixelizer_host_gpu_shared_private.h"
+
+#if defined(FFX_GPU)
+#ifndef FFX_PREFER_WAVE64
+#define FFX_PREFER_WAVE64
+#endif // #ifndef FFX_PREFER_WAVE64
+
+#define FFX_BRIXELIZER_SIZEOF_UINT 4
+
+#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
+#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
+#define DECLARE_CB_REGISTER(regIndex) b##regIndex
+#define FFX_BRIXELIZER_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
+#define FFX_BRIXELIZER_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
+#define FFX_BRIXELIZER_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
+#define FFX_BRIXELIZER_DECLARE_STATIC_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex), space1)
+
+#define FFX_BRIXELIZER_ROOTSIG_STRINGIFY(p) FFX_BRIXELIZER_ROOTSIG_STR(p)
+#define FFX_BRIXELIZER_ROOTSIG_STR(p) #p
+#define FFX_BRIXELIZER_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_BRIXELIZER_ROOTSIG_STRINGIFY(FFX_BRIXELIZER_RESOURCE_IDENTIFIER_COUNT) ")), " \
+ "DescriptorTable(SRV(t0, numDescriptors = " FFX_BRIXELIZER_ROOTSIG_STRINGIFY(FFX_BRIXELIZER_RESOURCE_IDENTIFIER_COUNT) ")), " \
+ "DescriptorTable(Sampler(s0)), " \
+ "CBV(b0), " \
+ "CBV(b1), " \
+ "CBV(b2), " \
+ "CBV(b3)")]
+#define FFX_BRIXELIZER_VOXELIZE_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_BRIXELIZER_ROOTSIG_STRINGIFY(FFX_BRIXELIZER_RESOURCE_IDENTIFIER_COUNT) ")), " \
+ "DescriptorTable(SRV(t0, numDescriptors = " FFX_BRIXELIZER_ROOTSIG_STRINGIFY(FFX_BRIXELIZER_RESOURCE_IDENTIFIER_COUNT) ")), " \
+ "DescriptorTable(SRV(t0, space = 1, numDescriptors = unbounded)), " \
+ "DescriptorTable(Sampler(s0)), " \
+ "CBV(b0), " \
+ "CBV(b1), " \
+ "CBV(b2), " \
+ "CBV(b3)")]
+
+#if defined(FFX_BRIXELIZER_EMBED_ROOTSIG)
+#define FFX_BRIXELIZER_EMBED_ROOTSIG_CONTENT FFX_BRIXELIZER_ROOTSIG
+#define FFX_BRIXELIZER_EMBED_VOXELIZE_ROOTSIG_CONTENT FFX_BRIXELIZER_VOXELIZE_ROOTSIG
+#else
+#define FFX_BRIXELIZER_EMBED_ROOTSIG_CONTENT
+#define FFX_BRIXELIZER_EMBED_VOXELIZE_ROOTSIG_CONTENT
+#endif // #if FFX_BRIXELIZER_EMBED_ROOTSIG
+
+// CBVs
+
+#if defined BRIXELIZER_BIND_CB_CASCADE_INFO
+ ConstantBuffer cbBrixelizerCascadeInfo : FFX_BRIXELIZER_DECLARE_CB(BRIXELIZER_BIND_CB_CASCADE_INFO);
+#endif
+
+#if defined BRIXELIZER_BIND_CB_CONTEXT_INFO
+ ConstantBuffer cbBrixelizerContextInfo : FFX_BRIXELIZER_DECLARE_CB(BRIXELIZER_BIND_CB_CONTEXT_INFO);
+#endif
+
+#if defined BRIXELIZER_BIND_CB_BUILD_INFO
+ ConstantBuffer cbBrixelizerBuildInfo : FFX_BRIXELIZER_DECLARE_CB(BRIXELIZER_BIND_CB_BUILD_INFO);
+#endif
+
+#if defined BRIXELIZER_BIND_CB_DEBUG_INFO
+ ConstantBuffer cbBrixelizerDebugInfo : FFX_BRIXELIZER_DECLARE_CB(BRIXELIZER_BIND_CB_DEBUG_INFO);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_DEBUG_AABBS
+ RWStructuredBuffer rw_debug_aabbs : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_DEBUG_AABBS);
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_DEBUG_INSTANCE_ID_BUFFER
+ StructuredBuffer r_debug_instance_id : FFX_BRIXELIZER_DECLARE_SRV(BRIXELIZER_BIND_SRV_DEBUG_INSTANCE_ID_BUFFER);
+#endif
+
+// SRVs
+
+#if defined BRIXELIZER_BIND_SRV_JOB_BUFFER
+ StructuredBuffer r_job_buffer : FFX_BRIXELIZER_DECLARE_SRV(BRIXELIZER_BIND_SRV_JOB_BUFFER);
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_JOB_INDEX_BUFFER
+ StructuredBuffer r_job_index_buffer : FFX_BRIXELIZER_DECLARE_SRV(BRIXELIZER_BIND_SRV_JOB_INDEX_BUFFER);
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_INSTANCE_INFO_BUFFER
+ StructuredBuffer r_instance_info_buffer : FFX_BRIXELIZER_DECLARE_SRV(BRIXELIZER_BIND_SRV_INSTANCE_INFO_BUFFER);
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_INSTANCE_TRANSFORM_BUFFER
+ StructuredBuffer r_instance_transform_buffer : FFX_BRIXELIZER_DECLARE_SRV(BRIXELIZER_BIND_SRV_INSTANCE_TRANSFORM_BUFFER);
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_VERTEX_BUFFERS
+ StructuredBuffer r_vertex_buffers[FFX_BRIXELIZER_STATIC_CONFIG_MAX_VERTEX_BUFFERS] : FFX_BRIXELIZER_DECLARE_STATIC_SRV(BRIXELIZER_BIND_SRV_VERTEX_BUFFERS);
+#endif
+
+#if defined BRIXELIZER_BIND_SRV_SDF_ATLAS
+ Texture3D r_sdf_atlas : FFX_BRIXELIZER_DECLARE_SRV(BRIXELIZER_BIND_SRV_SDF_ATLAS);
+#endif
+
+// UAVs
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE
+ RWStructuredBuffer rw_cascade_aabbtree : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_CASCADE_AABB_TREE);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAP
+ RWStructuredBuffer rw_cascade_brick_map : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_CASCADE_BRICK_MAP);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_COUNTERS
+ RWStructuredBuffer rw_scratch_counters : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_COUNTERS);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP
+ RWStructuredBuffer rw_scratch_index_swap : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_INDEX_SWAP);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_VOXEL_ALLOCATION_FAIL_COUNTER
+ RWStructuredBuffer rw_scratch_voxel_allocation_fail_counter : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_VOXEL_ALLOCATION_FAIL_COUNTER);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE
+ RWStructuredBuffer rw_scratch_bricks_storage : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE_OFFSETS
+ RWStructuredBuffer rw_scratch_bricks_storage_offsets : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_STORAGE_OFFSETS);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_COMPRESSION_LIST
+ RWStructuredBuffer rw_scratch_bricks_compression_list : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_COMPRESSION_LIST);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_CLEAR_LIST
+ RWStructuredBuffer rw_scratch_bricks_clear_list : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_BRICKS_CLEAR_LIST);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS
+ RWStructuredBuffer rw_scratch_job_counters : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS_SCAN
+ RWStructuredBuffer rw_scratch_job_counters_scan : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_JOB_COUNTERS_SCAN);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_JOB_GLOBAL_COUNTERS_SCAN
+ RWStructuredBuffer rw_scratch_job_global_counters_scan : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_JOB_GLOBAL_COUNTERS_SCAN);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REFERENCES
+ RWStructuredBuffer rw_scratch_cr1_references : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_CR1_REFERENCES);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_COMPACTED_REFERENCES
+ RWStructuredBuffer rw_scratch_cr1_compacted_references : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_CR1_COMPACTED_REFERENCES);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTERS
+ RWStructuredBuffer rw_scratch_cr1_ref_counters : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTERS);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTER_SCAN
+ RWStructuredBuffer rw_scratch_cr1_ref_counter_scan : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_COUNTER_SCAN);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_GLOBAL_SCAN
+ RWStructuredBuffer rw_scratch_cr1_ref_global_scan : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_CR1_REF_GLOBAL_SCAN);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_SCAN
+ RWStructuredBuffer rw_scratch_cr1_stamp_scan : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_SCAN);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_GLOBAL_SCAN
+ RWStructuredBuffer rw_scratch_cr1_stamp_global_scan : FFX_BRIXELIZER_DECLARE_UAV(BRIXELIZER_BIND_UAV_SCRATCH_CR1_STAMP_GLOBAL_SCAN);
+#endif
+
+#if defined BRIXELIZER_BIND_UAV_INDIRECT_ARGS
+ RWStructuredBuffer