├── .gitattributes ├── .gitignore ├── Bin ├── Assets │ ├── bunny.obj │ ├── dragon.obj │ └── venusm.obj ├── BinRaster.cso ├── ComputeRaster.exe ├── Dragon.bat ├── PixelRaster.cso ├── TileRaster.cso ├── VSStage.cso ├── VSStageIndexed.cso ├── Venusm.bat └── XUSG.dll ├── ComputeRaster.sln ├── ComputeRaster ├── Common │ ├── DXFramework.cpp │ ├── DXFramework.h │ ├── DXFrameworkHelper.h │ ├── DirectX-Graphics-Samples │ │ └── LICENSE │ ├── StepTimer.h │ ├── Win32Application.cpp │ ├── Win32Application.h │ ├── d3d12.h │ ├── d3d12 │ │ ├── LICENSE-CODE.txt │ │ └── LICENSE.txt │ ├── d3dcommon.h │ ├── dxgiformat.h │ ├── stb │ │ └── LICENSE │ ├── stb_image_write.cpp │ └── stb_image_write.h ├── ComputeRaster.cpp ├── ComputeRaster.h ├── ComputeRaster.vcxproj ├── ComputeRaster.vcxproj.filters ├── ComputeRaster.vcxproj.user ├── Content │ ├── Renderer.cpp │ ├── Renderer.h │ ├── Shaders │ │ ├── BinRaster.hlsl │ │ ├── Common.hlsli │ │ ├── DeclareAttributes.hlsli │ │ ├── DeclareTargets.hlsli │ │ ├── PixelRaster.hlsl │ │ ├── PixelShader.hlsl │ │ ├── SetAttributes.hlsli │ │ ├── SetTargets.hlsli │ │ ├── TileRaster.hlsl │ │ ├── VSStage.hlsl │ │ ├── VSStage.hlsli │ │ ├── VSStageIndexed.hlsl │ │ └── VertexShader.hlsl │ ├── SharedConst.h │ ├── SoftGraphicsPipeline.cpp │ └── SoftGraphicsPipeline.h ├── Main.cpp ├── XUSG │ ├── Bin │ │ ├── Debug │ │ │ ├── XUSG.dll │ │ │ ├── XUSG.lib │ │ │ └── XUSG.pdb │ │ ├── Release │ │ │ ├── XUSG.dll │ │ │ └── XUSG.lib │ │ └── x64 │ │ │ ├── Debug │ │ │ ├── XUSG.dll │ │ │ ├── XUSG.lib │ │ │ └── XUSG.pdb │ │ │ └── Release │ │ │ ├── XUSG.dll │ │ │ └── XUSG.lib │ ├── Core │ │ └── XUSG.h │ └── Optional │ │ ├── XUSGObjLoader.cpp │ │ └── XUSGObjLoader.h ├── stdafx.cpp └── stdafx.h ├── Doc └── Images │ ├── Bunny.jpg │ └── Venus.jpg └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | //*.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/* 15 | */[Dd]ebug/* 16 | [Dd]ebugPublic/ 17 | [Rr]elease/* 18 | */[Rr]elease/* 19 | [Rr]eleases/ 20 | x64/* 21 | */x64/* 22 | x86/ 23 | bld/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # DNX 46 | project.lock.json 47 | artifacts/ 48 | 49 | *_i.c 50 | *_p.c 51 | *_i.h 52 | *.ilk 53 | *.iobj 54 | *.ipdb 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.res 62 | *.rsp 63 | *.sbr 64 | *.tlb 65 | *.tli 66 | *.tlh 67 | *.tmp 68 | *.tmp_proj 69 | *.log 70 | *.vspscc 71 | *.vssscc 72 | .builds 73 | *.pidb 74 | *.svclog 75 | *.scc 76 | 77 | # Chutzpah Test files 78 | _Chutzpah* 79 | 80 | # Visual C++ cache files 81 | ipch/ 82 | *.aps 83 | *.ncb 84 | *.opendb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | *.VC.db 89 | *.VC.VC.opendb 90 | 91 | # Visual Studio profiler 92 | *.psess 93 | *.vsp 94 | *.vspx 95 | *.sap 96 | 97 | # TFS 2012 Local Workspace 98 | $tf/ 99 | 100 | # Guidance Automation Toolkit 101 | *.gpState 102 | 103 | # ReSharper is a .NET coding add-in 104 | _ReSharper*/ 105 | *.[Rr]e[Ss]harper 106 | *.DotSettings.user 107 | 108 | # JustCode is a .NET coding add-in 109 | .JustCode 110 | 111 | # TeamCity is a build add-in 112 | _TeamCity* 113 | 114 | # DotCover is a Code Coverage Tool 115 | *.dotCover 116 | 117 | # NCrunch 118 | _NCrunch_* 119 | .*crunch*.local.xml 120 | nCrunchTemp_* 121 | 122 | # MightyMoose 123 | *.mm.* 124 | AutoTest.Net/ 125 | 126 | # Web workbench (sass) 127 | .sass-cache/ 128 | 129 | # Installshield output folder 130 | [Ee]xpress/ 131 | 132 | # DocProject is a documentation generator add-in 133 | DocProject/buildhelp/ 134 | DocProject/Help/*.HxT 135 | DocProject/Help/*.HxC 136 | DocProject/Help/*.hhc 137 | DocProject/Help/*.hhk 138 | DocProject/Help/*.hhp 139 | DocProject/Help/Html2 140 | DocProject/Help/html 141 | 142 | # Click-Once directory 143 | publish/ 144 | 145 | # Publish Web Output 146 | *.[Pp]ublish.xml 147 | *.azurePubxml 148 | # TODO: Comment the next line if you want to checkin your web deploy settings 149 | # but database connection strings (with potential passwords) will be unencrypted 150 | *.pubxml 151 | *.publishproj 152 | 153 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 154 | # checkin your Azure Web App publish settings, but sensitive information contained 155 | # in these scripts will be unencrypted 156 | PublishScripts/ 157 | 158 | # NuGet Packages 159 | *.nupkg 160 | # The packages folder can be ignored because of Package Restore 161 | **/packages/* 162 | # except build/, which is used as an MSBuild target. 163 | !**/packages/build/ 164 | # Uncomment if necessary however generally it will be regenerated when needed 165 | #!**/packages/repositories.config 166 | # NuGet v3's project.json files produces more ignoreable files 167 | *.nuget.props 168 | *.nuget.targets 169 | 170 | # Microsoft Azure Build Output 171 | csx/ 172 | *.build.csdef 173 | 174 | # Microsoft Azure Emulator 175 | ecf/ 176 | rcf/ 177 | 178 | # Windows Store app package directories and files 179 | AppPackages/ 180 | BundleArtifacts/ 181 | Package.StoreAssociation.xml 182 | _pkginfo.txt 183 | 184 | # Visual Studio cache files 185 | # files ending in .cache can be ignored 186 | *.[Cc]ache 187 | # but keep track of directories ending in .cache 188 | !*.[Cc]ache/ 189 | 190 | # Others 191 | ClientBin/ 192 | ~$* 193 | *~ 194 | *.dbmdl 195 | *.dbproj.schemaview 196 | *.pfx 197 | *.publishsettings 198 | node_modules/ 199 | orleans.codegen.cs 200 | 201 | # Since there are multiple workflows, uncomment next line to ignore bower_components 202 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 203 | #bower_components/ 204 | 205 | # RIA/Silverlight projects 206 | Generated_Code/ 207 | 208 | # Backup & report files from converting an old project file 209 | # to a newer Visual Studio version. Backup files are not needed, 210 | # because we have git ;-) 211 | _UpgradeReport_Files/ 212 | Backup*/ 213 | UpgradeLog*.XML 214 | UpgradeLog*.htm 215 | 216 | # SQL Server files 217 | *.mdf 218 | *.ldf 219 | 220 | # Business Intelligence projects 221 | *.rdl.data 222 | *.bim.layout 223 | *.bim_*.settings 224 | 225 | # Microsoft Fakes 226 | FakesAssemblies/ 227 | 228 | # GhostDoc plugin setting file 229 | *.GhostDoc.xml 230 | 231 | # Node.js Tools for Visual Studio 232 | .ntvs_analysis.dat 233 | 234 | # Visual Studio 6 build log 235 | *.plg 236 | 237 | # Visual Studio 6 workspace options file 238 | *.opt 239 | 240 | # Visual Studio LightSwitch build output 241 | **/*.HTMLClient/GeneratedArtifacts 242 | **/*.DesktopClient/GeneratedArtifacts 243 | **/*.DesktopClient/ModelManifest.xml 244 | **/*.Server/GeneratedArtifacts 245 | **/*.Server/ModelManifest.xml 246 | _Pvt_Extensions 247 | 248 | # Paket dependency manager 249 | .paket/paket.exe 250 | paket-files/ 251 | 252 | # FAKE - F# Make 253 | .fake/ 254 | 255 | # JetBrains Rider 256 | .idea/ 257 | *.sln.iml 258 | 259 | # ========================= 260 | # Operating System Files 261 | # ========================= 262 | 263 | # OSX 264 | # ========================= 265 | 266 | .DS_Store 267 | .AppleDouble 268 | .LSOverride 269 | 270 | # Thumbnails 271 | ._* 272 | 273 | # Files that might appear in the root of a volume 274 | .DocumentRevisions-V100 275 | .fseventsd 276 | .Spotlight-V100 277 | .TemporaryItems 278 | .Trashes 279 | .VolumeIcon.icns 280 | 281 | # Directories potentially created on remote AFP share 282 | .AppleDB 283 | .AppleDesktop 284 | Network Trash Folder 285 | Temporary Items 286 | .apdisk 287 | 288 | # Windows 289 | # ========================= 290 | 291 | # Windows image file caches 292 | Thumbs.db 293 | ehthumbs.db 294 | 295 | # Folder config file 296 | Desktop.ini 297 | 298 | # Recycle Bin used on file shares 299 | $RECYCLE.BIN/ 300 | 301 | # Windows Installer files 302 | *.cab 303 | *.msi 304 | *.msm 305 | *.msp 306 | 307 | # Windows shortcuts 308 | *.lnk 309 | 310 | !XUSG.pdb 311 | !Bin/*/*.[Oo]bj 312 | -------------------------------------------------------------------------------- /Bin/BinRaster.cso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Bin/BinRaster.cso -------------------------------------------------------------------------------- /Bin/ComputeRaster.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Bin/ComputeRaster.exe -------------------------------------------------------------------------------- /Bin/Dragon.bat: -------------------------------------------------------------------------------- 1 | start ComputeRaster.exe -mesh Assets/dragon.obj 2 | -------------------------------------------------------------------------------- /Bin/PixelRaster.cso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Bin/PixelRaster.cso -------------------------------------------------------------------------------- /Bin/TileRaster.cso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Bin/TileRaster.cso -------------------------------------------------------------------------------- /Bin/VSStage.cso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Bin/VSStage.cso -------------------------------------------------------------------------------- /Bin/VSStageIndexed.cso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Bin/VSStageIndexed.cso -------------------------------------------------------------------------------- /Bin/Venusm.bat: -------------------------------------------------------------------------------- 1 | start ComputeRaster.exe -mesh Assets/Venusm.obj 0.0 0.0 0.0 0.003 2 | -------------------------------------------------------------------------------- /Bin/XUSG.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Bin/XUSG.dll -------------------------------------------------------------------------------- /ComputeRaster.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29519.87 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ComputeRaster", "ComputeRaster\ComputeRaster.vcxproj", "{39499F0E-A75D-4C90-990F-3C0965BAAC7A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Debug|x64.ActiveCfg = Debug|x64 17 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Debug|x64.Build.0 = Debug|x64 18 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Debug|x86.ActiveCfg = Debug|Win32 19 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Debug|x86.Build.0 = Debug|Win32 20 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Release|x64.ActiveCfg = Release|x64 21 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Release|x64.Build.0 = Release|x64 22 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Release|x86.ActiveCfg = Release|Win32 23 | {39499F0E-A75D-4C90-990F-3C0965BAAC7A}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {5A8B8310-EB2C-4CE6-9880-4A7C18BF57BF} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ComputeRaster/Common/DXFramework.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "DXFramework.h" 13 | 14 | using namespace Microsoft::WRL; 15 | 16 | DXFramework::DXFramework(uint32_t width, uint32_t height, std::wstring name) : 17 | m_width(width), 18 | m_height(height), 19 | m_title(name) 20 | { 21 | WCHAR assetsPath[512]; 22 | GetAssetsPath(assetsPath, _countof(assetsPath)); 23 | m_assetsPath = assetsPath; 24 | 25 | m_aspectRatio = static_cast(width) / static_cast(height); 26 | } 27 | 28 | DXFramework::~DXFramework() 29 | { 30 | } 31 | 32 | // Helper function for resolving the full path of assets. 33 | std::wstring DXFramework::GetAssetFullPath(LPCWSTR assetName) 34 | { 35 | return m_assetsPath + assetName; 36 | } 37 | 38 | // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. 39 | // If no such adapter can be found, *ppAdapter will be set to nullptr. 40 | _Use_decl_annotations_ 41 | void DXFramework::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) 42 | { 43 | ComPtr adapter; 44 | *ppAdapter = nullptr; 45 | 46 | for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) 47 | { 48 | DXGI_ADAPTER_DESC1 desc; 49 | adapter->GetDesc1(&desc); 50 | 51 | if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) 52 | { 53 | // Don't select the Basic Render Driver adapter. 54 | // If you want a software adapter, pass in "/warp" on the command line. 55 | continue; 56 | } 57 | 58 | // Check to see if the adapter supports Direct3D 12, but don't create the 59 | // actual device yet. 60 | if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) 61 | { 62 | break; 63 | } 64 | } 65 | 66 | *ppAdapter = adapter.Detach(); 67 | } 68 | 69 | // Helper function for setting the window's title text. 70 | void DXFramework::SetCustomWindowText(LPCWSTR text) 71 | { 72 | std::wstring windowText = m_title + L": " + text; 73 | SetWindowText(Win32Application::GetHwnd(), windowText.c_str()); 74 | } 75 | 76 | // Helper function for parsing any supplied command line args. 77 | _Use_decl_annotations_ 78 | void DXFramework::ParseCommandLineArgs(WCHAR* argv[], int argc) 79 | { 80 | } 81 | -------------------------------------------------------------------------------- /ComputeRaster/Common/DXFramework.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | #include "DXFrameworkHelper.h" 15 | #include "Win32Application.h" 16 | 17 | class DXFramework 18 | { 19 | public: 20 | DXFramework(uint32_t width, uint32_t height, std::wstring name); 21 | virtual ~DXFramework(); 22 | 23 | virtual void OnInit() = 0; 24 | virtual void OnUpdate() = 0; 25 | virtual void OnRender() = 0; 26 | virtual void OnDestroy() = 0; 27 | 28 | virtual void OnSuspending() {} 29 | virtual void OnResuming() {} 30 | virtual void OnWindowMoved() {} 31 | virtual void OnWindowSizeChanged(int width, int height) {} 32 | 33 | // Samples override the event handlers to handle specific messages. 34 | virtual void OnKeyDown(uint8_t /*key*/) {} 35 | virtual void OnKeyUp(uint8_t /*key*/) {} 36 | 37 | virtual void OnLButtonDown(float posX, float posY) {} 38 | virtual void OnLButtonUp(float posX, float posY) {} 39 | virtual void OnRButtonDown(float posX, float posY) {} 40 | virtual void OnRButtonUp(float posX, float posY) {} 41 | virtual void OnMouseMove(float posX, float posY) {} 42 | virtual void OnMouseWheel(float deltaZ, float posX, float posY) {} 43 | virtual void OnMouseLeave() {} 44 | 45 | // Accessors. 46 | uint32_t GetWidth() const { return m_width; } 47 | uint32_t GetHeight() const { return m_height; } 48 | const WCHAR* GetTitle() const { return m_title.c_str(); } 49 | 50 | virtual void ParseCommandLineArgs(_In_reads_(argc) WCHAR* argv[], int argc); 51 | 52 | protected: 53 | std::wstring GetAssetFullPath(LPCWSTR assetName); 54 | void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); 55 | void SetCustomWindowText(LPCWSTR text); 56 | 57 | // Viewport dimensions. 58 | uint32_t m_width; 59 | uint32_t m_height; 60 | float m_aspectRatio; 61 | 62 | // Window title. 63 | std::wstring m_title; 64 | 65 | private: 66 | // Root assets path. 67 | std::wstring m_assetsPath; 68 | }; 69 | -------------------------------------------------------------------------------- /ComputeRaster/Common/DXFrameworkHelper.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | // Note that while ComPtr is used to manage the lifetime of resources on the CPU, 15 | // it has no understanding of the lifetime of resources on the GPU. Apps must account 16 | // for the GPU lifetime of resources to avoid destroying objects that may still be 17 | // referenced by the GPU. 18 | using Microsoft::WRL::ComPtr; 19 | 20 | inline std::string HrToString(HRESULT hr) 21 | { 22 | char s_str[64] = {}; 23 | sprintf_s(s_str, "HRESULT of 0x%08X", static_cast(hr)); 24 | return std::string(s_str); 25 | } 26 | 27 | class HrException : public std::runtime_error 28 | { 29 | public: 30 | HrException(HRESULT hr) : std::runtime_error(HrToString(hr)), m_hr(hr) {} 31 | HRESULT Error() const { return m_hr; } 32 | private: 33 | const HRESULT m_hr; 34 | }; 35 | 36 | #define SAFE_RELEASE(p) if (p) (p)->Release() 37 | 38 | inline void ThrowIfFailed(HRESULT hr) 39 | { 40 | if (FAILED(hr)) 41 | { 42 | throw HrException(hr); 43 | } 44 | } 45 | 46 | inline void GetAssetsPath(_Out_writes_(pathSize) WCHAR* path, UINT pathSize) 47 | { 48 | if (path == nullptr) 49 | { 50 | throw std::exception(); 51 | } 52 | 53 | DWORD size = GetModuleFileName(nullptr, path, pathSize); 54 | if (size == 0 || size == pathSize) 55 | { 56 | // Method failed or path was truncated. 57 | throw std::exception(); 58 | } 59 | 60 | WCHAR* lastSlash = wcsrchr(path, L'\\'); 61 | if (lastSlash) 62 | { 63 | *(lastSlash + 1) = L'\0'; 64 | } 65 | } 66 | 67 | inline HRESULT ReadDataFromFile(LPCWSTR filename, byte** data, UINT* size) 68 | { 69 | using namespace Microsoft::WRL; 70 | 71 | CREATEFILE2_EXTENDED_PARAMETERS extendedParams = {}; 72 | extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); 73 | extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; 74 | extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN; 75 | extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; 76 | extendedParams.lpSecurityAttributes = nullptr; 77 | extendedParams.hTemplateFile = nullptr; 78 | 79 | Wrappers::FileHandle file(CreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extendedParams)); 80 | if (file.Get() == INVALID_HANDLE_VALUE) 81 | { 82 | throw std::exception(); 83 | } 84 | 85 | FILE_STANDARD_INFO fileInfo = {}; 86 | if (!GetFileInformationByHandleEx(file.Get(), FileStandardInfo, &fileInfo, sizeof(fileInfo))) 87 | { 88 | throw std::exception(); 89 | } 90 | 91 | if (fileInfo.EndOfFile.HighPart != 0) 92 | { 93 | throw std::exception(); 94 | } 95 | 96 | *data = reinterpret_cast(malloc(fileInfo.EndOfFile.LowPart)); 97 | *size = fileInfo.EndOfFile.LowPart; 98 | 99 | if (!ReadFile(file.Get(), *data, fileInfo.EndOfFile.LowPart, nullptr, nullptr)) 100 | { 101 | throw std::exception(); 102 | } 103 | 104 | return S_OK; 105 | } 106 | 107 | // Assign a name to the object to aid with debugging. 108 | #if defined(_DEBUG) || defined(DBG) 109 | inline void SetName(ID3D12Object* pObject, LPCWSTR name) 110 | { 111 | pObject->SetName(name); 112 | } 113 | inline void SetNameIndexed(ID3D12Object* pObject, LPCWSTR name, UINT index) 114 | { 115 | WCHAR fullName[50]; 116 | if (swprintf_s(fullName, L"%s[%u]", name, index) > 0) 117 | { 118 | pObject->SetName(fullName); 119 | } 120 | } 121 | #else 122 | inline void SetName(ID3D12Object*, LPCWSTR) 123 | { 124 | } 125 | inline void SetNameIndexed(ID3D12Object*, LPCWSTR, UINT) 126 | { 127 | } 128 | #endif 129 | 130 | // Naming helper for ComPtr. 131 | // Assigns the name of the variable as the name of the object. 132 | // The indexed variant will include the index in the name of the object. 133 | #define NAME_D3D12_OBJECT(x) SetName((x).Get(), L#x) 134 | #define NAME_D3D12_OBJECT_INDEXED(x, n) SetNameIndexed((x)[n].Get(), L#x, n) 135 | 136 | inline UINT CalculateConstantBufferByteSize(UINT byteSize) 137 | { 138 | // Constant buffer size is required to be aligned. 139 | return (byteSize + (D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1)) & ~(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1); 140 | } 141 | 142 | #ifdef D3D_COMPILE_STANDARD_FILE_INCLUDE 143 | inline Microsoft::WRL::ComPtr CompileShader( 144 | const std::wstring& filename, 145 | const D3D_SHADER_MACRO* defines, 146 | const std::string& entrypoint, 147 | const std::string& target) 148 | { 149 | UINT compileFlags = 0; 150 | #if defined(_DEBUG) || defined(DBG) 151 | compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; 152 | #endif 153 | 154 | HRESULT hr; 155 | 156 | Microsoft::WRL::ComPtr byteCode = nullptr; 157 | Microsoft::WRL::ComPtr errors; 158 | hr = D3DCompileFromFile(filename.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, 159 | entrypoint.c_str(), target.c_str(), compileFlags, 0, &byteCode, &errors); 160 | 161 | if (errors != nullptr) 162 | { 163 | OutputDebugStringA((char*)errors->GetBufferPointer()); 164 | } 165 | ThrowIfFailed(hr); 166 | 167 | return byteCode; 168 | } 169 | #endif 170 | 171 | // Resets all elements in a ComPtr array. 172 | template 173 | void ResetComPtrArray(T* comPtrArray) 174 | { 175 | for (auto &i : *comPtrArray) 176 | { 177 | i.Reset(); 178 | } 179 | } 180 | 181 | 182 | // Resets all elements in a unique_ptr array. 183 | template 184 | void ResetUniquePtrArray(T* uniquePtrArray) 185 | { 186 | for (auto &i : *uniquePtrArray) 187 | { 188 | i.reset(); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /ComputeRaster/Common/DirectX-Graphics-Samples/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /ComputeRaster/Common/StepTimer.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | // Helper class for animation and simulation timing. 15 | class StepTimer 16 | { 17 | public: 18 | StepTimer() : 19 | m_elapsedTicks(0), 20 | m_totalTicks(0), 21 | m_leftOverTicks(0), 22 | m_frameCount(0), 23 | m_framesPerSecond(0), 24 | m_framesThisSecond(0), 25 | m_qpcSecondCounter(0), 26 | m_isFixedTimeStep(false), 27 | m_targetElapsedTicks(TicksPerSecond / 60) 28 | { 29 | QueryPerformanceFrequency(&m_qpcFrequency); 30 | QueryPerformanceCounter(&m_qpcLastTime); 31 | 32 | // Initialize max delta to a second. 33 | m_qpcMaxDelta = m_qpcFrequency.QuadPart; 34 | } 35 | 36 | // Get elapsed time since the previous Update call. 37 | UINT64 GetElapsedTicks() const { return m_elapsedTicks; } 38 | double GetElapsedSeconds() const { return TicksToSeconds(m_elapsedTicks); } 39 | 40 | // Get total time since the start of the program. 41 | UINT64 GetTotalTicks() const { return m_totalTicks; } 42 | double GetTotalSeconds() const { return TicksToSeconds(m_totalTicks); } 43 | 44 | // Get total number of updates since start of the program. 45 | UINT32 GetFrameCount() const { return m_frameCount; } 46 | 47 | // Get the current framerate. 48 | UINT32 GetFramesPerSecond() const { return m_framesPerSecond; } 49 | 50 | // Set whether to use fixed or variable timestep mode. 51 | void SetFixedTimeStep(bool isFixedTimestep) { m_isFixedTimeStep = isFixedTimestep; } 52 | 53 | // Set how often to call Update when in fixed timestep mode. 54 | void SetTargetElapsedTicks(UINT64 targetElapsed) { m_targetElapsedTicks = targetElapsed; } 55 | void SetTargetElapsedSeconds(double targetElapsed) { m_targetElapsedTicks = SecondsToTicks(targetElapsed); } 56 | 57 | // Integer format represents time using 10,000,000 ticks per second. 58 | static const UINT64 TicksPerSecond = 10000000; 59 | 60 | static double TicksToSeconds(UINT64 ticks) { return static_cast(ticks) / TicksPerSecond; } 61 | static UINT64 SecondsToTicks(double seconds) { return static_cast(seconds * TicksPerSecond); } 62 | 63 | // After an intentional timing discontinuity (for instance a blocking IO operation) 64 | // call this to avoid having the fixed timestep logic attempt a set of catch-up 65 | // Update calls. 66 | 67 | void ResetElapsedTime() 68 | { 69 | QueryPerformanceCounter(&m_qpcLastTime); 70 | 71 | m_leftOverTicks = 0; 72 | m_framesPerSecond = 0; 73 | m_framesThisSecond = 0; 74 | m_qpcSecondCounter = 0; 75 | } 76 | 77 | typedef void(*LPUPDATEFUNC) (void); 78 | 79 | // Update timer state, calling the specified Update function the appropriate number of times. 80 | void Tick(LPUPDATEFUNC update = nullptr) 81 | { 82 | // Query the current time. 83 | LARGE_INTEGER currentTime; 84 | 85 | QueryPerformanceCounter(¤tTime); 86 | 87 | UINT64 timeDelta = currentTime.QuadPart - m_qpcLastTime.QuadPart; 88 | 89 | m_qpcLastTime = currentTime; 90 | m_qpcSecondCounter += timeDelta; 91 | 92 | // Clamp excessively large time deltas (e.g. after paused in the debugger). 93 | if (timeDelta > m_qpcMaxDelta) 94 | { 95 | timeDelta = m_qpcMaxDelta; 96 | } 97 | 98 | // Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp. 99 | timeDelta *= TicksPerSecond; 100 | timeDelta /= m_qpcFrequency.QuadPart; 101 | 102 | UINT32 lastFrameCount = m_frameCount; 103 | 104 | if (m_isFixedTimeStep) 105 | { 106 | // Fixed timestep update logic 107 | 108 | // If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp 109 | // the clock to exactly match the target value. This prevents tiny and irrelevant errors 110 | // from accumulating over time. Without this clamping, a game that requested a 60 fps 111 | // fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually 112 | // accumulate enough tiny errors that it would drop a frame. It is better to just round 113 | // small deviations down to zero to leave things running smoothly. 114 | 115 | if (abs(static_cast(timeDelta - m_targetElapsedTicks)) < TicksPerSecond / 4000) 116 | { 117 | timeDelta = m_targetElapsedTicks; 118 | } 119 | 120 | m_leftOverTicks += timeDelta; 121 | 122 | while (m_leftOverTicks >= m_targetElapsedTicks) 123 | { 124 | m_elapsedTicks = m_targetElapsedTicks; 125 | m_totalTicks += m_targetElapsedTicks; 126 | m_leftOverTicks -= m_targetElapsedTicks; 127 | m_frameCount++; 128 | 129 | if (update) 130 | { 131 | update(); 132 | } 133 | } 134 | } 135 | else 136 | { 137 | // Variable timestep update logic. 138 | m_elapsedTicks = timeDelta; 139 | m_totalTicks += timeDelta; 140 | m_leftOverTicks = 0; 141 | m_frameCount++; 142 | 143 | if (update) 144 | { 145 | update(); 146 | } 147 | } 148 | 149 | // Track the current framerate. 150 | if (m_frameCount != lastFrameCount) 151 | { 152 | m_framesThisSecond++; 153 | } 154 | 155 | if (m_qpcSecondCounter >= static_cast(m_qpcFrequency.QuadPart)) 156 | { 157 | m_framesPerSecond = m_framesThisSecond; 158 | m_framesThisSecond = 0; 159 | m_qpcSecondCounter %= m_qpcFrequency.QuadPart; 160 | } 161 | } 162 | 163 | private: 164 | // Source timing data uses QPC units. 165 | LARGE_INTEGER m_qpcFrequency; 166 | LARGE_INTEGER m_qpcLastTime; 167 | UINT64 m_qpcMaxDelta; 168 | 169 | // Derived timing data uses a canonical tick format. 170 | UINT64 m_elapsedTicks; 171 | UINT64 m_totalTicks; 172 | UINT64 m_leftOverTicks; 173 | 174 | // Members for tracking the framerate. 175 | UINT32 m_frameCount; 176 | UINT32 m_framesPerSecond; 177 | UINT32 m_framesThisSecond; 178 | UINT64 m_qpcSecondCounter; 179 | 180 | // Members for configuring fixed timestep mode. 181 | bool m_isFixedTimeStep; 182 | UINT64 m_targetElapsedTicks; 183 | }; 184 | -------------------------------------------------------------------------------- /ComputeRaster/Common/Win32Application.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include 13 | #include "Win32Application.h" 14 | 15 | HWND Win32Application::m_hwnd = nullptr; 16 | 17 | int Win32Application::Run(DXFramework *pFramework, HINSTANCE hInstance, int nCmdShow, HICON hIcon) 18 | { 19 | // Parse the command line parameters 20 | int argc; 21 | const auto argv = CommandLineToArgvW(GetCommandLineW(), &argc); 22 | pFramework->ParseCommandLineArgs(argv, argc); 23 | LocalFree(argv); 24 | 25 | // Initialize the window class. 26 | WNDCLASSEX windowClass = { 0 }; 27 | windowClass.cbSize = sizeof(WNDCLASSEX); 28 | windowClass.style = CS_HREDRAW | CS_VREDRAW; 29 | windowClass.lpfnWndProc = WindowProc; 30 | windowClass.hInstance = hInstance; 31 | windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); 32 | windowClass.lpszClassName = L"DXFrameworkClass"; 33 | RegisterClassEx(&windowClass); 34 | 35 | RECT windowRect = { 0, 0, static_cast(pFramework->GetWidth()), static_cast(pFramework->GetHeight()) }; 36 | AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); 37 | 38 | // Create the window and store a handle to it. 39 | m_hwnd = CreateWindow( 40 | windowClass.lpszClassName, 41 | pFramework->GetTitle(), 42 | WS_OVERLAPPEDWINDOW, 43 | CW_USEDEFAULT, 44 | CW_USEDEFAULT, 45 | windowRect.right - windowRect.left, 46 | windowRect.bottom - windowRect.top, 47 | nullptr, // We have no parent window. 48 | nullptr, // We aren't using menus. 49 | hInstance, 50 | pFramework); 51 | 52 | if (hIcon) 53 | { 54 | SendMessage(m_hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 55 | SendMessage(m_hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); 56 | } 57 | 58 | // Initialize the sample. OnInit is defined in each child-implementation of DXSample. 59 | pFramework->OnInit(); 60 | 61 | ShowWindow(m_hwnd, nCmdShow); 62 | 63 | // Main sample loop. 64 | MSG msg = {}; 65 | while (msg.message != WM_QUIT) 66 | { 67 | // Process any messages in the queue. 68 | if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) 69 | { 70 | TranslateMessage(&msg); 71 | DispatchMessage(&msg); 72 | } 73 | } 74 | 75 | pFramework->OnDestroy(); 76 | 77 | // Return this part of the WM_QUIT message to Windows. 78 | return static_cast(msg.wParam); 79 | } 80 | 81 | // Main message handler for the sample. 82 | LRESULT CALLBACK Win32Application::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 83 | { 84 | static bool s_in_sizemove = false; 85 | static bool s_in_suspend = false; 86 | static bool s_minimized = false; 87 | static bool s_fullscreen = false; 88 | // Set s_fullscreen to true if defaulting to fullscreen. 89 | 90 | static uint32_t s_width = 0; 91 | static uint32_t s_height = 0; 92 | 93 | const auto pFramework = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); 94 | 95 | switch (message) 96 | { 97 | case WM_CREATE: 98 | { 99 | // Save the DXSample* passed in to CreateWindow. 100 | LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); 101 | SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); 102 | } 103 | return 0; 104 | 105 | case WM_MOVE: 106 | if (pFramework) 107 | pFramework->OnWindowMoved(); 108 | return 0; 109 | 110 | case WM_SIZE: 111 | if (wParam == SIZE_MINIMIZED) 112 | { 113 | if (!s_minimized) 114 | { 115 | s_minimized = true; 116 | if (!s_in_suspend && pFramework) 117 | pFramework->OnSuspending(); 118 | s_in_suspend = true; 119 | } 120 | } 121 | else if (s_minimized) 122 | { 123 | s_minimized = false; 124 | if (s_in_suspend && pFramework) 125 | pFramework->OnResuming(); 126 | s_in_suspend = false; 127 | } 128 | else if (!s_in_sizemove && pFramework) 129 | { 130 | s_width = LOWORD(lParam); 131 | s_height = HIWORD(lParam); 132 | pFramework->OnWindowSizeChanged(s_width, s_height); 133 | } 134 | return 0; 135 | 136 | case WM_ENTERSIZEMOVE: 137 | s_in_sizemove = true; 138 | return 0; 139 | 140 | case WM_EXITSIZEMOVE: 141 | s_in_sizemove = false; 142 | if (pFramework) 143 | { 144 | RECT rc; 145 | GetClientRect(hWnd, &rc); 146 | 147 | const auto w = rc.right - rc.left; 148 | const auto h = rc.bottom - rc.top; 149 | 150 | if (s_width != w || s_height != h) 151 | { 152 | pFramework->OnWindowSizeChanged(w, h); 153 | s_width = w; 154 | s_height = h; 155 | } 156 | } 157 | return 0; 158 | 159 | case WM_KEYDOWN: 160 | if (pFramework) pFramework->OnKeyDown(static_cast(wParam)); 161 | return 0; 162 | 163 | case WM_KEYUP: 164 | if (pFramework) pFramework->OnKeyUp(static_cast(wParam)); 165 | return 0; 166 | 167 | case WM_LBUTTONDOWN: 168 | if (pFramework) 169 | pFramework->OnLButtonDown(static_cast(GET_X_LPARAM(lParam)), static_cast(GET_Y_LPARAM(lParam))); 170 | return 0; 171 | 172 | case WM_LBUTTONUP: 173 | if (pFramework) 174 | pFramework->OnLButtonUp(static_cast(GET_X_LPARAM(lParam)), static_cast(GET_Y_LPARAM(lParam))); 175 | return 0; 176 | 177 | case WM_RBUTTONDOWN: 178 | if (pFramework) 179 | pFramework->OnRButtonDown(static_cast(GET_X_LPARAM(lParam)), static_cast(GET_Y_LPARAM(lParam))); 180 | return 0; 181 | 182 | case WM_RBUTTONUP: 183 | if (pFramework) 184 | pFramework->OnRButtonUp(static_cast(GET_X_LPARAM(lParam)), static_cast(GET_Y_LPARAM(lParam))); 185 | return 0; 186 | 187 | case WM_MOUSEMOVE: 188 | if (pFramework) 189 | pFramework->OnMouseMove(static_cast(GET_X_LPARAM(lParam)), static_cast(GET_Y_LPARAM(lParam))); 190 | { 191 | TRACKMOUSEEVENT csTME = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, hWnd }; 192 | TrackMouseEvent(&csTME); 193 | } 194 | return 0; 195 | 196 | case WM_MOUSELEAVE: 197 | if (pFramework) pFramework->OnMouseLeave(); 198 | return 0; 199 | 200 | case WM_MOUSEWHEEL: 201 | if (pFramework) pFramework->OnMouseWheel(static_cast(GET_WHEEL_DELTA_WPARAM(wParam)) / WHEEL_DELTA, 202 | static_cast(GET_X_LPARAM(lParam)), static_cast(GET_Y_LPARAM(lParam))); 203 | return 0; 204 | 205 | case WM_PAINT: 206 | if (pFramework) 207 | { 208 | pFramework->OnUpdate(); 209 | pFramework->OnRender(); 210 | } 211 | return 0; 212 | 213 | case WM_DESTROY: 214 | PostQuitMessage(0); 215 | return 0; 216 | } 217 | 218 | // Handle any messages the switch statement didn't. 219 | return DefWindowProc(hWnd, message, wParam, lParam); 220 | } 221 | -------------------------------------------------------------------------------- /ComputeRaster/Common/Win32Application.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | #include "DXFramework.h" 15 | 16 | class DXFramework; 17 | 18 | class Win32Application 19 | { 20 | public: 21 | static int Run(DXFramework *pFramework, HINSTANCE hInstance, int nCmdShow, HICON hIcon = nullptr); 22 | static HWND GetHwnd() { return m_hwnd; } 23 | 24 | protected: 25 | static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 26 | 27 | private: 28 | static HWND m_hwnd; 29 | }; 30 | -------------------------------------------------------------------------------- /ComputeRaster/Common/d3d12/LICENSE-CODE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /ComputeRaster/Common/d3d12/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MICROSOFT SOFTWARE LICENSE TERMS 2 | 3 | MICROSOFT DIRECTX 4 | 5 | These license terms are an agreement between you and Microsoft 6 | Corporation (or one of its affiliates). They apply to the software named 7 | above and any Microsoft services or software updates (except to the 8 | extent such services or updates are accompanied by new or additional 9 | terms, in which case those different terms apply prospectively and do 10 | not alter your or Microsoft’s rights relating to pre-updated software or 11 | services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS 12 | BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. 13 | 14 | INSTALLATION AND USE RIGHTS. 15 | 16 | General. Subject to the terms of this agreement, you may install and use any number of copies of the software, and solely for use on Windows. 17 | 18 | Included Microsoft Applications. The software may include other Microsoft applications. These license terms apply to those included applications, if any, unless other license terms are provided with the other Microsoft applications. 19 | 20 | Microsoft Platforms. The software may include components from Microsoft Windows. These components are governed by separate agreements and their own product support policies, as described in the license terms found in the installation directory for that component or in the “Licenses” folder accompanying the software. 21 | 22 | Third Party Components. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software. 23 | 24 | DATA. 25 | 26 | Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation.  There are also some features in the software that may enable you to collect data from users of your applications. If you use these features to enable data collection in your applications, you must comply with applicable law, including providing appropriate notices to users of your applications. You can learn more about data collection and use in the help documentation and the privacy statement at https://aka.ms/privacy. Your use of the software operates as your consent to these practices. 27 | 28 | Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at https://docs.microsoft.com/en-us/legal/gdpr. 29 | 30 | DISTRIBUTABLE CODE. The software may contain code you are permitted to distribute (i.e. make available for third parties) in applications you develop, as described in this Section. 31 | 32 | Distribution Rights. The code and test files described below are distributable if included with the software. 33 | 34 | Distributables. You may copy and distribute the object code form of the software listed in the distributables file list in the software; and 35 | 36 | Third Party Distribution. You may permit distributors of your applications to copy and distribute any of this distributable code you elect to distribute with your applications. 37 | 38 | Distribution Requirements. For any code you distribute, you must: 39 | 40 | add significant primary functionality to it in your applications; 41 | 42 | i. require distributors and external end users to agree to terms that protect it and Microsoft at least as much as this agreement; and 43 | 44 | ii. indemnify, defend, and hold harmless Microsoft from any claims, including attorneys’ fees, related to the distribution or use of your applications, except to the extent that any claim is based solely on the unmodified distributable code. 45 | 46 | Distribution Restrictions. You may not: 47 | 48 | use Microsoft’s trademarks or trade dress in your application in any way that suggests your application comes from or is endorsed by Microsoft; or modify or distribute the source code of any distributable code so that any part of it becomes subject to any license that requires that the distributable code, any other part of the software, or any of Microsoft’s other intellectual property be disclosed or distributed in source code form, or that others have the right to modify it. 49 | 50 | SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you will not (and have no right to): 51 | 52 | work around any technical limitations in the software that only allow you to use it in certain ways; 53 | 54 | reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software; 55 | 56 | remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software; 57 | 58 | use the software in any way that is against the law or to create or propagate malware; or 59 | 60 | share, publish, distribute, or lease the software (except for any distributable code, subject to the terms above), provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party. 61 | 62 | EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit https://aka.ms/exporting. 63 | 64 | SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for the software. Any support provided is “as is”, “with all faults”, and without warranty of any kind. 65 | 66 | UPDATES. The software may periodically check for updates, and download and install them for you. You may obtain updates only from Microsoft or authorized sources. Microsoft may need to update your system to provide you with updates. You agree to receive these automatic updates without any additional notice. Updates may not include or support all existing software features, services, or peripheral devices. 67 | 68 | ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements, updates, or third-party applications, is the entire agreement for the software. 69 | 70 | APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United States or Canada, the laws of the state or province where you live (or, if a business, where your principal place of business is located) govern the interpretation of this agreement, claims for its breach, and all other claims (including consumer protection, unfair competition, and tort claims), regardless of conflict of laws principles. If you acquired the software in any other country, its laws apply. If U.S. federal jurisdiction exists, you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, Washington for all disputes heard in court. If not, you and Microsoft consent to exclusive jurisdiction and venue in the Superior Court of King County, Washington for all disputes heard in court. 71 | 72 | CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you: 73 | 74 | a. Australia. You have statutory guarantees under the Australian 75 | Consumer Law and nothing in this agreement is intended to affect 76 | those rights. 77 | 78 | b. Canada. If you acquired this software in Canada, you may stop 79 | receiving updates by turning off the automatic update feature, 80 | disconnecting your device from the Internet (if and when you 81 | re-connect to the Internet, however, the software will resume 82 | checking for and installing updates), or uninstalling the software. 83 | The product documentation, if any, may also specify how to turn off 84 | updates for your specific device or software. 85 | 86 | c. Germany and Austria. 87 | 88 | i. Warranty. The properly licensed software will perform substantially 89 | as described in any Microsoft materials that accompany the software. 90 | However, Microsoft gives no contractual guarantee in relation to the 91 | licensed software. 92 | 93 | ii. Limitation of Liability. In case of intentional conduct, gross 94 | negligence, claims based on the Product Liability Act, as well as, in 95 | case of death or personal or physical injury, Microsoft is liable 96 | according to the statutory law. 97 | 98 | Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence. 99 | 100 | DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 101 | 102 | LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT, OR INCIDENTAL DAMAGES. 103 | 104 | This limitation applies to (a) anything related to the software, 105 | services, content (including code) on third party Internet sites, or 106 | third party applications; and (b) claims for breach of contract, 107 | warranty, guarantee, or condition; strict liability, negligence, or 108 | other tort; or any other claim; in each case to the extent permitted by 109 | applicable law. 110 | 111 | It also applies even if Microsoft knew or should have known about the 112 | possibility of the damages. The above limitation or exclusion may not 113 | apply to you because your state, province, or country may not allow the 114 | exclusion or limitation of incidental, consequential, or other damages. 115 | 116 | Please note: As this software is distributed in Canada, some of the 117 | clauses in this agreement are provided below in French. 118 | 119 | Remarque: Ce logiciel étant distribué au Canada, certaines des clauses 120 | dans ce contrat sont fournies ci-dessous en français. 121 | 122 | EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « 123 | tel quel ». Toute utilisation de ce logiciel est à votre seule risque et 124 | péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez 125 | bénéficier de droits additionnels en vertu du droit local sur la 126 | protection des consommateurs, que ce contrat ne peut modifier. La ou 127 | elles sont permises par le droit locale, les garanties implicites de 128 | qualité marchande, d’adéquation à un usage particulier et d’absence de 129 | contrefaçon sont exclues. 130 | 131 | LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES 132 | DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une 133 | indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ 134 | US. Vous ne pouvez prétendre à aucune indemnisation pour les autres 135 | dommages, y compris les dommages spéciaux, indirects ou accessoires et 136 | pertes de bénéfices. 137 | 138 | Cette limitation concerne: 139 | 140 | • tout ce qui est relié au logiciel, aux services ou au contenu (y 141 | compris le code) figurant sur des sites Internet tiers ou dans des 142 | programmes tiers; et 143 | 144 | • les réclamations au titre de violation de contrat ou de garantie, ou 145 | au titre de responsabilité stricte, de négligence ou d’une autre faute 146 | dans la limite autorisée par la loi en vigueur. 147 | 148 | Elle s’applique également, même si Microsoft connaissait ou devrait 149 | connaître l’éventualité d’un tel dommage. Si votre pays n’autorise pas 150 | l’exclusion ou la limitation de responsabilité pour les dommages 151 | indirects, accessoires ou de quelque nature que ce soit, il se peut que 152 | la limitation ou l’exclusion ci-dessus ne s’appliquera pas à votre 153 | égard. 154 | 155 | EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. 156 | Vous pourriez avoir d’autres droits prévus par les lois de votre pays. 157 | Le présent contrat ne modifie pas les droits que vous confèrent les lois 158 | de votre pays si celles-ci ne le permettent pas. 159 | -------------------------------------------------------------------------------- /ComputeRaster/Common/dxgiformat.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) Microsoft Corporation. 3 | // Licensed under the MIT license 4 | // 5 | 6 | #ifndef __dxgiformat_h__ 7 | #define __dxgiformat_h__ 8 | 9 | #define DXGI_FORMAT_DEFINED 1 10 | 11 | typedef enum DXGI_FORMAT 12 | { 13 | DXGI_FORMAT_UNKNOWN = 0, 14 | DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, 15 | DXGI_FORMAT_R32G32B32A32_FLOAT = 2, 16 | DXGI_FORMAT_R32G32B32A32_UINT = 3, 17 | DXGI_FORMAT_R32G32B32A32_SINT = 4, 18 | DXGI_FORMAT_R32G32B32_TYPELESS = 5, 19 | DXGI_FORMAT_R32G32B32_FLOAT = 6, 20 | DXGI_FORMAT_R32G32B32_UINT = 7, 21 | DXGI_FORMAT_R32G32B32_SINT = 8, 22 | DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, 23 | DXGI_FORMAT_R16G16B16A16_FLOAT = 10, 24 | DXGI_FORMAT_R16G16B16A16_UNORM = 11, 25 | DXGI_FORMAT_R16G16B16A16_UINT = 12, 26 | DXGI_FORMAT_R16G16B16A16_SNORM = 13, 27 | DXGI_FORMAT_R16G16B16A16_SINT = 14, 28 | DXGI_FORMAT_R32G32_TYPELESS = 15, 29 | DXGI_FORMAT_R32G32_FLOAT = 16, 30 | DXGI_FORMAT_R32G32_UINT = 17, 31 | DXGI_FORMAT_R32G32_SINT = 18, 32 | DXGI_FORMAT_R32G8X24_TYPELESS = 19, 33 | DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, 34 | DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, 35 | DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, 36 | DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, 37 | DXGI_FORMAT_R10G10B10A2_UNORM = 24, 38 | DXGI_FORMAT_R10G10B10A2_UINT = 25, 39 | DXGI_FORMAT_R11G11B10_FLOAT = 26, 40 | DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, 41 | DXGI_FORMAT_R8G8B8A8_UNORM = 28, 42 | DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, 43 | DXGI_FORMAT_R8G8B8A8_UINT = 30, 44 | DXGI_FORMAT_R8G8B8A8_SNORM = 31, 45 | DXGI_FORMAT_R8G8B8A8_SINT = 32, 46 | DXGI_FORMAT_R16G16_TYPELESS = 33, 47 | DXGI_FORMAT_R16G16_FLOAT = 34, 48 | DXGI_FORMAT_R16G16_UNORM = 35, 49 | DXGI_FORMAT_R16G16_UINT = 36, 50 | DXGI_FORMAT_R16G16_SNORM = 37, 51 | DXGI_FORMAT_R16G16_SINT = 38, 52 | DXGI_FORMAT_R32_TYPELESS = 39, 53 | DXGI_FORMAT_D32_FLOAT = 40, 54 | DXGI_FORMAT_R32_FLOAT = 41, 55 | DXGI_FORMAT_R32_UINT = 42, 56 | DXGI_FORMAT_R32_SINT = 43, 57 | DXGI_FORMAT_R24G8_TYPELESS = 44, 58 | DXGI_FORMAT_D24_UNORM_S8_UINT = 45, 59 | DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, 60 | DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, 61 | DXGI_FORMAT_R8G8_TYPELESS = 48, 62 | DXGI_FORMAT_R8G8_UNORM = 49, 63 | DXGI_FORMAT_R8G8_UINT = 50, 64 | DXGI_FORMAT_R8G8_SNORM = 51, 65 | DXGI_FORMAT_R8G8_SINT = 52, 66 | DXGI_FORMAT_R16_TYPELESS = 53, 67 | DXGI_FORMAT_R16_FLOAT = 54, 68 | DXGI_FORMAT_D16_UNORM = 55, 69 | DXGI_FORMAT_R16_UNORM = 56, 70 | DXGI_FORMAT_R16_UINT = 57, 71 | DXGI_FORMAT_R16_SNORM = 58, 72 | DXGI_FORMAT_R16_SINT = 59, 73 | DXGI_FORMAT_R8_TYPELESS = 60, 74 | DXGI_FORMAT_R8_UNORM = 61, 75 | DXGI_FORMAT_R8_UINT = 62, 76 | DXGI_FORMAT_R8_SNORM = 63, 77 | DXGI_FORMAT_R8_SINT = 64, 78 | DXGI_FORMAT_A8_UNORM = 65, 79 | DXGI_FORMAT_R1_UNORM = 66, 80 | DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, 81 | DXGI_FORMAT_R8G8_B8G8_UNORM = 68, 82 | DXGI_FORMAT_G8R8_G8B8_UNORM = 69, 83 | DXGI_FORMAT_BC1_TYPELESS = 70, 84 | DXGI_FORMAT_BC1_UNORM = 71, 85 | DXGI_FORMAT_BC1_UNORM_SRGB = 72, 86 | DXGI_FORMAT_BC2_TYPELESS = 73, 87 | DXGI_FORMAT_BC2_UNORM = 74, 88 | DXGI_FORMAT_BC2_UNORM_SRGB = 75, 89 | DXGI_FORMAT_BC3_TYPELESS = 76, 90 | DXGI_FORMAT_BC3_UNORM = 77, 91 | DXGI_FORMAT_BC3_UNORM_SRGB = 78, 92 | DXGI_FORMAT_BC4_TYPELESS = 79, 93 | DXGI_FORMAT_BC4_UNORM = 80, 94 | DXGI_FORMAT_BC4_SNORM = 81, 95 | DXGI_FORMAT_BC5_TYPELESS = 82, 96 | DXGI_FORMAT_BC5_UNORM = 83, 97 | DXGI_FORMAT_BC5_SNORM = 84, 98 | DXGI_FORMAT_B5G6R5_UNORM = 85, 99 | DXGI_FORMAT_B5G5R5A1_UNORM = 86, 100 | DXGI_FORMAT_B8G8R8A8_UNORM = 87, 101 | DXGI_FORMAT_B8G8R8X8_UNORM = 88, 102 | DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, 103 | DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, 104 | DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, 105 | DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, 106 | DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, 107 | DXGI_FORMAT_BC6H_TYPELESS = 94, 108 | DXGI_FORMAT_BC6H_UF16 = 95, 109 | DXGI_FORMAT_BC6H_SF16 = 96, 110 | DXGI_FORMAT_BC7_TYPELESS = 97, 111 | DXGI_FORMAT_BC7_UNORM = 98, 112 | DXGI_FORMAT_BC7_UNORM_SRGB = 99, 113 | DXGI_FORMAT_AYUV = 100, 114 | DXGI_FORMAT_Y410 = 101, 115 | DXGI_FORMAT_Y416 = 102, 116 | DXGI_FORMAT_NV12 = 103, 117 | DXGI_FORMAT_P010 = 104, 118 | DXGI_FORMAT_P016 = 105, 119 | DXGI_FORMAT_420_OPAQUE = 106, 120 | DXGI_FORMAT_YUY2 = 107, 121 | DXGI_FORMAT_Y210 = 108, 122 | DXGI_FORMAT_Y216 = 109, 123 | DXGI_FORMAT_NV11 = 110, 124 | DXGI_FORMAT_AI44 = 111, 125 | DXGI_FORMAT_IA44 = 112, 126 | DXGI_FORMAT_P8 = 113, 127 | DXGI_FORMAT_A8P8 = 114, 128 | DXGI_FORMAT_B4G4R4A4_UNORM = 115, 129 | 130 | DXGI_FORMAT_P208 = 130, 131 | DXGI_FORMAT_V208 = 131, 132 | DXGI_FORMAT_V408 = 132, 133 | 134 | 135 | DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189, 136 | DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190, 137 | 138 | DXGI_FORMAT_A4B4G4R4_UNORM = 191, 139 | 140 | 141 | DXGI_FORMAT_FORCE_UINT = 0xffffffff 142 | } DXGI_FORMAT; 143 | 144 | #endif // __dxgiformat_h__ 145 | -------------------------------------------------------------------------------- /ComputeRaster/Common/stb/LICENSE: -------------------------------------------------------------------------------- 1 | This software is available under 2 licenses -- choose whichever you prefer. 2 | ------------------------------------------------------------------------------ 3 | ALTERNATIVE A - MIT License 4 | Copyright (c) 2017 Sean Barrett 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | ------------------------------------------------------------------------------ 21 | ALTERNATIVE B - Public Domain (www.unlicense.org) 22 | This is free and unencumbered software released into the public domain. 23 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 24 | software, either in source code form or as a compiled binary, for any purpose, 25 | commercial or non-commercial, and by any means. 26 | In jurisdictions that recognize copyright laws, the author or authors of this 27 | software dedicate any and all copyright interest in the software to the public 28 | domain. We make this dedication for the benefit of the public at large and to 29 | the detriment of our heirs and successors. We intend this dedication to be an 30 | overt act of relinquishment in perpetuity of all present and future rights to 31 | this software under copyright law. 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 35 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 36 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 37 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 38 | -------------------------------------------------------------------------------- /ComputeRaster/Common/stb_image_write.cpp: -------------------------------------------------------------------------------- 1 | /* stb_image_write - v1.16 - public domain - http://nothings.org/stb 2 | writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 3 | no warranty implied; use at your own risk 4 | 5 | Before #including, 6 | 7 | #define STB_IMAGE_WRITE_IMPLEMENTATION 8 | 9 | in the file that you want to have the implementation. 10 | 11 | Will probably not work correctly with strict-aliasing optimizations. 12 | 13 | ABOUT: 14 | 15 | This header file is a library for writing images to C stdio or a callback. 16 | 17 | The PNG output is not optimal; it is 20-50% larger than the file 18 | written by a decent optimizing implementation; though providing a custom 19 | zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. 20 | This library is designed for source code compactness and simplicity, 21 | not optimal image file size or run-time performance. 22 | 23 | BUILDING: 24 | 25 | You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. 26 | You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace 27 | malloc,realloc,free. 28 | You can #define STBIW_MEMMOVE() to replace memmove() 29 | You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function 30 | for PNG compression (instead of the builtin one), it must have the following signature: 31 | unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); 32 | The returned data will be freed with STBIW_FREE() (free() by default), 33 | so it must be heap allocated with STBIW_MALLOC() (malloc() by default), 34 | 35 | UNICODE: 36 | 37 | If compiling for Windows and you wish to use Unicode filenames, compile 38 | with 39 | #define STBIW_WINDOWS_UTF8 40 | and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert 41 | Windows wchar_t filenames to utf8. 42 | 43 | USAGE: 44 | 45 | There are five functions, one for each image file format: 46 | 47 | int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 48 | int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); 49 | int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); 50 | int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); 51 | int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); 52 | 53 | void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically 54 | 55 | There are also five equivalent functions that use an arbitrary write function. You are 56 | expected to open/close your file-equivalent before and after calling these: 57 | 58 | int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); 59 | int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 60 | int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 61 | int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); 62 | int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); 63 | 64 | where the callback is: 65 | void stbi_write_func(void *context, void *data, int size); 66 | 67 | You can configure it with these global variables: 68 | int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE 69 | int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression 70 | int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode 71 | 72 | 73 | You can define STBI_WRITE_NO_STDIO to disable the file variant of these 74 | functions, so the library will not use stdio.h at all. However, this will 75 | also disable HDR writing, because it requires stdio for formatted output. 76 | 77 | Each function returns 0 on failure and non-0 on success. 78 | 79 | The functions create an image file defined by the parameters. The image 80 | is a rectangle of pixels stored from left-to-right, top-to-bottom. 81 | Each pixel contains 'comp' channels of data stored interleaved with 8-bits 82 | per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is 83 | monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. 84 | The *data pointer points to the first byte of the top-left-most pixel. 85 | For PNG, "stride_in_bytes" is the distance in bytes from the first byte of 86 | a row of pixels to the first byte of the next row of pixels. 87 | 88 | PNG creates output files with the same number of components as the input. 89 | The BMP format expands Y to RGB in the file format and does not 90 | output alpha. 91 | 92 | PNG supports writing rectangles of data even when the bytes storing rows of 93 | data are not consecutive in memory (e.g. sub-rectangles of a larger image), 94 | by supplying the stride between the beginning of adjacent rows. The other 95 | formats do not. (Thus you cannot write a native-format BMP through the BMP 96 | writer, both because it is in BGR order and because it may have padding 97 | at the end of the line.) 98 | 99 | PNG allows you to set the deflate compression level by setting the global 100 | variable 'stbi_write_png_compression_level' (it defaults to 8). 101 | 102 | HDR expects linear float data. Since the format is always 32-bit rgb(e) 103 | data, alpha (if provided) is discarded, and for monochrome data it is 104 | replicated across all three channels. 105 | 106 | TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed 107 | data, set the global variable 'stbi_write_tga_with_rle' to 0. 108 | 109 | JPEG does ignore alpha channels in input data; quality is between 1 and 100. 110 | Higher quality looks better but results in a bigger image. 111 | JPEG baseline (no JPEG progressive). 112 | 113 | CREDITS: 114 | 115 | 116 | Sean Barrett - PNG/BMP/TGA 117 | Baldur Karlsson - HDR 118 | Jean-Sebastien Guay - TGA monochrome 119 | Tim Kelsey - misc enhancements 120 | Alan Hickman - TGA RLE 121 | Emmanuel Julien - initial file IO callback implementation 122 | Jon Olick - original jo_jpeg.cpp code 123 | Daniel Gibson - integrate JPEG, allow external zlib 124 | Aarni Koskela - allow choosing PNG filter 125 | 126 | bugfixes: 127 | github:Chribba 128 | Guillaume Chereau 129 | github:jry2 130 | github:romigrou 131 | Sergio Gonzalez 132 | Jonas Karlsson 133 | Filip Wasil 134 | Thatcher Ulrich 135 | github:poppolopoppo 136 | Patrick Boettcher 137 | github:xeekworx 138 | Cap Petschulat 139 | Simon Rodriguez 140 | Ivan Tikhonov 141 | github:ignotion 142 | Adam Schackart 143 | Andrew Kensler 144 | 145 | LICENSE 146 | 147 | See end of file for license information. 148 | 149 | */ 150 | 151 | #define STB_IMAGE_WRITE_IMPLEMENTATION 152 | #define __STDC_LIB_EXT1__ 153 | #include "stb_image_write.h" 154 | 155 | /* 156 | ------------------------------------------------------------------------------ 157 | This software is available under 2 licenses -- choose whichever you prefer. 158 | ------------------------------------------------------------------------------ 159 | ALTERNATIVE A - MIT License 160 | Copyright (c) 2017 Sean Barrett 161 | Permission is hereby granted, free of charge, to any person obtaining a copy of 162 | this software and associated documentation files (the "Software"), to deal in 163 | the Software without restriction, including without limitation the rights to 164 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 165 | of the Software, and to permit persons to whom the Software is furnished to do 166 | so, subject to the following conditions: 167 | The above copyright notice and this permission notice shall be included in all 168 | copies or substantial portions of the Software. 169 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 170 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 172 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 173 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 174 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 175 | SOFTWARE. 176 | ------------------------------------------------------------------------------ 177 | ALTERNATIVE B - Public Domain (www.unlicense.org) 178 | This is free and unencumbered software released into the public domain. 179 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 180 | software, either in source code form or as a compiled binary, for any purpose, 181 | commercial or non-commercial, and by any means. 182 | In jurisdictions that recognize copyright laws, the author or authors of this 183 | software dedicate any and all copyright interest in the software to the public 184 | domain. We make this dedication for the benefit of the public at large and to 185 | the detriment of our heirs and successors. We intend this dedication to be an 186 | overt act of relinquishment in perpetuity of all present and future rights to 187 | this software under copyright law. 188 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 189 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 190 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 191 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 192 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 193 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 194 | ------------------------------------------------------------------------------ 195 | */ 196 | -------------------------------------------------------------------------------- /ComputeRaster/ComputeRaster.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "Optional/XUSGObjLoader.h" 13 | #include "ComputeRaster.h" 14 | #include "stb_image_write.h" 15 | 16 | using namespace std; 17 | using namespace XUSG; 18 | 19 | ComputeRaster::ComputeRaster(uint32_t width, uint32_t height, std::wstring name) : 20 | DXFramework(width, height, name), 21 | m_frameIndex(0), 22 | m_deviceType(DEVICE_DISCRETE), 23 | m_showFPS(true), 24 | m_isPaused(false), 25 | m_tracking(false), 26 | m_meshFileName("Assets/bunny.obj"), 27 | m_meshPosScale(0.0f, 0.0f, 0.0f, 1.0f), 28 | m_screenShot(0) 29 | { 30 | #if defined (_DEBUG) 31 | _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 32 | AllocConsole(); 33 | FILE* stream; 34 | freopen_s(&stream, "CONIN$", "r+t", stdin); 35 | freopen_s(&stream, "CONOUT$", "w+t", stdout); 36 | freopen_s(&stream, "CONOUT$", "w+t", stderr); 37 | #endif 38 | } 39 | 40 | ComputeRaster::~ComputeRaster() 41 | { 42 | #if defined (_DEBUG) 43 | FreeConsole(); 44 | #endif 45 | } 46 | 47 | void ComputeRaster::OnInit() 48 | { 49 | LoadPipeline(); 50 | LoadAssets(); 51 | } 52 | 53 | // Load the rendering pipeline dependencies. 54 | void ComputeRaster::LoadPipeline() 55 | { 56 | auto dxgiFactoryFlags = 0u; 57 | 58 | #if defined(_DEBUG) 59 | // Enable the debug layer (requires the Graphics Tools "optional feature"). 60 | // NOTE: Enabling the debug layer after device creation will invalidate the active device. 61 | { 62 | com_ptr debugController; 63 | if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) 64 | { 65 | debugController->EnableDebugLayer(); 66 | //debugController->SetEnableGPUBasedValidation(TRUE); 67 | 68 | // Enable additional debug layers. 69 | dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; 70 | } 71 | } 72 | #endif 73 | 74 | com_ptr factory; 75 | ThrowIfFailed(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory))); 76 | 77 | DXGI_ADAPTER_DESC1 dxgiAdapterDesc; 78 | com_ptr dxgiAdapter; 79 | const auto useUMA = m_deviceType == DEVICE_UMA; 80 | const auto useWARP = m_deviceType == DEVICE_WARP; 81 | auto checkUMA = true, checkWARP = true; 82 | auto hr = DXGI_ERROR_NOT_FOUND; 83 | for (uint8_t n = 0; n < 3; ++n) 84 | { 85 | if (FAILED(hr)) hr = DXGI_ERROR_UNSUPPORTED; 86 | for (auto i = 0u; hr == DXGI_ERROR_UNSUPPORTED; ++i) 87 | { 88 | dxgiAdapter = nullptr; 89 | hr = factory->EnumAdapters1(i, &dxgiAdapter); 90 | 91 | if (SUCCEEDED(hr) && dxgiAdapter) 92 | { 93 | dxgiAdapter->GetDesc1(&dxgiAdapterDesc); 94 | if (checkWARP) hr = dxgiAdapterDesc.VendorId == 0x1414 && dxgiAdapterDesc.DeviceId == 0x8c ? 95 | (useWARP ? hr : DXGI_ERROR_UNSUPPORTED) : (useWARP ? DXGI_ERROR_UNSUPPORTED : hr); 96 | } 97 | 98 | if (SUCCEEDED(hr)) 99 | { 100 | m_device = Device::MakeUnique(); 101 | if (SUCCEEDED(m_device->Create(dxgiAdapter.get(), D3D_FEATURE_LEVEL_11_0)) && checkUMA) 102 | { 103 | D3D12_FEATURE_DATA_ARCHITECTURE feature = {}; 104 | const auto pDevice = static_cast(m_device->GetHandle()); 105 | if (SUCCEEDED(pDevice->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &feature, sizeof(feature)))) 106 | hr = feature.UMA ? (useUMA ? hr : DXGI_ERROR_UNSUPPORTED) : (useUMA ? DXGI_ERROR_UNSUPPORTED : hr); 107 | } 108 | } 109 | } 110 | 111 | checkUMA = false; 112 | if (n) checkWARP = false; 113 | } 114 | 115 | if (dxgiAdapterDesc.VendorId == 0x1414 && dxgiAdapterDesc.DeviceId == 0x8c) m_title += L" (WARP)"; 116 | else if (dxgiAdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) m_title += L" (Software)"; 117 | //else m_title += wstring(L" - ") + dxgiAdapterDesc.Description; 118 | ThrowIfFailed(hr); 119 | 120 | // Create the command queue. 121 | m_commandQueue = CommandQueue::MakeUnique(); 122 | XUSG_N_RETURN(m_commandQueue->Create(m_device.get(), CommandListType::DIRECT, CommandQueueFlag::NONE, 123 | 0, 0, L"CommandQueue"), ThrowIfFailed(E_FAIL)); 124 | 125 | // Describe and create the swap chain. 126 | m_swapChain = SwapChain::MakeUnique(); 127 | XUSG_N_RETURN(m_swapChain->Create(factory.get(), Win32Application::GetHwnd(), m_commandQueue->GetHandle(), 128 | SoftGraphicsPipeline::FrameCount, m_width, m_height, Format::R8G8B8A8_UNORM, 129 | SwapChainFlag::ALLOW_TEARING), ThrowIfFailed(E_FAIL)); 130 | 131 | // This sample does not support fullscreen transitions. 132 | ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)); 133 | 134 | m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); 135 | 136 | // Create frame resources. 137 | // Create a RTV and a command allocator for each frame. 138 | for (uint8_t n = 0; n < SoftGraphicsPipeline::FrameCount; ++n) 139 | { 140 | m_renderTargets[n] = RenderTarget::MakeUnique(); 141 | XUSG_N_RETURN(m_renderTargets[n]->CreateFromSwapChain(m_device.get(), m_swapChain.get(), n), ThrowIfFailed(E_FAIL)); 142 | 143 | m_commandAllocators[n] = CommandAllocator::MakeUnique(); 144 | XUSG_N_RETURN(m_commandAllocators[n]->Create(m_device.get(), CommandListType::DIRECT, 145 | (L"CommandAllocator" + to_wstring(n)).c_str()), ThrowIfFailed(E_FAIL)); 146 | } 147 | } 148 | 149 | // Load the sample assets. 150 | void ComputeRaster::LoadAssets() 151 | { 152 | // Create the command list. 153 | m_commandList = CommandList::MakeUnique(); 154 | const auto pCommandList = m_commandList.get(); 155 | XUSG_N_RETURN(pCommandList->Create(m_device.get(), 0, CommandListType::DIRECT, 156 | m_commandAllocators[m_frameIndex].get(), nullptr), ThrowIfFailed(E_FAIL)); 157 | 158 | vector uploaders(0); 159 | XUSG_X_RETURN(m_renderer, make_unique(), ThrowIfFailed(E_FAIL)); 160 | XUSG_N_RETURN(m_renderer->Init(pCommandList, m_width, m_height, uploaders, 161 | m_meshFileName.c_str(), m_meshPosScale), ThrowIfFailed(E_FAIL)); 162 | 163 | // Close the command list and execute it to begin the initial GPU setup. 164 | XUSG_N_RETURN(pCommandList->Close(), ThrowIfFailed(E_FAIL)); 165 | m_commandQueue->ExecuteCommandList(pCommandList); 166 | 167 | // Create synchronization objects and wait until assets have been uploaded to the GPU. 168 | { 169 | if (!m_fence) 170 | { 171 | m_fence = Fence::MakeUnique(); 172 | XUSG_N_RETURN(m_fence->Create(m_device.get(), m_fenceValues[m_frameIndex]++, FenceFlag::NONE, L"Fence"), ThrowIfFailed(E_FAIL)); 173 | } 174 | 175 | // Create an event handle to use for frame synchronization. 176 | m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); 177 | if (!m_fenceEvent) ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); 178 | 179 | // Wait for the command list to execute; we are reusing the same command 180 | // list in our main loop but for now, we just want to wait for setup to 181 | // complete before continuing. 182 | WaitForGpu(); 183 | } 184 | 185 | // Projection 186 | const auto aspectRatio = m_width / static_cast(m_height); 187 | const auto proj = XMMatrixPerspectiveFovLH(g_FOVAngleY, aspectRatio, g_zNear, g_zFar); 188 | XMStoreFloat4x4(&m_proj, proj); 189 | 190 | // View initialization 191 | m_focusPt = XMFLOAT3(0.0f, 4.0f, 0.0f); 192 | m_eyePt = XMFLOAT3(0.0f, 8.0f, -20.0f); 193 | const auto focusPt = XMLoadFloat3(&m_focusPt); 194 | const auto eyePt = XMLoadFloat3(&m_eyePt); 195 | const auto view = XMMatrixLookAtLH(eyePt, focusPt, XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f)); 196 | XMStoreFloat4x4(&m_view, view); 197 | } 198 | 199 | // Update frame-based values. 200 | void ComputeRaster::OnUpdate() 201 | { 202 | // Timer 203 | static auto time = 0.0, pauseTime = 0.0; 204 | 205 | m_timer.Tick(); 206 | const auto totalTime = CalculateFrameStats(); 207 | pauseTime = m_isPaused ? totalTime - time : pauseTime; 208 | time = totalTime - pauseTime; 209 | 210 | // View 211 | const auto eyePt = XMLoadFloat3(&m_eyePt); 212 | const auto view = XMLoadFloat4x4(&m_view); 213 | const auto proj = XMLoadFloat4x4(&m_proj); 214 | m_renderer->UpdateFrame(m_frameIndex, view, proj, m_eyePt, time); 215 | } 216 | 217 | // Render the scene. 218 | void ComputeRaster::OnRender() 219 | { 220 | // Record all the commands we need to render the scene into the command list. 221 | PopulateCommandList(); 222 | 223 | // Execute the command list. 224 | m_commandQueue->ExecuteCommandList(m_commandList.get()); 225 | 226 | // Present the frame. 227 | XUSG_N_RETURN(m_swapChain->Present(0, PresentFlag::ALLOW_TEARING), ThrowIfFailed(E_FAIL)); 228 | 229 | MoveToNextFrame(); 230 | } 231 | 232 | void ComputeRaster::OnDestroy() 233 | { 234 | // Ensure that the GPU is no longer referencing resources that are about to be 235 | // cleaned up by the destructor. 236 | WaitForGpu(); 237 | 238 | CloseHandle(m_fenceEvent); 239 | } 240 | 241 | // User hot-key interactions. 242 | void ComputeRaster::OnKeyUp(uint8_t key) 243 | { 244 | switch (key) 245 | { 246 | case VK_SPACE: 247 | m_isPaused = !m_isPaused; 248 | break; 249 | case VK_F1: 250 | m_showFPS = !m_showFPS; 251 | break; 252 | case VK_F11: 253 | m_screenShot = 1; 254 | break; 255 | } 256 | } 257 | 258 | // User camera interactions. 259 | void ComputeRaster::OnLButtonDown(float posX, float posY) 260 | { 261 | m_tracking = true; 262 | m_mousePt = XMFLOAT2(posX, posY); 263 | } 264 | 265 | void ComputeRaster::OnLButtonUp(float posX, float posY) 266 | { 267 | m_tracking = false; 268 | } 269 | 270 | void ComputeRaster::OnMouseMove(float posX, float posY) 271 | { 272 | if (m_tracking) 273 | { 274 | const auto dPos = XMFLOAT2(m_mousePt.x - posX, m_mousePt.y - posY); 275 | 276 | XMFLOAT2 radians; 277 | radians.x = XM_2PI * dPos.y / m_height; 278 | radians.y = XM_2PI * dPos.x / m_width; 279 | 280 | const auto focusPt = XMLoadFloat3(&m_focusPt); 281 | auto eyePt = XMLoadFloat3(&m_eyePt); 282 | 283 | const auto len = XMVectorGetX(XMVector3Length(focusPt - eyePt)); 284 | auto transform = XMMatrixTranslation(0.0f, 0.0f, -len); 285 | transform *= XMMatrixRotationRollPitchYaw(radians.x, radians.y, 0.0f); 286 | transform *= XMMatrixTranslation(0.0f, 0.0f, len); 287 | 288 | const auto view = XMLoadFloat4x4(&m_view) * transform; 289 | const auto viewInv = XMMatrixInverse(nullptr, view); 290 | eyePt = viewInv.r[3]; 291 | 292 | XMStoreFloat3(&m_eyePt, eyePt); 293 | XMStoreFloat4x4(&m_view, view); 294 | 295 | m_mousePt = XMFLOAT2(posX, posY); 296 | } 297 | } 298 | 299 | void ComputeRaster::OnMouseWheel(float deltaZ, float posX, float posY) 300 | { 301 | const auto focusPt = XMLoadFloat3(&m_focusPt); 302 | auto eyePt = XMLoadFloat3(&m_eyePt); 303 | 304 | const auto len = XMVectorGetX(XMVector3Length(focusPt - eyePt)); 305 | const auto transform = XMMatrixTranslation(0.0f, 0.0f, -len * deltaZ / 16.0f); 306 | 307 | const auto view = XMLoadFloat4x4(&m_view) * transform; 308 | const auto viewInv = XMMatrixInverse(nullptr, view); 309 | eyePt = viewInv.r[3]; 310 | 311 | XMStoreFloat3(&m_eyePt, eyePt); 312 | XMStoreFloat4x4(&m_view, view); 313 | } 314 | 315 | void ComputeRaster::OnMouseLeave() 316 | { 317 | m_tracking = false; 318 | } 319 | 320 | void ComputeRaster::ParseCommandLineArgs(wchar_t* argv[], int argc) 321 | { 322 | const auto str_tolower = [](wstring s) 323 | { 324 | transform(s.begin(), s.end(), s.begin(), [](wchar_t c) { return towlower(c); }); 325 | 326 | return s; 327 | }; 328 | 329 | const auto isArgMatched = [&argv, &str_tolower](int i, const wchar_t* paramName) 330 | { 331 | const auto& arg = argv[i]; 332 | 333 | return (arg[0] == L'-' || arg[0] == L'/') 334 | && str_tolower(&arg[1]) == str_tolower(paramName); 335 | }; 336 | 337 | const auto hasNextArgValue = [&argv, &argc](int i) 338 | { 339 | const auto& arg = argv[i + 1]; 340 | 341 | return i + 1 < argc && arg[0] != L'/' && 342 | (arg[0] != L'-' || (arg[1] >= L'0' && arg[1] <= L'9') || arg[1] == L'.'); 343 | }; 344 | 345 | DXFramework::ParseCommandLineArgs(argv, argc); 346 | 347 | for (auto i = 1; i < argc; ++i) 348 | { 349 | if (isArgMatched(i, L"warp")) m_deviceType = DEVICE_WARP; 350 | else if (isArgMatched(i, L"uma")) m_deviceType = DEVICE_UMA; 351 | else if (isArgMatched(i, L"mesh")) 352 | { 353 | if (hasNextArgValue(i)) 354 | { 355 | m_meshFileName.resize(wcslen(argv[++i])); 356 | for (size_t j = 0; j < m_meshFileName.size(); ++j) 357 | m_meshFileName[j] = static_cast(argv[i][j]); 358 | } 359 | if (hasNextArgValue(i)) i += swscanf_s(argv[i + 1], L"%f", &m_meshPosScale.x); 360 | if (hasNextArgValue(i)) i += swscanf_s(argv[i + 1], L"%f", &m_meshPosScale.y); 361 | if (hasNextArgValue(i)) i += swscanf_s(argv[i + 1], L"%f", &m_meshPosScale.z); 362 | if (hasNextArgValue(i)) i += swscanf_s(argv[i + 1], L"%f", &m_meshPosScale.w); 363 | } 364 | } 365 | } 366 | 367 | void ComputeRaster::PopulateCommandList() 368 | { 369 | // Command list allocators can only be reset when the associated 370 | // command lists have finished execution on the GPU; apps should use 371 | // fences to determine GPU execution progress. 372 | const auto pCommandAllocator = m_commandAllocators[m_frameIndex].get(); 373 | XUSG_N_RETURN(pCommandAllocator->Reset(), ThrowIfFailed(E_FAIL)); 374 | 375 | // However, when ExecuteCommandList() is called on a particular command 376 | // list, that command list can then be reset at any time and must be before 377 | // re-recording. 378 | const auto pCommandList = m_commandList.get(); 379 | XUSG_N_RETURN(pCommandList->Reset(pCommandAllocator, nullptr), ThrowIfFailed(E_FAIL)); 380 | 381 | // Record commands. 382 | m_renderer->Render(pCommandList, m_frameIndex); 383 | 384 | // Copy to back buffer. 385 | const auto pRenderTarget = m_renderTargets[m_frameIndex].get(); 386 | { 387 | const auto pColorTarget = m_renderer->GetColorTarget(); 388 | const TextureCopyLocation dst(pRenderTarget, 0); 389 | const TextureCopyLocation src(pColorTarget, 0); 390 | 391 | ResourceBarrier barriers[2]; 392 | auto numBarriers = pRenderTarget->SetBarrier(barriers, ResourceState::COPY_DEST); 393 | numBarriers = pColorTarget->SetBarrier(barriers, ResourceState::COPY_SOURCE, numBarriers); 394 | pCommandList->Barrier(numBarriers, barriers); 395 | 396 | pCommandList->CopyTextureRegion(dst, 0, 0, 0, src); 397 | 398 | // Indicate that the back buffer will now be used to present. 399 | numBarriers = pRenderTarget->SetBarrier(barriers, ResourceState::PRESENT); 400 | pCommandList->Barrier(numBarriers, barriers); 401 | } 402 | 403 | // Screen-shot helper 404 | if (m_screenShot == 1) 405 | { 406 | if (!m_readBuffer) m_readBuffer = Buffer::MakeUnique(); 407 | pRenderTarget->ReadBack(pCommandList, m_readBuffer.get(), &m_rowPitch); 408 | m_screenShot = 2; 409 | } 410 | 411 | XUSG_N_RETURN(pCommandList->Close(), ThrowIfFailed(E_FAIL)); 412 | } 413 | 414 | // Wait for pending GPU work to complete. 415 | void ComputeRaster::WaitForGpu() 416 | { 417 | // Schedule a Signal command in the queue. 418 | XUSG_N_RETURN(m_commandQueue->Signal(m_fence.get(), m_fenceValues[m_frameIndex]), ThrowIfFailed(E_FAIL)); 419 | 420 | // Wait until the fence has been processed. 421 | XUSG_N_RETURN(m_fence->SetEventOnCompletion(m_fenceValues[m_frameIndex], m_fenceEvent), ThrowIfFailed(E_FAIL)); 422 | WaitForSingleObject(m_fenceEvent, INFINITE); 423 | 424 | // Increment the fence value for the current frame. 425 | m_fenceValues[m_frameIndex]++; 426 | } 427 | 428 | // Prepare to render the next frame. 429 | void ComputeRaster::MoveToNextFrame() 430 | { 431 | // Schedule a Signal command in the queue. 432 | const auto currentFenceValue = m_fenceValues[m_frameIndex]; 433 | XUSG_N_RETURN(m_commandQueue->Signal(m_fence.get(), currentFenceValue), ThrowIfFailed(E_FAIL)); 434 | 435 | // Update the frame index. 436 | m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); 437 | 438 | // If the next frame is not ready to be rendered yet, wait until it is ready. 439 | if (m_fence->GetCompletedValue() < m_fenceValues[m_frameIndex]) 440 | { 441 | XUSG_N_RETURN(m_fence->SetEventOnCompletion(m_fenceValues[m_frameIndex], m_fenceEvent), ThrowIfFailed(E_FAIL)); 442 | WaitForSingleObject(m_fenceEvent, INFINITE); 443 | } 444 | 445 | // Set the fence value for the next frame. 446 | m_fenceValues[m_frameIndex] = currentFenceValue + 1; 447 | 448 | // Screen-shot helper 449 | if (m_screenShot) 450 | { 451 | if (m_screenShot > SoftGraphicsPipeline::FrameCount) 452 | { 453 | char timeStr[15]; 454 | tm dateTime; 455 | const auto now = time(nullptr); 456 | if (!localtime_s(&dateTime, &now) && strftime(timeStr, sizeof(timeStr), "%Y%m%d%H%M%S", &dateTime)) 457 | SaveImage((string("ComputeRaster_") + timeStr + ".png").c_str(), m_readBuffer.get(), m_width, m_height, m_rowPitch); 458 | m_screenShot = 0; 459 | } 460 | else ++m_screenShot; 461 | } 462 | } 463 | 464 | void ComputeRaster::SaveImage(char const* fileName, Buffer* pImageBuffer, uint32_t w, uint32_t h, uint32_t rowPitch, uint8_t comp) 465 | { 466 | assert(comp == 3 || comp == 4); 467 | const auto pData = static_cast(pImageBuffer->Map(nullptr)); 468 | 469 | //stbi_write_png_compression_level = 1024; 470 | vector imageData(comp * w * h); 471 | const auto sw = rowPitch / 4; // Byte to pixel 472 | for (auto i = 0u; i < h; ++i) 473 | for (auto j = 0u; j < w; ++j) 474 | { 475 | const auto s = sw * i + j; 476 | const auto d = w * i + j; 477 | for (uint8_t k = 0; k < comp; ++k) 478 | imageData[comp * d + k] = pData[4 * s + k]; 479 | } 480 | 481 | stbi_write_png(fileName, w, h, comp, imageData.data(), 0); 482 | 483 | pImageBuffer->Unmap(); 484 | } 485 | 486 | double ComputeRaster::CalculateFrameStats(float* pTimeStep) 487 | { 488 | static auto frameCnt = 0u; 489 | static auto previousTime = 0.0; 490 | const auto totalTime = m_timer.GetTotalSeconds(); 491 | ++frameCnt; 492 | 493 | const auto timeStep = totalTime - previousTime; 494 | 495 | // Compute averages over one second period. 496 | if (timeStep >= 1.0) 497 | { 498 | const auto fps = static_cast(frameCnt / timeStep); // Normalize to an exact second. 499 | 500 | frameCnt = 0; 501 | previousTime = totalTime; 502 | 503 | wstringstream windowText; 504 | windowText << L" fps: "; 505 | if (m_showFPS) windowText << setprecision(2) << fixed << fps; 506 | else windowText << L"[F1]"; 507 | 508 | windowText << L" [F11] screen shot"; 509 | 510 | SetCustomWindowText(windowText.str().c_str()); 511 | } 512 | 513 | if (pTimeStep) *pTimeStep = static_cast(m_timer.GetElapsedSeconds()); 514 | 515 | return totalTime; 516 | } 517 | -------------------------------------------------------------------------------- /ComputeRaster/ComputeRaster.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #pragma once 13 | 14 | #include "DXFramework.h" 15 | #include "StepTimer.h" 16 | #include "Renderer.h" 17 | 18 | using namespace DirectX; 19 | 20 | // Note that while ComPtr is used to manage the lifetime of resources on the CPU, 21 | // it has no understanding of the lifetime of resources on the GPU. Apps must account 22 | // for the GPU lifetime of resources to avoid destroying objects that may still be 23 | // referenced by the GPU. 24 | // An example of this can be found in the class method: OnDestroy(). 25 | 26 | class ComputeRaster : public DXFramework 27 | { 28 | public: 29 | ComputeRaster(uint32_t width, uint32_t height, std::wstring name); 30 | virtual ~ComputeRaster(); 31 | 32 | virtual void OnInit(); 33 | virtual void OnUpdate(); 34 | virtual void OnRender(); 35 | virtual void OnDestroy(); 36 | 37 | virtual void OnKeyUp(uint8_t /*key*/); 38 | virtual void OnLButtonDown(float posX, float posY); 39 | virtual void OnLButtonUp(float posX, float posY); 40 | virtual void OnMouseMove(float posX, float posY); 41 | virtual void OnMouseWheel(float deltaZ, float posX, float posY); 42 | virtual void OnMouseLeave(); 43 | 44 | virtual void ParseCommandLineArgs(wchar_t* argv[], int argc); 45 | 46 | private: 47 | enum DeviceType : uint8_t 48 | { 49 | DEVICE_DISCRETE, 50 | DEVICE_UMA, 51 | DEVICE_WARP 52 | }; 53 | 54 | XUSG::SwapChain::uptr m_swapChain; 55 | XUSG::CommandAllocator::uptr m_commandAllocators[SoftGraphicsPipeline::FrameCount]; 56 | XUSG::CommandQueue::uptr m_commandQueue; 57 | 58 | XUSG::Device::uptr m_device; 59 | XUSG::RenderTarget::uptr m_renderTargets[SoftGraphicsPipeline::FrameCount]; 60 | XUSG::CommandList::uptr m_commandList; 61 | 62 | // App resources. 63 | std::unique_ptr m_renderer; 64 | XMFLOAT4X4 m_proj; 65 | XMFLOAT4X4 m_view; 66 | XMFLOAT3 m_focusPt; 67 | XMFLOAT3 m_eyePt; 68 | 69 | // Synchronization objects. 70 | uint32_t m_frameIndex; 71 | HANDLE m_fenceEvent; 72 | XUSG::Fence::uptr m_fence; 73 | uint64_t m_fenceValues[SoftGraphicsPipeline::FrameCount]; 74 | 75 | // Application state 76 | DeviceType m_deviceType; 77 | StepTimer m_timer; 78 | bool m_showFPS; 79 | bool m_isPaused; 80 | 81 | // User camera interactions 82 | bool m_tracking; 83 | XMFLOAT2 m_mousePt; 84 | 85 | // User external settings 86 | std::string m_meshFileName; 87 | XMFLOAT4 m_meshPosScale; 88 | 89 | // Screen-shot helpers and state 90 | XUSG::Buffer::uptr m_readBuffer; 91 | uint32_t m_rowPitch; 92 | uint8_t m_screenShot; 93 | 94 | void LoadPipeline(); 95 | void LoadAssets(); 96 | 97 | void PopulateCommandList(); 98 | void WaitForGpu(); 99 | void MoveToNextFrame(); 100 | void SaveImage(char const* fileName, XUSG::Buffer* pImageBuffer, 101 | uint32_t w, uint32_t h, uint32_t rowPitch, uint8_t comp = 3); 102 | double CalculateFrameStats(float* fTimeStep = nullptr); 103 | }; 104 | -------------------------------------------------------------------------------- /ComputeRaster/ComputeRaster.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {99BC179A-8DDD-404A-9051-221693BF72B3} 24 | VoxelizerX 25 | 10.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v143 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v143 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v143 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v143 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | Disabled 77 | true 78 | Use 79 | $(ProjectDir);$(ProjectDir)Content;$(ProjectDir)XUSG;$(ProjectDir)Common 80 | true 81 | 82 | 83 | d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;XUSG.lib;%(AdditionalDependencies) 84 | $(ProjectDir)XUSG\Bin\$(Configuration) 85 | 86 | 87 | $(ProjectDir)Content\Shaders;$(ProjectDir)Content;$(ProjectDir)XUSG\Shaders;$(ProjectDir)XUSG;$(ProjectDir) 88 | 5.0 89 | true 90 | 91 | 92 | COPY /Y "$(OutDir)*.cso" "$(ProjectDir)..\Bin\" 93 | COPY /Y "$(OutDir)*.exe" "$(ProjectDir)..\Bin\" 94 | COPY /Y "$(ProjectDir)XUSG\Bin\$(Configuration)\*.dll" "$(ProjectDir)..\Bin\" 95 | 96 | 97 | 98 | 99 | Level3 100 | Disabled 101 | true 102 | Use 103 | $(ProjectDir);$(ProjectDir)Content;$(ProjectDir)XUSG;$(ProjectDir)Common 104 | AdvancedVectorExtensions2 105 | Fast 106 | true 107 | 108 | 109 | d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;XUSG.lib;%(AdditionalDependencies) 110 | $(ProjectDir)XUSG\Bin\$(Platform)\$(Configuration) 111 | 112 | 113 | $(ProjectDir)Content\Shaders;$(ProjectDir)Content;$(ProjectDir)XUSG\Shaders;$(ProjectDir)XUSG;$(ProjectDir) 114 | 5.0 115 | true 116 | 117 | 118 | COPY /Y "$(OutDir)*.cso" "$(ProjectDir)..\Bin\" 119 | COPY /Y "$(OutDir)*.exe" "$(ProjectDir)..\Bin\" 120 | COPY /Y "$(ProjectDir)XUSG\Bin\$(Platform)\$(Configuration)\*.dll" "$(ProjectDir)..\Bin\" 121 | 122 | 123 | 124 | 125 | Level3 126 | MaxSpeed 127 | true 128 | true 129 | true 130 | Use 131 | $(ProjectDir);$(ProjectDir)Content;$(ProjectDir)XUSG;$(ProjectDir)Common 132 | true 133 | 134 | 135 | true 136 | true 137 | d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;XUSG.lib;%(AdditionalDependencies) 138 | $(ProjectDir)XUSG\Bin\$(Configuration) 139 | 140 | 141 | $(ProjectDir)Content\Shaders;$(ProjectDir)Content;$(ProjectDir)XUSG\Shaders;$(ProjectDir)XUSG;$(ProjectDir) 142 | 5.0 143 | true 144 | 145 | 146 | COPY /Y "$(OutDir)*.cso" "$(ProjectDir)..\Bin\" 147 | COPY /Y "$(OutDir)*.exe" "$(ProjectDir)..\Bin\" 148 | COPY /Y "$(ProjectDir)XUSG\Bin\$(Configuration)\*.dll" "$(ProjectDir)..\Bin\" 149 | 150 | 151 | 152 | 153 | Level3 154 | MaxSpeed 155 | true 156 | true 157 | true 158 | Use 159 | $(ProjectDir);$(ProjectDir)Content;$(ProjectDir)XUSG;$(ProjectDir)Common 160 | AdvancedVectorExtensions2 161 | Fast 162 | true 163 | 164 | 165 | true 166 | true 167 | d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;XUSG.lib;%(AdditionalDependencies) 168 | $(ProjectDir)XUSG\Bin\$(Platform)\$(Configuration) 169 | 170 | 171 | $(ProjectDir)Content\Shaders;$(ProjectDir)Content;$(ProjectDir)XUSG\Shaders;$(ProjectDir)XUSG;$(ProjectDir) 172 | 5.0 173 | true 174 | 175 | 176 | COPY /Y "$(OutDir)*.cso" "$(ProjectDir)..\Bin\" 177 | COPY /Y "$(OutDir)*.exe" "$(ProjectDir)..\Bin\" 178 | COPY /Y "$(ProjectDir)XUSG\Bin\$(Platform)\$(Configuration)\*.dll" "$(ProjectDir)..\Bin\" 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | stdafx.h 201 | stdafx.h 202 | stdafx.h 203 | stdafx.h 204 | 205 | 206 | stdafx.h 207 | stdafx.h 208 | stdafx.h 209 | stdafx.h 210 | 211 | 212 | stdafx.h 213 | stdafx.h 214 | stdafx.h 215 | stdafx.h 216 | 217 | 218 | stdafx.h 219 | stdafx.h 220 | stdafx.h 221 | stdafx.h 222 | 223 | 224 | stdafx.h 225 | stdafx.h 226 | stdafx.h 227 | stdafx.h 228 | 229 | 230 | stdafx.h 231 | stdafx.h 232 | stdafx.h 233 | stdafx.h 234 | 235 | 236 | stdafx.h 237 | stdafx.h 238 | stdafx.h 239 | stdafx.h 240 | 241 | 242 | Create 243 | Create 244 | Create 245 | Create 246 | 247 | 248 | stdafx.h 249 | stdafx.h 250 | stdafx.h 251 | stdafx.h 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | Compute 267 | Compute 268 | Compute 269 | Compute 270 | HI_Z=1 271 | HI_Z=1 272 | HI_Z=1 273 | HI_Z=1 274 | 275 | 276 | Compute 277 | Compute 278 | Compute 279 | Compute 280 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm;CR_TARGET_TYPE0=float4 281 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm;CR_TARGET_TYPE0=float4 282 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm;CR_TARGET_TYPE0=float4 283 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm;CR_TARGET_TYPE0=float4 284 | 285 | 286 | Compute 287 | Compute 288 | Compute 289 | Compute 290 | HI_Z=1 291 | HI_Z=1 292 | HI_Z=1 293 | HI_Z=1 294 | 295 | 296 | Compute 297 | Compute 298 | Compute 299 | Compute 300 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 301 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 302 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 303 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 304 | 305 | 306 | Compute 307 | Compute 308 | Compute 309 | Compute 310 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 311 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 312 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 313 | CR_ATTRIBUTE_BASE_TYPE0=float;CR_ATTRIBUTE_COMPONENT_COUNT0=3;CR_ATTRIBUTE0=Nrm 314 | 315 | 316 | 317 | 318 | 319 | -------------------------------------------------------------------------------- /ComputeRaster/ComputeRaster.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {5cce8bfc-130f-4926-9dd6-e0718356a114} 18 | 19 | 20 | {34cb71b2-8e74-46c6-abf0-f6436c5084b4} 21 | 22 | 23 | {213718c1-63a4-42ed-8970-c26b977fabc6} 24 | 25 | 26 | {e03571e2-64ac-409e-8b71-75096e2e5c75} 27 | 28 | 29 | {b260c74f-31ac-461c-aa6e-80f763f7e27d} 30 | 31 | 32 | {39a871a6-0a7f-4d06-b83f-8b043b482455} 33 | 34 | 35 | {ee928985-8694-4c41-93ae-de981feb8784} 36 | 37 | 38 | 39 | 40 | Common\Header Files 41 | 42 | 43 | Common\Header Files 44 | 45 | 46 | Common\Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Common\Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | XUSG\Optional 68 | 69 | 70 | Common\Header Files 71 | 72 | 73 | XUSG 74 | 75 | 76 | Common\Header Files 77 | 78 | 79 | Common\Header Files 80 | 81 | 82 | Common\Header Files 83 | 84 | 85 | 86 | 87 | Common\Source Files 88 | 89 | 90 | Common\Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | XUSG\Optional 109 | 110 | 111 | Common\Source Files 112 | 113 | 114 | 115 | 116 | Shaders 117 | 118 | 119 | Shaders 120 | 121 | 122 | Shaders\Internal 123 | 124 | 125 | Shaders\Internal 126 | 127 | 128 | Shaders\Internal 129 | 130 | 131 | Shaders\Internal 132 | 133 | 134 | Shaders\Internal 135 | 136 | 137 | Shaders\Internal 138 | 139 | 140 | 141 | 142 | Shaders\Internal 143 | 144 | 145 | Shaders\Internal 146 | 147 | 148 | Shaders\Internal 149 | 150 | 151 | Shaders\Internal 152 | 153 | 154 | Shaders\Internal 155 | 156 | 157 | -------------------------------------------------------------------------------- /ComputeRaster/ComputeRaster.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(ProjectDir)..\Bin 5 | WindowsLocalDebugger 6 | 7 | 8 | $(ProjectDir)..\Bin 9 | WindowsLocalDebugger 10 | 11 | 12 | $(ProjectDir)..\Bin 13 | WindowsLocalDebugger 14 | 15 | 16 | $(ProjectDir)..\Bin 17 | WindowsLocalDebugger 18 | 19 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Renderer.cpp: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #include "Optional/XUSGObjLoader.h" 6 | #include "Renderer.h" 7 | 8 | using namespace std; 9 | using namespace DirectX; 10 | using namespace XUSG; 11 | 12 | Renderer::Renderer() 13 | { 14 | } 15 | 16 | Renderer::~Renderer() 17 | { 18 | } 19 | 20 | bool Renderer::Init(CommandList* pCommandList, uint32_t width, 21 | uint32_t height, vector& uploaders, const char* fileName, 22 | const XMFLOAT4& posScale) 23 | { 24 | const auto pDevice = pCommandList->GetDevice(); 25 | m_viewport.x = static_cast(width); 26 | m_viewport.y = static_cast(height); 27 | m_posScale = posScale; 28 | 29 | XUSG_X_RETURN(m_softGraphicsPipeline, make_unique(), false); 30 | XUSG_N_RETURN(m_softGraphicsPipeline->Init(pCommandList, uploaders), false); 31 | 32 | // Create Color target 33 | m_colorTarget = Texture2D::MakeUnique(); 34 | XUSG_N_RETURN(m_colorTarget->Create(pDevice, width, height, Format::R8G8B8A8_UNORM, 1, 35 | ResourceFlag::ALLOW_UNORDERED_ACCESS | ResourceFlag::ALLOW_SIMULTANEOUS_ACCESS), false); 36 | 37 | // Create depth buffer 38 | XUSG_N_RETURN(m_softGraphicsPipeline->CreateDepthBuffer(pDevice, 39 | m_depth, width, height, Format::R32_UINT), false); 40 | 41 | { 42 | const auto pipelineLayout = Util::PipelineLayout::MakeUnique(); 43 | pipelineLayout->SetRange(0, DescriptorType::CBV, 1, 0, 0, DescriptorFlag::DATA_STATIC); 44 | m_softGraphicsPipeline->SetAttribute(0, sizeof(uint32_t[4]), Format::R32G32B32A32_FLOAT, L"Normal"); 45 | XUSG_N_RETURN(m_softGraphicsPipeline->CreateVertexShaderLayout(pipelineLayout.get(), 1), false); 46 | } 47 | 48 | { 49 | const auto pipelineLayout = Util::PipelineLayout::MakeUnique(); 50 | pipelineLayout->SetRange(0, DescriptorType::CBV, 1, 0, 0, DescriptorFlag::DATA_STATIC); 51 | pipelineLayout->SetRange(1, DescriptorType::CBV, 1, 1, 0, DescriptorFlag::DATA_STATIC); 52 | XUSG_N_RETURN(m_softGraphicsPipeline->CreatePixelShaderLayout(pipelineLayout.get(), true, 1, 2, 1), false); 53 | } 54 | 55 | // Create constant buffers 56 | const auto& frameCount = SoftGraphicsPipeline::FrameCount; 57 | m_cbMatrices = ConstantBuffer::MakeUnique(); 58 | XUSG_N_RETURN(m_cbMatrices->Create(pDevice, sizeof(XMFLOAT4X4[2]) * frameCount, frameCount), false); 59 | for (uint8_t i = 0; i < frameCount; ++i) 60 | { 61 | const auto descriptorTable = Util::DescriptorTable::MakeUnique(); 62 | descriptorTable->SetDescriptors(0, 1, &m_cbMatrices->GetCBV(i)); 63 | m_cbvTables[CBV_TABLE_MATRICES + i] = descriptorTable->GetCbvSrvUavTable(m_softGraphicsPipeline->GetDescriptorTableLib()); 64 | } 65 | 66 | // Per-frame lighting 67 | m_cbLighting = ConstantBuffer::MakeUnique(); 68 | XUSG_N_RETURN(m_cbLighting->Create(pDevice, sizeof(XMFLOAT4[4]) * frameCount, frameCount), false); 69 | for (uint8_t i = 0; i < frameCount; ++i) 70 | { 71 | const auto descriptorTable = Util::DescriptorTable::MakeUnique(); 72 | descriptorTable->SetDescriptors(0, 1, &m_cbLighting->GetCBV(i)); 73 | m_cbvTables[CBV_TABLE_LIGHTING + i] = descriptorTable->GetCbvSrvUavTable(m_softGraphicsPipeline->GetDescriptorTableLib()); 74 | } 75 | 76 | // Immutable material 77 | { 78 | XMFLOAT3 baseColor(1.0f, 1.0f, 0.5f); 79 | m_cbMaterial = ConstantBuffer::MakeUnique(); 80 | XUSG_N_RETURN(m_cbMaterial->Create(pDevice, sizeof(XMFLOAT3), 1, nullptr, MemoryType::DEFAULT), false); 81 | uploaders.emplace_back(Resource::MakeUnique()); 82 | m_cbMaterial->Upload(pCommandList, uploaders.back().get(), &baseColor, sizeof(XMFLOAT4)); 83 | 84 | const auto descriptorTable = Util::DescriptorTable::MakeUnique(); 85 | descriptorTable->SetDescriptors(0, 1, &m_cbMaterial->GetCBV()); 86 | m_cbvTables[CBV_TABLE_MATERIAL] = descriptorTable->GetCbvSrvUavTable(m_softGraphicsPipeline->GetDescriptorTableLib()); 87 | } 88 | 89 | m_vb = VertexBuffer::MakeUnique(); 90 | m_ib = IndexBuffer::MakeUnique(); 91 | #if 1 92 | // Load inputs 93 | ObjLoader objLoader; 94 | XUSG_N_RETURN(objLoader.Import(fileName, true, true), false); 95 | 96 | m_numIndices = objLoader.GetNumIndices(); 97 | XUSG_N_RETURN(m_softGraphicsPipeline->CreateVertexBuffer(pCommandList, *m_vb, uploaders, 98 | objLoader.GetVertices(), objLoader.GetNumVertices(), objLoader.GetVertexStride()), false); 99 | XUSG_N_RETURN(m_softGraphicsPipeline->CreateIndexBuffer(pCommandList, *m_ib, 100 | uploaders, objLoader.GetIndices(), m_numIndices, Format::R32_UINT), false); 101 | #else 102 | const float vbData[] = 103 | { 104 | 0.0f, 9.0f, 0.0f, 105 | 0.0f, 0.0f, -1.0f, 106 | 5.0f, -1.0f, 0.0f, 107 | 0.0f, 0.0f, -1.0f, 108 | -5.0f, -1.0f, 0.0f, 109 | 0.0f, 0.0f, -1.0f, 110 | }; 111 | XUSG_N_RETURN(m_softGraphicsPipeline->CreateVertexBuffer(commandList, m_vb, 112 | uploaders, vbData, 3, sizeof(float[6])), false); 113 | 114 | const uint16_t ibData[] = { 0, 1, 2 }; 115 | m_numIndices = 3; 116 | XUSG_N_RETURN(m_softGraphicsPipeline->CreateIndexBuffer(commandList, m_ib, 117 | uploaders, ibData, m_numIndices, Format::R16_UINT), false); 118 | #endif 119 | 120 | return true; 121 | } 122 | 123 | void Renderer::UpdateFrame(uint8_t frameIndex, CXMMATRIX view, 124 | CXMMATRIX proj, const XMFLOAT3& eyePt, double time) 125 | { 126 | { 127 | struct CBMatrices 128 | { 129 | XMMATRIX WorldViewProj; 130 | XMMATRIX Normal; 131 | }; 132 | const auto pCb = reinterpret_cast(m_cbMatrices->Map(frameIndex)); 133 | const auto world = XMMatrixScaling(m_posScale.w, m_posScale.w, m_posScale.w) * 134 | XMMatrixTranslation(m_posScale.x, m_posScale.y, m_posScale.z); 135 | const auto worldInv = XMMatrixInverse(nullptr, world); 136 | pCb->WorldViewProj = XMMatrixTranspose(world * view * proj); 137 | pCb->Normal = worldInv; 138 | } 139 | 140 | { 141 | struct CBLighting 142 | { 143 | XMFLOAT4 AmbientColor; 144 | XMFLOAT4 LightColor; 145 | XMFLOAT4 LightPt; 146 | XMFLOAT3 EyePt; 147 | }; 148 | const auto pCb = reinterpret_cast(m_cbLighting->Map(frameIndex)); 149 | pCb->AmbientColor = XMFLOAT4(0.6f, 0.7f, 1.0f, 2.4f); 150 | pCb->LightColor = XMFLOAT4(1.0f, 0.7f, 0.5f, (static_cast(sin(time)) * 0.3f + 0.7f) * 3.14f); 151 | XMStoreFloat4(&pCb->LightPt, XMVectorSet(1.0f, 1.0f, -1.0, 0.0f)); 152 | pCb->EyePt = eyePt; 153 | } 154 | } 155 | 156 | void Renderer::Render(CommandList* pCommandList, uint8_t frameIndex) 157 | { 158 | // Compute raster rendering 159 | const float clearColor[] = { CLEAR_COLOR, 0.0f }; 160 | m_softGraphicsPipeline->SetDecriptorHeaps(pCommandList); 161 | m_softGraphicsPipeline->SetRenderTargets(1, m_colorTarget.get(), &m_depth); 162 | m_softGraphicsPipeline->ClearFloat(*m_colorTarget, clearColor); 163 | m_softGraphicsPipeline->ClearDepth(1.0f); 164 | m_softGraphicsPipeline->SetViewport(Viewport(0.0f, 0.0f, m_viewport.x, m_viewport.y)); 165 | m_softGraphicsPipeline->SetVertexBuffer(m_vb->GetSRV()); 166 | m_softGraphicsPipeline->SetIndexBuffer(m_ib->GetSRV()); 167 | m_softGraphicsPipeline->VSSetDescriptorTable(0, m_cbvTables[CBV_TABLE_MATRICES + frameIndex]); 168 | m_softGraphicsPipeline->PSSetDescriptorTable(0, m_cbvTables[CBV_TABLE_LIGHTING + frameIndex]); 169 | m_softGraphicsPipeline->PSSetDescriptorTable(1, m_cbvTables[CBV_TABLE_MATERIAL]); 170 | m_softGraphicsPipeline->DrawIndexed(pCommandList, m_numIndices); 171 | } 172 | 173 | Texture2D* Renderer::GetColorTarget() const 174 | { 175 | return m_colorTarget.get(); 176 | } 177 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Renderer.h: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #pragma once 6 | 7 | #include "SoftGraphicsPipeline.h" 8 | 9 | class Renderer 10 | { 11 | public: 12 | Renderer(); 13 | virtual ~Renderer(); 14 | 15 | bool Init(XUSG::CommandList* pCommandList, uint32_t width, uint32_t height, 16 | std::vector& uploaders, const char* fileName, 17 | const DirectX::XMFLOAT4& posScale); 18 | 19 | void UpdateFrame(uint8_t frameIndex, DirectX::CXMMATRIX view, 20 | DirectX::CXMMATRIX proj, const DirectX::XMFLOAT3& eyePt, double time); 21 | void Render(XUSG::CommandList* pCommandList, uint8_t frameIndex); 22 | 23 | XUSG::Texture2D* GetColorTarget() const; 24 | 25 | protected: 26 | enum CBVTable : uint8_t 27 | { 28 | CBV_TABLE_MATRICES, 29 | CBV_TABLE_LIGHTING = CBV_TABLE_MATRICES + SoftGraphicsPipeline::FrameCount, 30 | CBV_TABLE_MATERIAL = CBV_TABLE_LIGHTING + SoftGraphicsPipeline::FrameCount, 31 | 32 | NUM_CBV_TABLE 33 | }; 34 | 35 | std::unique_ptr m_softGraphicsPipeline; 36 | XUSG::VertexBuffer::uptr m_vb; 37 | XUSG::IndexBuffer::uptr m_ib; 38 | XUSG::ConstantBuffer::uptr m_cbMatrices; 39 | XUSG::ConstantBuffer::uptr m_cbLighting; 40 | XUSG::ConstantBuffer::uptr m_cbMaterial; 41 | 42 | XUSG::Texture2D::uptr m_colorTarget; 43 | SoftGraphicsPipeline::DepthBuffer m_depth; 44 | 45 | XUSG::DescriptorTable m_cbvTables[NUM_CBV_TABLE]; 46 | 47 | DirectX::XMFLOAT2 m_viewport; 48 | DirectX::XMFLOAT4 m_posScale; 49 | 50 | uint32_t m_numIndices; 51 | }; 52 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/BinRaster.hlsl: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #include "SharedConst.h" 6 | #include "Common.hlsli" 7 | 8 | //-------------------------------------------------------------------------------------- 9 | // Structures 10 | //-------------------------------------------------------------------------------------- 11 | struct TileInfo 12 | { 13 | uint SizeLog; 14 | uint Size; 15 | uint2 Dim; 16 | }; 17 | 18 | struct RasterUavInfo 19 | { 20 | RWStructuredBuffer rwPrimCount; 21 | RWStructuredBuffer rwPrimitives; 22 | RWTexture2D rwHiZ; 23 | }; 24 | 25 | struct RasterInfo 26 | { 27 | float3 w; 28 | float3x2 n; 29 | float2 MinPt; 30 | uint2 MinTile; 31 | uint2 MaxTile; 32 | uint ZMin; 33 | uint ZMax; 34 | RasterUavInfo UavInfo; 35 | }; 36 | 37 | //-------------------------------------------------------------------------------------- 38 | // UAV buffers 39 | //-------------------------------------------------------------------------------------- 40 | RWStructuredBuffer g_rwVertexPos; 41 | RWStructuredBuffer g_rwTilePrimCount; 42 | RWStructuredBuffer g_rwTilePrimitives; 43 | 44 | globallycoherent 45 | RWTexture2D g_rwTileZ; 46 | globallycoherent 47 | RWTexture2D g_rwBinZ; 48 | 49 | RWStructuredBuffer g_rwBinPrimCount; 50 | RWStructuredBuffer g_rwBinPrimitives; 51 | 52 | //-------------------------------------------------------------------------------------- 53 | // Cull a primitive to the view frustum defined in clip space. 54 | //-------------------------------------------------------------------------------------- 55 | bool CullPrimitive(float3x4 primVPos) 56 | { 57 | bool isFullOutside = true; 58 | 59 | [unroll] 60 | for (uint i = 0; i < 3; ++i) 61 | { 62 | bool isOutside = false; 63 | isOutside = isOutside || abs(primVPos[i].x) > primVPos[i].w; 64 | isOutside = isOutside || abs(primVPos[i].y) > primVPos[i].w; 65 | isOutside = isOutside || primVPos[i].z < 0.0; 66 | isOutside = isOutside || primVPos[i].z > primVPos[i].w; 67 | isFullOutside = isFullOutside && isOutside; 68 | } 69 | 70 | return isFullOutside; 71 | } 72 | 73 | //-------------------------------------------------------------------------------------- 74 | // Compute the minimum pixel as well as the maximum pixel 75 | // possibly overlapped by the primitive. 76 | //-------------------------------------------------------------------------------------- 77 | void ComputeAABB(float3x4 primVPos, out uint2 minTile, 78 | out uint2 maxTile, TileInfo tileInfo) 79 | { 80 | const float2 minPt = min(primVPos[0].xy, min(primVPos[1].xy, primVPos[2].xy)); 81 | const float2 maxPt = max(primVPos[0].xy, max(primVPos[1].xy, primVPos[2].xy)); 82 | 83 | minTile = floor(minPt); 84 | maxTile = floor(maxPt - 0.5); 85 | 86 | // Shrink by (tileInfo.Size x tileInfo.Size) 87 | minTile >>= tileInfo.SizeLog; 88 | maxTile >>= tileInfo.SizeLog; 89 | 90 | minTile = max(minTile, 0); 91 | maxTile = min(maxTile + 1, tileInfo.Dim); 92 | } 93 | 94 | //-------------------------------------------------------------------------------------- 95 | // Appends the pointer to the first vertex together with its 96 | // clipping parameters in clip space at the end of uavInfo.rwPrimitives. 97 | //-------------------------------------------------------------------------------------- 98 | void AppendPrimitive(uint primId, uint tileY, inout uint3 scanLine, 99 | uint tileDimX, RasterUavInfo uavInfo) 100 | { 101 | const uint scanLineLen = scanLine.y - scanLine.x; 102 | 103 | TilePrim tilePrim; 104 | tilePrim.TileIdx = tileDimX * tileY + scanLine.x; 105 | tilePrim.PrimId = primId; 106 | 107 | uint baseIdx; 108 | #if SHADER_MODEL >= 6 109 | // compute number of items to append for the whole wave 110 | const uint appendCount = WaveActiveSum(scanLineLen); 111 | // update the output location for this whole wave 112 | if (WaveIsFirstLane()) 113 | { 114 | // this way, we only issue one atomic for the entire wave, which reduces contention 115 | // and keeps the output data for each lane in this wave together in the output buffer 116 | InterlockedAdd(uavInfo.rwPrimCount[0], appendCount, baseIdx); 117 | } 118 | baseIdx = WaveReadLaneFirst(baseIdx); // broadcast value 119 | baseIdx += WavePrefixSum(scanLineLen); // and add in the offset for this lane 120 | // write to the offset location for this lane 121 | #else 122 | InterlockedAdd(uavInfo.rwPrimCount[0], scanLineLen, baseIdx); 123 | #endif 124 | for (uint i = 0; i < scanLineLen; ++i) 125 | { 126 | uavInfo.rwPrimitives[baseIdx + i] = tilePrim; 127 | ++tilePrim.TileIdx; 128 | } 129 | 130 | scanLine.x = scanLine.y; 131 | scanLine.y = scanLine.z; 132 | } 133 | 134 | //-------------------------------------------------------------------------------------- 135 | // Bin the primitive. 136 | //-------------------------------------------------------------------------------------- 137 | void BinPrimitive(uint primId, uint tileDimX, RasterInfo rasterInfo) 138 | { 139 | const float3 w = rasterInfo.w; 140 | const float3x2 n = rasterInfo.n; 141 | const float2 minPt = rasterInfo.MinPt; 142 | const uint2 minTile = rasterInfo.MinTile; 143 | const uint2 maxTile = rasterInfo.MaxTile; 144 | const uint zMin = rasterInfo.ZMin; 145 | const uint zMax = rasterInfo.ZMax; 146 | const RasterUavInfo uavInfo = rasterInfo.UavInfo; 147 | 148 | uint2 tile; 149 | for (uint i = minTile.y; i <= maxTile.y; ++i) 150 | { 151 | uint3 scanLine = uint3(0xffffffff, 0u.xx); 152 | tile.y = i; 153 | 154 | for (uint j = minTile.x; j <= maxTile.x; ++j) 155 | { 156 | // Tile overlap tests 157 | tile.x = j; 158 | if (Overlap(tile + 0.5, n, minPt, w)) 159 | scanLine.x = scanLine.x == 0xffffffff ? j : scanLine.x; 160 | else scanLine.y = j; 161 | 162 | scanLine.y = j == maxTile.x ? j : scanLine.y; 163 | if (scanLine.x < scanLine.y) break; 164 | } 165 | 166 | scanLine.z = scanLine.y; 167 | const uint loopCount = scanLine.z - scanLine.x; 168 | const bool isInsideY = i + 2 > minTile.y && i + 2 < maxTile.y; 169 | 170 | [allow_uav_condition] 171 | for (uint k = 0; k < loopCount && scanLine.x < scanLine.y; ++k) // Avoid time-out 172 | //while (scanLine.x < scanLine.y) 173 | { 174 | #if HI_Z 175 | uint hiZ; 176 | [allow_uav_condition] 177 | for (uint j = scanLine.x; j < scanLine.y; ++j) 178 | { 179 | tile.x = j; 180 | if (j > scanLine.x + 2 && j + 3 < scanLine.y && isInsideY) 181 | InterlockedMin(uavInfo.rwHiZ[tile], zMax, hiZ); 182 | else 183 | { 184 | DeviceMemoryBarrier(); 185 | hiZ = uavInfo.rwHiZ[tile]; 186 | } 187 | 188 | if (hiZ < zMin) 189 | { 190 | // Depth Test failed for this tile 191 | scanLine.y = j; 192 | break; 193 | } 194 | } 195 | #endif 196 | AppendPrimitive(primId, i, scanLine, tileDimX, uavInfo); 197 | } 198 | } 199 | } 200 | 201 | //-------------------------------------------------------------------------------------- 202 | // Get tile info. 203 | //-------------------------------------------------------------------------------------- 204 | bool GetTileInfo(float3x4 primVPos, out TileInfo tileInfo) 205 | { 206 | const float area = determinant(primVPos[0].xy, primVPos[1].xy, primVPos[2].xy); 207 | if (USE_TRIPPLE_RASTER && area > (TILE_SIZE * TILE_SIZE)* (4.0 * 4.0)) 208 | { 209 | // If the area > 4x4 tile sizes, the bin rasterization will be triggered. 210 | tileInfo.SizeLog = BIN_SIZE_LOG; 211 | tileInfo.Size = BIN_SIZE; 212 | tileInfo.Dim = g_binDim; 213 | 214 | return true; 215 | } 216 | else 217 | { 218 | // Otherwise, the tile rasterization is directly done. 219 | tileInfo.SizeLog = TILE_SIZE_LOG; 220 | tileInfo.Size = TILE_SIZE; 221 | tileInfo.Dim = g_tileDim; 222 | 223 | return false; 224 | } 225 | } 226 | 227 | //-------------------------------------------------------------------------------------- 228 | // Determine all potentially overlapping tiles. 229 | //-------------------------------------------------------------------------------------- 230 | void ProcessPrimitive(float3x4 primVPos, uint primId) 231 | { 232 | // Get tile info 233 | TileInfo tileInfo; 234 | const bool useBin = GetTileInfo(primVPos, tileInfo); 235 | 236 | RasterInfo rasterInfo; 237 | 238 | // Create the AABB. 239 | ComputeAABB(primVPos, rasterInfo.MinTile, rasterInfo.MaxTile, tileInfo); 240 | 241 | rasterInfo.ZMin = asuint(min(primVPos[0].z, min(primVPos[1].z, primVPos[2].z))); 242 | rasterInfo.ZMax = asuint(max(primVPos[0].z, max(primVPos[1].z, primVPos[2].z))); 243 | 244 | // Scale the primitive for conservative rasterization. 245 | float3x2 v; 246 | [unroll] 247 | for (uint i = 0; i < 3; ++i) v[i] = primVPos[i].xy / tileInfo.Size; 248 | v = Scale(v, 0.5); 249 | 250 | // Triangle edge equation setup. 251 | rasterInfo.n = float3x2 252 | ( 253 | v[1].y - v[2].y, v[2].x - v[1].x, 254 | v[2].y - v[0].y, v[0].x - v[2].x, 255 | v[0].y - v[1].y, v[1].x - v[0].x 256 | ); 257 | 258 | // Calculate barycentric coordinates at min corner. 259 | const float2 minPt = min(v[0], min(v[1], v[2])); 260 | rasterInfo.w.x = determinant(v[1], v[2], minPt); 261 | rasterInfo.w.y = determinant(v[2], v[0], minPt); 262 | rasterInfo.w.z = determinant(v[0], v[1], minPt); 263 | rasterInfo.MinPt = minPt; 264 | 265 | if (useBin) 266 | { 267 | // Need bin rasterization. 268 | rasterInfo.UavInfo.rwPrimCount = g_rwBinPrimCount; 269 | rasterInfo.UavInfo.rwPrimitives = g_rwBinPrimitives; 270 | rasterInfo.UavInfo.rwHiZ = g_rwBinZ; 271 | BinPrimitive(primId, tileInfo.Dim.x, rasterInfo); 272 | } 273 | else 274 | { 275 | // Otherwise, the tile rasterization is directly done. 276 | rasterInfo.UavInfo.rwPrimCount = g_rwTilePrimCount; 277 | rasterInfo.UavInfo.rwPrimitives = g_rwTilePrimitives; 278 | rasterInfo.UavInfo.rwHiZ = g_rwTileZ; 279 | BinPrimitive(primId, tileInfo.Dim.x, rasterInfo); 280 | } 281 | } 282 | 283 | #if 0 284 | //-------------------------------------------------------------------------------------- 285 | // Select min X 286 | //-------------------------------------------------------------------------------------- 287 | uint GetMinX(uint i, uint j, float2 v[3]) 288 | { 289 | return v[i].x < v[j].x ? i : j; 290 | } 291 | 292 | //-------------------------------------------------------------------------------------- 293 | // Select top left as the first 294 | //-------------------------------------------------------------------------------------- 295 | uint GetV0(uint i, uint j, float2 v[3]) 296 | { 297 | return v[i].y < v[j].y ? i : (v[i].y == v[j].y ? GetMinX(i, j, v) : j); 298 | } 299 | 300 | //-------------------------------------------------------------------------------------- 301 | // Sort vertices and compute the minimum pixel as well as 302 | // the maximum pixel possibly overlapped by the primitive. 303 | //-------------------------------------------------------------------------------------- 304 | void ToTiledSpace(float3x4 primVPos, out float2 v[3], out float2 rangeY) 305 | { 306 | float2 p[3]; 307 | [unroll] 308 | for (uint i = 0; i < 3; ++i) p[i] = primVPos[i].xy / TILE_SIZE; 309 | 310 | rangeY.x = min(p[0].y, min(p[1].y, p[2].y)); 311 | rangeY.y = max(p[0].y, max(p[1].y, p[2].y)); 312 | rangeY.x = max(floor(rangeY.x) + 0.5, 0.0); 313 | rangeY.y = min(ceil(rangeY.y) + 0.5, g_tileDim.y); 314 | 315 | const uint k = GetV0(GetV0(0, 1, p), 2, p); 316 | v[0] = p[k]; 317 | v[1] = p[k + 2 < 3 ? k + 2 : k + 2 - 3]; 318 | v[2] = p[k + 1 < 3 ? k + 1 : k + 1 - 3]; 319 | } 320 | 321 | //-------------------------------------------------------------------------------------- 322 | // Compute k and b for x = ky + b. 323 | //-------------------------------------------------------------------------------------- 324 | float2 ComputeKB(float2 v0, float2 v1) 325 | { 326 | const float2 e = v1 - v0; 327 | const float k = e.x / e.y; 328 | 329 | return float2(k, v0.x - k * v0.y); 330 | } 331 | 332 | //-------------------------------------------------------------------------------------- 333 | // Bin the primitive. 334 | //-------------------------------------------------------------------------------------- 335 | void BinPrimitive2(float3x4 primVPos, uint primId) 336 | { 337 | // Get tile info 338 | TileInfo tileInfo; 339 | const bool useBin = GetTileInfo(primVPos, tileInfo); 340 | 341 | // To tiled space. 342 | float2 v[3], rangeY; 343 | ToTiledSpace(primVPos, v, rangeY); 344 | 345 | const float nearestZ = min(primVPos[0].z, min(primVPos[1].z, primVPos[2].z)); 346 | 347 | const float2 e01 = ComputeKB(v[0], v[1]); 348 | const float2 e02 = ComputeKB(v[0], v[2]); 349 | const float2 e12 = ComputeKB(v[1], v[2]); 350 | const float2 e21 = float2(-e12.x, v[2].x + e12.x * v[2].y); 351 | 352 | float2 scan; 353 | //scan.x = e01.x * rangeY.x + e01.y; 354 | //scan.y = e02.x * rangeY.y + e02.y; 355 | 356 | RasterUavInfo uavInfo; 357 | //if (useBin) 358 | // else 359 | { 360 | // Otherwise, the tile rasterization is directly done. 361 | uavInfo.rwPrimCount = g_rwTilePrimCount; 362 | uavInfo.rwPrimitives = g_rwTilePrimitives; 363 | uavInfo.rwHiZ = g_rwTileZ; 364 | } 365 | 366 | bool2 phase2 = false; 367 | for (float y = rangeY.x; y <= rangeY.y; ++y) 368 | { 369 | if (!phase2.x && y > v[1].y) 370 | { 371 | //scan.x = e12.x * y + e12.y; 372 | phase2.x = true; 373 | } 374 | 375 | if (!phase2.y && y > v[2].y) 376 | { 377 | //scan.y = e21.x * y + e21.y; 378 | phase2.y = true; 379 | } 380 | 381 | scan.x = phase2.x ? e12.x * y + e12.y : e01.x * y + e01.y; 382 | scan.y = phase2.y ? e21.x * y + e21.y : e02.x * y + e02.y; 383 | 384 | uint3 scanLine; 385 | scanLine.x = min(scan.x, scan.y) - 0.5; 386 | scanLine.y = max(scan.x, scan.y) + 1.5; 387 | 388 | // Clip 389 | scanLine.x = max(scanLine.x, 0); 390 | scanLine.y = min(scanLine.y, g_tileDim.x); 391 | 392 | scanLine.z = scanLine.y; 393 | 394 | AppendPrimitive(primId, y, scanLine, g_tileDim.x, uavInfo); 395 | 396 | //scan.x += phase2.x ? e12.x : e01.x; 397 | //scan.y += phase2.y ? e21.x : e02.x; 398 | } 399 | } 400 | #endif 401 | 402 | [numthreads(64, 1, 1)] 403 | void main(uint DTid : SV_DispatchThreadID) 404 | { 405 | float3x4 primVPos; 406 | 407 | // Load the vertex positions of the triangle 408 | const uint baseVIdx = DTid * 3; 409 | [unroll] 410 | for (uint i = 0; i < 3; ++i) primVPos[i] = g_rwVertexPos[baseVIdx + i]; 411 | 412 | // Cull the primitive. 413 | if (CullPrimitive(primVPos)) return; 414 | 415 | // To screen space. 416 | ToScreenSpace(primVPos); 417 | 418 | // Store each successful clipping result. 419 | ProcessPrimitive(primVPos, DTid); 420 | } 421 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/Common.hlsli: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | //-------------------------------------------------------------------------------------- 6 | // Structure 7 | //-------------------------------------------------------------------------------------- 8 | struct TilePrim 9 | { 10 | uint TileIdx; 11 | uint PrimId; 12 | }; 13 | 14 | //-------------------------------------------------------------------------------------- 15 | // Constant buffer 16 | //-------------------------------------------------------------------------------------- 17 | cbuffer cb 18 | { 19 | float4 g_viewport; // X, Y, W, H 20 | uint2 g_tileDim; 21 | uint2 g_binDim; 22 | }; 23 | 24 | //-------------------------------------------------------------------------------------- 25 | // Transform a vector in homogeneous clip space to the screen space. 26 | // --> First does perspective division to get the normalized device coordinates. 27 | // --> Then scales the coordinates to the whole screen. 28 | //-------------------------------------------------------------------------------------- 29 | float4 ClipToScreen(float4 pos) 30 | { 31 | const float rhw = 1.0 / pos.w; 32 | pos.xyz *= rhw; 33 | pos.y = -pos.y; 34 | pos.xy = pos.xy * 0.5 + 0.5; 35 | pos.xy = pos.xy * g_viewport.zw; 36 | 37 | return float4(pos.xyz, rhw); 38 | } 39 | 40 | //-------------------------------------------------------------------------------------- 41 | // Transform a primitive given in clip space to screen space. 42 | //-------------------------------------------------------------------------------------- 43 | void ToScreenSpace(inout float3x4 primVPos) 44 | { 45 | [unroll] 46 | for (uint i = 0; i < 3; ++i) 47 | primVPos[i] = ClipToScreen(primVPos[i]); 48 | } 49 | 50 | //-------------------------------------------------------------------------------------- 51 | // Determinant 52 | //-------------------------------------------------------------------------------------- 53 | float determinant(float2 a, float2 b, float2 c) 54 | { 55 | return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); 56 | } 57 | 58 | //-------------------------------------------------------------------------------------- 59 | // Move the vertex by the pixel bias. 60 | //-------------------------------------------------------------------------------------- 61 | float2 Scale(float2 pv, float2 cv, float2 nv, float pixelBias = 0.5) 62 | { 63 | float3 plane0 = cross(float3(cv - pv, 0.0), float3(pv, 1.0)); 64 | float3 plane1 = cross(float3(nv - cv, 0.0), float3(cv, 1.0)); 65 | 66 | plane0.z -= dot(pixelBias, abs(plane0.xy)); 67 | plane1.z -= dot(pixelBias, abs(plane1.xy)); 68 | 69 | const float3 result = cross(plane0, plane1); 70 | 71 | return result.xy / result.z; 72 | } 73 | 74 | //-------------------------------------------------------------------------------------- 75 | // Scale the primitive vertices by the pixel bias. 76 | //-------------------------------------------------------------------------------------- 77 | float3x2 Scale(float3x2 v, float pixelBias) 78 | { 79 | float3x2 sv; 80 | sv[0] = Scale(v[2], v[0], v[1], pixelBias); 81 | sv[1] = Scale(v[0], v[1], v[2], pixelBias); 82 | sv[2] = Scale(v[1], v[2], v[0], pixelBias); 83 | 84 | return sv; 85 | } 86 | 87 | //-------------------------------------------------------------------------------------- 88 | // Check if the point is overlapped by a primitive. 89 | //-------------------------------------------------------------------------------------- 90 | float3 ComputeUnnormalizedBarycentric(float2 pos, float3x2 n, float2 minPt, float3 w) 91 | { 92 | const float2 disp = pos - minPt; 93 | w += mul(n, disp); 94 | 95 | return w; 96 | } 97 | 98 | //-------------------------------------------------------------------------------------- 99 | // Check if the point is overlapped by a primitive. 100 | //-------------------------------------------------------------------------------------- 101 | bool Overlap(float2 pos, float3x2 n, float2 minPt, float3 w) 102 | { 103 | w = ComputeUnnormalizedBarycentric(pos, n, minPt, w); 104 | 105 | return all(w >= 0.0); 106 | } 107 | 108 | //-------------------------------------------------------------------------------------- 109 | // Check if the point is overlapped by a primitive. 110 | //-------------------------------------------------------------------------------------- 111 | bool Overlap(float2 pos, float3x2 v, out float3 w) 112 | { 113 | // Triangle edge equation setup. 114 | const float3x2 n = 115 | { 116 | v[1].y - v[2].y, v[2].x - v[1].x, 117 | v[2].y - v[0].y, v[0].x - v[2].x, 118 | v[0].y - v[1].y, v[1].x - v[0].x, 119 | }; 120 | 121 | // Calculate barycentric coordinates at min corner. 122 | const float2 minPt = min(v[0].xy, min(v[1].xy, v[2].xy)); 123 | w.x = determinant(v[1].xy, v[2].xy, minPt); 124 | w.y = determinant(v[2].xy, v[0].xy, minPt); 125 | w.z = determinant(v[0].xy, v[1].xy, minPt); 126 | 127 | // If pixel is inside of all edges, set pixel. 128 | w = ComputeUnnormalizedBarycentric(pos, n, minPt, w); 129 | 130 | return all(w >= 0.0); 131 | } 132 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/DeclareAttributes.hlsli: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #if DEFINED_ATTRIBUTE(0) 6 | DECLARE_ATTRIBUTE(0); 7 | #endif 8 | 9 | #if DEFINED_ATTRIBUTE(1) 10 | DECLARE_ATTRIBUTE(1); 11 | #endif 12 | 13 | #if DEFINED_ATTRIBUTE(2) 14 | DECLARE_ATTRIBUTE(2); 15 | #endif 16 | 17 | #if DEFINED_ATTRIBUTE(3) 18 | DECLARE_ATTRIBUTE(3); 19 | #endif 20 | 21 | #if DEFINED_ATTRIBUTE(4) 22 | DECLARE_ATTRIBUTE(4); 23 | #endif 24 | 25 | #if DEFINED_ATTRIBUTE(5) 26 | DECLARE_ATTRIBUTE(5); 27 | #endif 28 | 29 | #if DEFINED_ATTRIBUTE(6) 30 | DECLARE_ATTRIBUTE(6); 31 | #endif 32 | 33 | #if DEFINED_ATTRIBUTE(7) 34 | DECLARE_ATTRIBUTE(7); 35 | #endif 36 | 37 | #if DEFINED_ATTRIBUTE(8) 38 | DECLARE_ATTRIBUTE(8); 39 | #endif 40 | 41 | #if DEFINED_ATTRIBUTE(9) 42 | DECLARE_ATTRIBUTE(9); 43 | #endif 44 | 45 | #if DEFINED_ATTRIBUTE(10) 46 | DECLARE_ATTRIBUTE(10); 47 | #endif 48 | 49 | #if DEFINED_ATTRIBUTE(11) 50 | DECLARE_ATTRIBUTE(11); 51 | #endif 52 | 53 | #if DEFINED_ATTRIBUTE(12) 54 | DECLARE_ATTRIBUTE(12); 55 | #endif 56 | 57 | #if DEFINED_ATTRIBUTE(13) 58 | DECLARE_ATTRIBUTE(13); 59 | #endif 60 | 61 | #if DEFINED_ATTRIBUTE(14) 62 | DECLARE_ATTRIBUTE(14); 63 | #endif 64 | 65 | #if DEFINED_ATTRIBUTE(15) 66 | DECLARE_ATTRIBUTE(15); 67 | #endif 68 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/DeclareTargets.hlsli: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #ifdef CR_TARGET_TYPE0 6 | DECLARE_TARGET(0); 7 | #endif 8 | 9 | #if DEFINED_TARGET(1) 10 | DECLARE_TARGET(1); 11 | #endif 12 | 13 | #if DEFINED_TARGET(2) 14 | DECLARE_TARGET(2); 15 | #endif 16 | 17 | #if DEFINED_TARGET(3) 18 | DECLARE_TARGET(3); 19 | #endif 20 | 21 | #if DEFINED_TARGET(4) 22 | DECLARE_TARGET(4); 23 | #endif 24 | 25 | #if DEFINED_TARGET(5) 26 | DECLARE_TARGET(5); 27 | #endif 28 | 29 | #if DEFINED_TARGET(6) 30 | DECLARE_TARGET(6); 31 | #endif 32 | 33 | #if DEFINED_TARGET(7) 34 | DECLARE_TARGET(7); 35 | #endif 36 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/PixelRaster.hlsl: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #include "SharedConst.h" 6 | #define main PSMain 7 | #include "PixelShader.hlsl" 8 | #undef main 9 | #include "Common.hlsli" 10 | 11 | #define CR_PRIMITIVE_VERTEX_ATTRIBUTE_TYPE(t, c) t##3x##c 12 | #define CR_ATTRIBUTE_GEN_TYPE(t, c) t##c 13 | #define CR_ATTRIBUTE_TYPE(n) CR_ATTRIBUTE_GEN_TYPE(CR_ATTRIBUTE_BASE_TYPE##n, CR_ATTRIBUTE_COMPONENT_COUNT##n) 14 | 15 | #define COMPUTE_ATTRIBUTE_float(n) \ 16 | { \ 17 | CR_PRIMITIVE_VERTEX_ATTRIBUTE_TYPE(CR_ATTRIBUTE_BASE_TYPE##n, CR_ATTRIBUTE_COMPONENT_COUNT##n) primVAtt; \ 18 | [unroll] \ 19 | for (i = 0; i < 3; ++i) primVAtt[i] = g_roVertexAtt##n[baseVIdx + i]; \ 20 | input.CR_ATTRIBUTE##n = mul(persp, primVAtt); \ 21 | } 22 | 23 | #define COMPUTE_ATTRIBUTE_min16float(n) COMPUTE_ATTRIBUTE_float(n) 24 | #define COMPUTE_ATTRIBUTE_int(n) input.CR_ATTRIBUTE##n = g_roVertexAtt##n[baseVIdx] 25 | #define COMPUTE_ATTRIBUTE_uint(n) COMPUTE_ATTRIBUTE_int(n) 26 | #define COMPUTE_ATTRIBUTE_min16int(n) COMPUTE_ATTRIBUTE_int(n) 27 | #define COMPUTE_ATTRIBUTE_min16uint(n) COMPUTE_ATTRIBUTE_int(n) 28 | #define COMPUTE_ATTRIBUTE_bool(n) COMPUTE_ATTRIBUTE_int(n) 29 | 30 | #define COMPUTE_ATTRIBUTE(t, n) COMPUTE_ATTRIBUTE_##t(n) 31 | #define SET_ATTRIBUTE(n) COMPUTE_ATTRIBUTE(CR_ATTRIBUTE_BASE_TYPE##n, n) 32 | 33 | #define DEFINED_ATTRIBUTE(n) (defined(CR_ATTRIBUTE_BASE_TYPE##n) && defined(CR_ATTRIBUTE_COMPONENT_COUNT##n)) 34 | #define DECLARE_ATTRIBUTE(n) Buffer g_roVertexAtt##n 35 | 36 | #define SET_TARGET(n) g_rwRenderTarget##n[pixelPos] = output.CR_TARGET##n 37 | #define DEFINED_TARGET(n) (defined(CR_TARGET_TYPE##n) && defined(CR_TARGET##n)) 38 | #define DECLARE_TARGET(n) RWTexture2D g_rwRenderTarget##n 39 | 40 | #define USE_MUTEX 1 41 | 42 | //-------------------------------------------------------------------------------------- 43 | // Buffers 44 | //-------------------------------------------------------------------------------------- 45 | StructuredBuffer g_roTilePrimitives; 46 | #include "DeclareAttributes.hlsli" 47 | 48 | //-------------------------------------------------------------------------------------- 49 | // UAV buffers 50 | //-------------------------------------------------------------------------------------- 51 | RWStructuredBuffer g_rwVertexPos; 52 | #include "DeclareTargets.hlsli" 53 | 54 | globallycoherent 55 | RWTexture2D g_rwDepth; 56 | RWTexture2D g_rwHiZ; 57 | 58 | [numthreads(8, 8, 1)] 59 | void main(uint2 GTid : SV_GroupThreadID, uint Gid : SV_GroupID)//, uint GTidx : SV_GroupIndex) 60 | { 61 | const TilePrim tilePrim = g_roTilePrimitives[Gid]; 62 | const uint2 tile = uint2(tilePrim.TileIdx % g_tileDim.x, tilePrim.TileIdx / g_tileDim.x); 63 | 64 | float3x4 primVPos; 65 | 66 | // Load the vertex positions of the triangle 67 | const uint baseVIdx = tilePrim.PrimId * 3; 68 | [unroll] 69 | for (uint i = 0; i < 3; ++i) primVPos[i] = g_rwVertexPos[baseVIdx + i]; 70 | 71 | // To screen space. 72 | ToScreenSpace(primVPos); 73 | 74 | #if RE_HI_Z 75 | const uint zMin = asuint(min(primVPos[0].z, min(primVPos[1].z, primVPos[2].z))); 76 | if (g_rwHiZ[tile] < zMin) return; 77 | #endif 78 | 79 | PSIn input; 80 | float3 w; 81 | const uint2 pixelPos = (tile << TILE_SIZE_LOG) + GTid; 82 | input.Pos.xy = pixelPos + 0.5; 83 | if (!Overlap(input.Pos.xy, (float3x2)primVPos, w)) return; 84 | 85 | // Normalize barycentric coordinates. 86 | const float area = determinant(primVPos[0].xy, primVPos[1].xy, primVPos[2].xy); 87 | if (area <= 0.0) return; 88 | w /= area; 89 | 90 | // Depth test 91 | uint depthMin; 92 | input.Pos.z = w.x * primVPos[0].z + w.y * primVPos[1].z + w.z * primVPos[2].z; 93 | const uint depth = asuint(input.Pos.z); 94 | #if USE_MUTEX > 1 95 | // Mutual exclusive writing 96 | [allow_uav_condition] 97 | for (i = 0, depthMin = 0xffffffff; i < 0xffffffff && depthMin == 0xffffffff; ++i) 98 | { 99 | InterlockedExchange(g_rwDepth[pixelPos], 0xffffffff, depthMin); 100 | if (depthMin != 0xffffffff) 101 | // Critical section 102 | g_rwDepth[pixelPos] = min(depth, depthMin); 103 | } 104 | #else 105 | InterlockedMin(g_rwDepth[pixelPos], depth, depthMin); 106 | #endif 107 | if (depth > depthMin) return; 108 | 109 | // Interpolations 110 | float3 persp = float3(w.x * primVPos[0].w, w.y * primVPos[1].w, w.z * primVPos[2].w); 111 | input.Pos.w = 1.0 / (persp.x + persp.y + persp.z); 112 | persp *= input.Pos.w; 113 | 114 | #include "SetAttributes.hlsli" 115 | 116 | // Call pixel shader 117 | #ifndef CR_OUT_STRUCT_TYPE 118 | #define CR_OUT_STRUCT_TYPE CR_TARGET_TYPE0 119 | #endif 120 | CR_OUT_STRUCT_TYPE output = PSMain(input); 121 | 122 | #if USE_MUTEX 123 | // Mutual exclusive writing 124 | [allow_uav_condition] 125 | for (i = 0, depthMin = 0xffffffff; i < 0xffffffff && depthMin == 0xffffffff; ++i) 126 | { 127 | InterlockedExchange(g_rwDepth[pixelPos], 0xffffffff, depthMin); 128 | if (depthMin != 0xffffffff) 129 | { 130 | // Critical section 131 | if (depth <= depthMin) 132 | { 133 | //g_rwRenderTarget[pixelPos] = float4(w, 1.0); 134 | #include "SetTargets.hlsli" 135 | } 136 | g_rwDepth[pixelPos] = min(depth, depthMin); 137 | } 138 | } 139 | #else 140 | // This path is not fully watertight, but is faster and works in most cases 141 | DeviceMemoryBarrier(); 142 | if (depth == g_rwDepth[pixelPos]) 143 | { 144 | #include "SetTargets.hlsli" 145 | } 146 | #endif 147 | } 148 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/PixelShader.hlsl: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | //-------------------------------------------------------------------------------------- 6 | // Structures 7 | //-------------------------------------------------------------------------------------- 8 | struct PSIn 9 | { 10 | float4 Pos : SV_POSITION; 11 | float3 Nrm : NORMAL; 12 | }; 13 | 14 | cbuffer cbLighting 15 | { 16 | float4 g_ambientColor; 17 | float4 g_lightColor; 18 | float3 g_lightPt; 19 | float3 g_eyePt; 20 | }; 21 | 22 | cbuffer cbMaterial 23 | { 24 | float3 g_baseColor; 25 | }; 26 | 27 | static float3 g_ambient = g_ambientColor.xyz * g_ambientColor.w; 28 | static float3 g_light = g_lightColor.xyz * g_lightColor.w; 29 | 30 | //-------------------------------------------------------------------------------------- 31 | // Pixel shader 32 | //-------------------------------------------------------------------------------------- 33 | float4 main(PSIn input) : SV_TARGET 34 | { 35 | const float3 L = normalize(g_lightPt); 36 | const float3 N = normalize(input.Nrm); 37 | const float3 V = normalize(g_eyePt); 38 | 39 | const float lightAmt = saturate(dot(N, L)); 40 | const float ambientAmt = N.y * 0.5 + 0.5; 41 | 42 | const float3 H = normalize(V + L); 43 | const float NoH = saturate(dot(N, H)); 44 | 45 | const float3 diffuse = lightAmt * g_light; 46 | const float3 spec = 3.14 * 0.08 * pow(NoH, 64.0) * g_light; 47 | const float3 ambient = ambientAmt * g_ambient; 48 | 49 | float3 result = g_baseColor * (diffuse + ambient) + spec; 50 | result /= result + 1.0; 51 | 52 | return float4(result, 1.0); 53 | } 54 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/SetAttributes.hlsli: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #if DEFINED_ATTRIBUTE(0) 6 | SET_ATTRIBUTE(0); 7 | #endif 8 | 9 | #if DEFINED_ATTRIBUTE(1) 10 | SET_ATTRIBUTE(1); 11 | #endif 12 | 13 | #if DEFINED_ATTRIBUTE(2) 14 | SET_ATTRIBUTE(2); 15 | #endif 16 | 17 | #if DEFINED_ATTRIBUTE(3) 18 | SET_ATTRIBUTE(3); 19 | #endif 20 | 21 | #if DEFINED_ATTRIBUTE(4) 22 | SET_ATTRIBUTE(4); 23 | #endif 24 | 25 | #if DEFINED_ATTRIBUTE(5) 26 | SET_ATTRIBUTE(5); 27 | #endif 28 | 29 | #if DEFINED_ATTRIBUTE(6) 30 | SET_ATTRIBUTE(6); 31 | #endif 32 | 33 | #if DEFINED_ATTRIBUTE(7) 34 | SET_ATTRIBUTE(7); 35 | #endif 36 | 37 | #if DEFINED_ATTRIBUTE(8) 38 | SET_ATTRIBUTE(8); 39 | #endif 40 | 41 | #if DEFINED_ATTRIBUTE(9) 42 | SET_ATTRIBUTE(9); 43 | #endif 44 | 45 | #if DEFINED_ATTRIBUTE(10) 46 | SET_ATTRIBUTE(10); 47 | #endif 48 | 49 | #if DEFINED_ATTRIBUTE(11) 50 | SET_ATTRIBUTE(11); 51 | #endif 52 | 53 | #if DEFINED_ATTRIBUTE(12) 54 | SET_ATTRIBUTE(12); 55 | #endif 56 | 57 | #if DEFINED_ATTRIBUTE(13) 58 | SET_ATTRIBUTE(13); 59 | #endif 60 | 61 | #if DEFINED_ATTRIBUTE(14) 62 | SET_ATTRIBUTE(14); 63 | #endif 64 | 65 | #if DEFINED_ATTRIBUTE(15) 66 | SET_ATTRIBUTE(15); 67 | #endif 68 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/SetTargets.hlsli: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #if DEFINED_TARGET(0) 6 | SET_TARGET(0); 7 | #elif defined(CR_TARGET_TYPE0) 8 | g_rwRenderTarget0[pixelPos] = output; 9 | #endif 10 | 11 | #if DEFINED_TARGET(1) 12 | SET_TARGET(1); 13 | #endif 14 | 15 | #if DEFINED_TARGET(2) 16 | SET_TARGET(2); 17 | #endif 18 | 19 | #if DEFINED_TARGET(3) 20 | SET_TARGET(3); 21 | #endif 22 | 23 | #if DEFINED_TARGET(4) 24 | SET_TARGET(4); 25 | #endif 26 | 27 | #if DEFINED_TARGET(5) 28 | SET_TARGET(5); 29 | #endif 30 | 31 | #if DEFINED_TARGET(6) 32 | SET_TARGET(6); 33 | #endif 34 | 35 | #if DEFINED_TARGET(7) 36 | SET_TARGET(7); 37 | #endif 38 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/TileRaster.hlsl: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #include "SharedConst.h" 6 | #include "Common.hlsli" 7 | 8 | //-------------------------------------------------------------------------------------- 9 | // Buffers 10 | //-------------------------------------------------------------------------------------- 11 | StructuredBuffer g_roBinPrimitives; 12 | 13 | //-------------------------------------------------------------------------------------- 14 | // UAV buffers 15 | //-------------------------------------------------------------------------------------- 16 | RWStructuredBuffer g_rwVertexPos; 17 | RWStructuredBuffer g_rwTilePrimCount; 18 | RWStructuredBuffer g_rwTilePrimitives; 19 | 20 | globallycoherent 21 | RWTexture2D g_rwTileZ; 22 | RWTexture2D g_rwHiZ; 23 | 24 | [numthreads(8, 8, 1)] 25 | void main(uint2 GTid : SV_GroupThreadID, uint Gid : SV_GroupID)//, uint GTidx : SV_GroupIndex) 26 | { 27 | TilePrim tilePrim = g_roBinPrimitives[Gid]; 28 | const uint2 bin = uint2(tilePrim.TileIdx % g_binDim.x, tilePrim.TileIdx / g_binDim.x); 29 | 30 | float3x4 primVPos; 31 | 32 | // Load the vertex positions of the triangle 33 | const uint baseVIdx = tilePrim.PrimId * 3; 34 | [unroll] 35 | for (uint i = 0; i < 3; ++i) primVPos[i] = g_rwVertexPos[baseVIdx + i]; 36 | 37 | // To screen space. 38 | ToScreenSpace(primVPos); 39 | 40 | #if RE_HI_Z 41 | const uint zMin = asuint(min(primVPos[0].z, min(primVPos[1].z, primVPos[2].z))); 42 | if (g_rwHiZ[bin] < zMin) return; 43 | #endif 44 | 45 | // Scale the primitive for conservative rasterization. 46 | float3x2 v; 47 | [unroll] 48 | for (i = 0; i < 3; ++i) v[i] = primVPos[i].xy / TILE_SIZE; 49 | float3x2 sv = Scale(v, 0.5); 50 | 51 | float3 w; 52 | const uint2 tile = (bin << TILE_TO_BIN_LOG) + GTid; 53 | const float2 pos = tile + 0.5; 54 | if (!Overlap(pos, sv, w)) return; 55 | 56 | #if HI_Z 57 | // Depth test 58 | #if !RE_HI_Z 59 | const uint zMin = asuint(min(primVPos[0].z, min(primVPos[1].z, primVPos[2].z))); 60 | #endif 61 | const uint zMax = asuint(max(primVPos[0].z, max(primVPos[1].z, primVPos[2].z))); 62 | 63 | // Shrink the primitive. 64 | const float area = determinant(v[0], v[1], v[2]); 65 | sv = Scale(v, -0.5); 66 | 67 | uint tileZ; 68 | if (area >= 2.0 && Overlap(pos, sv, w)) 69 | InterlockedMin(g_rwTileZ[tile], zMax, tileZ); 70 | else 71 | { 72 | DeviceMemoryBarrier(); 73 | tileZ = g_rwTileZ[tile]; 74 | } 75 | 76 | if (tileZ < zMin) return; 77 | #endif 78 | 79 | tilePrim.TileIdx = g_tileDim.x * tile.y + tile.x; 80 | 81 | uint idx; 82 | #if SHADER_MODEL >= 6 83 | // compute number of items to append for the whole wave 84 | const uint appendCount = WaveActiveCountBits(true); 85 | // update the output location for this whole wave 86 | if (WaveIsFirstLane()) 87 | { 88 | // this way, we only issue one atomic for the entire wave, which reduces contention 89 | // and keeps the output data for each lane in this wave together in the output buffer 90 | InterlockedAdd(g_rwTilePrimCount[0], appendCount, idx); 91 | } 92 | idx = WaveReadLaneFirst(idx); // broadcast value 93 | idx += WavePrefixCountBits(true); // and add in the offset for this lane 94 | // write to the offset location for this lane 95 | #else 96 | InterlockedAdd(g_rwTilePrimCount[0], 1, idx); 97 | #endif 98 | g_rwTilePrimitives[idx] = tilePrim; 99 | } 100 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/VSStage.hlsl: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #include "VSStage.hlsli" 6 | 7 | //-------------------------------------------------------------------------------------- 8 | // Fetch shader 9 | //-------------------------------------------------------------------------------------- 10 | void FetchShader(uint id, out VSIn result) 11 | { 12 | result = g_roVertexBuffer[id]; 13 | } 14 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/VSStage.hlsli: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #define main VSMain 6 | #include "VertexShader.hlsl" 7 | #undef main 8 | 9 | #define CR_ATTRIBUTE_GEN_TYPE(t, c) t##c 10 | #define CR_ATTRIBUTE_TYPE(n) CR_ATTRIBUTE_GEN_TYPE(CR_ATTRIBUTE_BASE_TYPE##n, CR_ATTRIBUTE_COMPONENT_COUNT##n) 11 | 12 | #define SET_ATTRIBUTE(n) g_rwVertexAtt##n[DTid] = output.CR_ATTRIBUTE##n 13 | 14 | #define DEFINED_ATTRIBUTE(n) (defined(CR_ATTRIBUTE_BASE_TYPE##n) && defined(CR_ATTRIBUTE_COMPONENT_COUNT##n)) 15 | #define DECLARE_ATTRIBUTE(n) RWBuffer g_rwVertexAtt##n 16 | 17 | //-------------------------------------------------------------------------------------- 18 | // Buffers 19 | //-------------------------------------------------------------------------------------- 20 | StructuredBuffer g_roVertexBuffer; 21 | Buffer g_roIndexBuffer; 22 | 23 | //-------------------------------------------------------------------------------------- 24 | // UAV buffers 25 | //-------------------------------------------------------------------------------------- 26 | RWStructuredBuffer g_rwVertexPos; 27 | #include "DeclareAttributes.hlsli" 28 | 29 | //-------------------------------------------------------------------------------------- 30 | // Fetch shader 31 | //-------------------------------------------------------------------------------------- 32 | void FetchShader(uint id, out VSIn result); 33 | 34 | //-------------------------------------------------------------------------------------- 35 | // Vertex shader stage process 36 | //-------------------------------------------------------------------------------------- 37 | [numthreads(64, 1, 1)] 38 | void main(uint DTid : SV_DispatchThreadID) 39 | { 40 | VSIn input; 41 | FetchShader(DTid, input); 42 | 43 | // Call vertex shader 44 | VSOut output = VSMain(input); 45 | 46 | g_rwVertexPos[DTid] = output.Pos; 47 | 48 | #include "SetAttributes.hlsli" 49 | } 50 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/VSStageIndexed.hlsl: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #include "VSStage.hlsli" 6 | 7 | //-------------------------------------------------------------------------------------- 8 | // Fetch shader 9 | //-------------------------------------------------------------------------------------- 10 | void FetchShader(uint id, out VSIn result) 11 | { 12 | const uint index = g_roIndexBuffer[id]; 13 | result = g_roVertexBuffer[index]; 14 | } 15 | -------------------------------------------------------------------------------- /ComputeRaster/Content/Shaders/VertexShader.hlsl: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | //-------------------------------------------------------------------------------------- 6 | // Structures 7 | //-------------------------------------------------------------------------------------- 8 | struct VSIn 9 | { 10 | float3 Pos : POSITION; 11 | float3 Nrm : NORMAL; 12 | }; 13 | 14 | struct VSOut 15 | { 16 | float4 Pos : SV_POSITION; 17 | float3 Nrm : NORMAL; 18 | }; 19 | 20 | cbuffer cb 21 | { 22 | matrix g_worldViewProj; 23 | matrix g_normal; 24 | }; 25 | 26 | //-------------------------------------------------------------------------------------- 27 | // Vertex shader 28 | //-------------------------------------------------------------------------------------- 29 | VSOut main(VSIn input) 30 | { 31 | VSOut output; 32 | 33 | output.Pos = float4(input.Pos, 1.0); 34 | output.Pos = mul(output.Pos, g_worldViewProj); 35 | output.Nrm = mul(input.Nrm, (float3x3)g_normal); 36 | 37 | return output; 38 | } 39 | -------------------------------------------------------------------------------- /ComputeRaster/Content/SharedConst.h: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #define FRAME_COUNT 3 6 | 7 | #define USE_TRIPPLE_RASTER 1 8 | 9 | #define TILE_SIZE_LOG 3 10 | #define TILE_SIZE (1 << TILE_SIZE_LOG) 11 | #define TILE_TO_BIN_LOG 3 12 | #define BIN_SIZE_LOG (TILE_SIZE_LOG + TILE_TO_BIN_LOG) 13 | #define BIN_SIZE (1 << BIN_SIZE_LOG) 14 | 15 | #define CLEAR_COLOR 0.0f, 0.2f, 0.4f 16 | 17 | #define PIDIV4 0.785398163f 18 | 19 | static const float g_FOVAngleY = PIDIV4; 20 | static const float g_zNear = 1.0f; 21 | static const float g_zFar = 1000.0f; 22 | -------------------------------------------------------------------------------- /ComputeRaster/Content/SoftGraphicsPipeline.h: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #pragma once 6 | 7 | #include "Core/XUSG.h" 8 | #include "SharedConst.h" 9 | 10 | class SoftGraphicsPipeline 11 | { 12 | public: 13 | struct DepthBuffer 14 | { 15 | XUSG::Texture2D::uptr PixelZ; 16 | XUSG::Texture2D::uptr TileZ; 17 | XUSG::Texture2D::uptr BinZ; 18 | }; 19 | 20 | SoftGraphicsPipeline(); 21 | virtual ~SoftGraphicsPipeline(); 22 | 23 | bool Init(XUSG::CommandList* pCommandList, std::vector& uploaders); 24 | bool CreateVertexShaderLayout(XUSG::Util::PipelineLayout* pPipelineLayout, 25 | uint32_t slotCount = 0, int32_t srvBindingMax = -1, int32_t uavBindingMax = -1); 26 | bool CreatePixelShaderLayout(XUSG::Util::PipelineLayout* pPipelineLayout, 27 | bool hasDepth, uint32_t numRTs, uint32_t slotCount = 0, int32_t cbvBindingMax = -1, 28 | int32_t srvBindingMax = -1, int32_t uavBindingMax = -1); 29 | void SetDecriptorHeaps(XUSG::CommandList* pCommandList); 30 | void SetAttribute(uint32_t i, uint32_t stride, XUSG::Format format, const wchar_t* name = L"Attribute"); 31 | void SetVertexBuffer(const XUSG::Descriptor& vertexBufferView); 32 | void SetIndexBuffer(const XUSG::Descriptor& indexBufferView); 33 | void SetRenderTargets(uint32_t numRTs, XUSG::Texture2D* pColorTarget, DepthBuffer* pDepth); 34 | void SetViewport(const XUSG::Viewport& viewport); 35 | void VSSetDescriptorTable(uint32_t i, const XUSG::DescriptorTable& descriptorTable); 36 | void PSSetDescriptorTable(uint32_t i, const XUSG::DescriptorTable& descriptorTable); 37 | void ClearFloat(const XUSG::Texture2D& target, const float clearValues[4]); 38 | void ClearUint(const XUSG::Texture2D& target, const uint32_t clearValues[4]); 39 | void ClearDepth(const float clearValue); 40 | void Draw(XUSG::CommandList* pCommandList, uint32_t numVertices); 41 | void DrawIndexed(XUSG::CommandList* pCommandList, uint32_t numIndices); 42 | 43 | bool CreateDepthBuffer(const XUSG::Device* pDevice, DepthBuffer &depth, uint32_t width, 44 | uint32_t height, XUSG::Format format, const wchar_t* name = L"Depth"); 45 | bool CreateVertexBuffer(XUSG::CommandList* pCommandList, XUSG::VertexBuffer& vb, 46 | std::vector& uploaders, const void* pData, uint32_t numVert, 47 | uint32_t srtide, const wchar_t* name = L"VertexBuffer") const; 48 | bool CreateIndexBuffer(XUSG::CommandList* pCommandList, XUSG::IndexBuffer& ib, 49 | std::vector& uploaders, const void* pData, uint32_t numIdx, 50 | XUSG::Format format, const wchar_t* name = L"IndexBuffer"); 51 | XUSG::DescriptorTableLib* GetDescriptorTableLib() const; 52 | 53 | static const uint8_t FrameCount = FRAME_COUNT; 54 | 55 | protected: 56 | enum StageIndex : uint8_t 57 | { 58 | VERTEX_PROCESS, 59 | VERTEX_INDEXED, 60 | BIN_RASTER, 61 | TILE_RASTER, 62 | PIX_RASTER, 63 | 64 | NUM_STAGE 65 | }; 66 | 67 | enum SRVTable : uint8_t 68 | { 69 | SRV_TABLE_VS, 70 | SRV_TABLE_TR, 71 | SRV_TABLE_PS, 72 | 73 | NUM_SRV_TABLE 74 | }; 75 | 76 | enum UAVTable : uint8_t 77 | { 78 | UAV_TABLE_VS, 79 | UAV_TABLE_RS, 80 | 81 | NUM_UAV_TABLE 82 | }; 83 | 84 | struct CBViewPort 85 | { 86 | float TopLeftX; 87 | float TopLeftY; 88 | float Width; 89 | float Height; 90 | uint32_t NumTileX; 91 | uint32_t NumTileY; 92 | uint32_t NumBinX; 93 | uint32_t NumBinY; 94 | }; 95 | 96 | struct AttributeInfo 97 | { 98 | uint32_t Stride; 99 | XUSG::Format Format; 100 | std::wstring Name; 101 | }; 102 | 103 | struct ClearInfo 104 | { 105 | bool IsUint; 106 | const XUSG::Texture2D* pTarget; 107 | union 108 | { 109 | float ClearFloat[4]; 110 | uint32_t ClearUint[4]; 111 | }; 112 | }; 113 | 114 | bool createPipelines(); 115 | bool createResetBuffer(XUSG::CommandList* pCommandList, std::vector& uploaders); 116 | bool createCommandLayout(const XUSG::Device* pDevice); 117 | bool createDescriptorTables(); 118 | 119 | void draw(XUSG::CommandList* pCommandList, uint32_t num, StageIndex vs); 120 | void rasterizer(XUSG::CommandList* pCommandList, uint32_t numTriangles); 121 | 122 | XUSG::ShaderLib::uptr m_shaderLib; 123 | XUSG::Compute::PipelineLib::uptr m_computePipelineLib; 124 | XUSG::PipelineLayoutLib::uptr m_pipelineLayoutLib; 125 | XUSG::DescriptorTableLib::uptr m_descriptorTableLib; 126 | 127 | XUSG::PipelineLayout m_pipelineLayouts[NUM_STAGE]; 128 | XUSG::Pipeline m_pipelines[NUM_STAGE]; 129 | XUSG::CommandLayout::uptr m_commandLayout; 130 | 131 | std::vector m_clears; 132 | std::vector m_extVsTables; 133 | std::vector m_extPsTables; 134 | std::vector m_outTables; 135 | 136 | XUSG::DescriptorTable m_cbvTable; 137 | XUSG::DescriptorTable m_srvTables[NUM_SRV_TABLE]; 138 | XUSG::DescriptorTable m_uavTables[NUM_UAV_TABLE]; 139 | XUSG::DescriptorTable m_samplerTable; 140 | 141 | XUSG::ConstantBuffer::uptr m_cbMatrices; 142 | XUSG::ConstantBuffer::uptr m_cbPerFrame; 143 | XUSG::ConstantBuffer::uptr m_cbPerObject; 144 | XUSG::ConstantBuffer::uptr m_cbBound; 145 | 146 | XUSG::Descriptor m_vertexBufferView; 147 | XUSG::Descriptor m_indexBufferView; 148 | XUSG::Texture2D* m_pColorTarget; 149 | DepthBuffer* m_pDepth; 150 | 151 | std::vector m_attribInfo; 152 | std::vector m_vertexAttribs; 153 | XUSG::StructuredBuffer::uptr m_vertexCompletions; 154 | XUSG::StructuredBuffer::uptr m_vertexPos; 155 | XUSG::StructuredBuffer::uptr m_tilePrimCountReset; 156 | XUSG::StructuredBuffer::uptr m_binPrimCount; 157 | XUSG::StructuredBuffer::uptr m_binPrimitives; 158 | XUSG::StructuredBuffer::uptr m_tilePrimCount; 159 | XUSG::StructuredBuffer::uptr m_tilePrimitives; 160 | 161 | XUSG::Viewport m_viewport; 162 | 163 | uint32_t m_maxVertexCount; 164 | uint32_t m_numColorTargets; 165 | uint32_t m_clearDepth; 166 | }; 167 | -------------------------------------------------------------------------------- /ComputeRaster/Main.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "ComputeRaster.h" 13 | 14 | _Use_decl_annotations_ 15 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) 16 | { 17 | ComputeRaster computeRaster(800, 600, L"Compute Rasterization"); 18 | 19 | return Win32Application::Run(&computeRaster, hInstance, nCmdShow); 20 | } 21 | -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/Debug/XUSG.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/Debug/XUSG.dll -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/Debug/XUSG.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/Debug/XUSG.lib -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/Debug/XUSG.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/Debug/XUSG.pdb -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/Release/XUSG.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/Release/XUSG.dll -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/Release/XUSG.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/Release/XUSG.lib -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/x64/Debug/XUSG.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/x64/Debug/XUSG.dll -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/x64/Debug/XUSG.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/x64/Debug/XUSG.lib -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/x64/Debug/XUSG.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/x64/Debug/XUSG.pdb -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/x64/Release/XUSG.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/x64/Release/XUSG.dll -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Bin/x64/Release/XUSG.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/ComputeRaster/XUSG/Bin/x64/Release/XUSG.lib -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Optional/XUSGObjLoader.cpp: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #include "XUSGObjLoader.h" 6 | 7 | using namespace std; 8 | using namespace XUSG; 9 | 10 | ObjLoader::ObjLoader() 11 | { 12 | } 13 | 14 | ObjLoader::~ObjLoader() 15 | { 16 | } 17 | 18 | bool ObjLoader::Import(const char* pszFilename, bool needNorm, bool needAABB, bool forDX, bool swapYZ) 19 | { 20 | FILE* pFile; 21 | fopen_s(&pFile, pszFilename, "r"); 22 | 23 | if (!pFile) return false; 24 | 25 | m_stride = sizeof(float3); 26 | m_stride += needNorm ? sizeof(float3) : 0; 27 | 28 | // Import the OBJ file. 29 | uint32_t numTexc, numNorm; 30 | importGeometryFirstPass(pFile, numTexc, numNorm); 31 | rewind(pFile); 32 | importGeometrySecondPass(pFile, numTexc, numNorm, forDX, swapYZ); 33 | fclose(pFile); 34 | 35 | // Perform post import tasks. 36 | if (needNorm && !numNorm) recomputeNormals(); 37 | if (needAABB) computeAABB(); 38 | 39 | return true; 40 | } 41 | 42 | const uint32_t ObjLoader::GetNumVertices() const 43 | { 44 | return static_cast(m_vertices.size() / GetVertexStride()); 45 | } 46 | 47 | const uint32_t ObjLoader::GetNumIndices() const 48 | { 49 | return static_cast(m_indices.size()); 50 | } 51 | 52 | const uint32_t ObjLoader::GetVertexStride() const 53 | { 54 | return m_stride; 55 | } 56 | 57 | const uint8_t* ObjLoader::GetVertices() const 58 | { 59 | return m_vertices.data(); 60 | } 61 | 62 | const uint32_t* ObjLoader::GetIndices() const 63 | { 64 | return m_indices.data(); 65 | } 66 | 67 | const ObjLoader::AABB& ObjLoader::GetAABB() const 68 | { 69 | return m_aabb; 70 | } 71 | 72 | void ObjLoader::importGeometryFirstPass(FILE* pFile, uint32_t& numTexc, uint32_t& numNorm) 73 | { 74 | auto v = 0u; 75 | auto vt = 0u; 76 | auto vn = 0u; 77 | char buffer[256] = { 0 }; 78 | 79 | auto numVert = 0u; 80 | auto numTri = 0u; 81 | numTexc = 0; 82 | numNorm = 0; 83 | 84 | while (fscanf_s(pFile, "%s", buffer, static_cast(sizeof(buffer))) != EOF) 85 | { 86 | switch (buffer[0]) 87 | { 88 | case 'f': // v, v//vn, v/vt, v/vt/vn. 89 | fscanf_s(pFile, "%s", buffer, static_cast(sizeof(buffer))); 90 | 91 | if (strstr(buffer, "//")) // v//vn 92 | { 93 | sscanf_s(buffer, "%u//%u", &v, &vn); 94 | fscanf_s(pFile, "%u//%u", &v, &vn); 95 | fscanf_s(pFile, "%u//%u", &v, &vn); 96 | ++numTri; 97 | 98 | while (fscanf_s(pFile, "%u//%u", &v, &vn) > 0) ++numTri; 99 | } 100 | else if (sscanf_s(buffer, "%u/%u/%u", &v, &vt, &vn) == 3) // v/vt/vn 101 | { 102 | fscanf_s(pFile, "%u/%u/%u", &v, &vt, &vn); 103 | fscanf_s(pFile, "%u/%u/%u", &v, &vt, &vn); 104 | ++numTri; 105 | 106 | while (fscanf_s(pFile, "%u/%u/%u", &v, &vt, &vn) > 0) ++numTri; 107 | 108 | //m_hasTexcoord = true; 109 | } 110 | else if (sscanf_s(buffer, "%u/%u", &v, &vt) == 2) // v/vt 111 | { 112 | fscanf_s(pFile, "%u/%u", &v, &vt); 113 | fscanf_s(pFile, "%u/%u", &v, &vt); 114 | ++numTri; 115 | 116 | while (fscanf_s(pFile, "%u/%u", &v, &vt) > 0) ++numTri; 117 | 118 | //m_hasTexcoord = true; 119 | } 120 | else // v 121 | { 122 | fscanf_s(pFile, "%u", &v); 123 | fscanf_s(pFile, "%u", &v); 124 | ++numTri; 125 | 126 | while (fscanf_s(pFile, "%u", &v) > 0) 127 | ++numTri; 128 | } 129 | break; 130 | 131 | case 'v': // v, vt, or vn 132 | switch (buffer[1]) 133 | { 134 | case '\0': 135 | fgets(buffer, sizeof(buffer), pFile); 136 | ++numVert; 137 | break; 138 | case 't': 139 | fgets(buffer, sizeof(buffer), pFile); 140 | ++numTexc; 141 | break; 142 | case 'n': 143 | fgets(buffer, sizeof(buffer), pFile); 144 | ++numNorm; 145 | break; 146 | default: 147 | break; 148 | } 149 | break; 150 | 151 | default: 152 | fgets(buffer, sizeof(buffer), pFile); 153 | break; 154 | } 155 | } 156 | 157 | // Allocate memory for the OBJ model data. 158 | const auto numIdx = numTri * 3; 159 | m_stride += m_stride <= sizeof(float3) && numNorm ? sizeof(float3) : 0; 160 | m_stride += numTexc ? sizeof(float[2]) : 0; 161 | m_vertices.reserve(m_stride * (max)((max)(numVert, numTexc), numNorm)); 162 | m_vertices.resize(m_stride * numVert); 163 | m_indices.resize(numIdx); 164 | } 165 | 166 | void ObjLoader::importGeometrySecondPass(FILE* pFile, uint32_t numTexc, uint32_t numNorm, bool forDX, bool swapYZ) 167 | { 168 | auto numVert = 0u; 169 | auto numTri = 0u; 170 | char buffer[256] = { 0 }; 171 | 172 | vector normals; 173 | vector tIndices, nIndices; 174 | if (numTexc) tIndices.resize(m_indices.size()); 175 | if (numNorm) nIndices.resize(m_indices.size()); 176 | normals.reserve(numNorm); 177 | 178 | while (fscanf_s(pFile, "%s", buffer, static_cast(sizeof(buffer))) != EOF) 179 | { 180 | switch (buffer[0]) 181 | { 182 | case 'f': // v, v//vn, v/vt, or v/vt/vn. 183 | loadIndices(pFile, numTri, numTexc, numNorm, nIndices, tIndices); 184 | break; 185 | case 'v': // v, vn, or vt. 186 | switch (buffer[1]) 187 | { 188 | case '\0': // v 189 | { 190 | auto& p = getPosition(numVert++); 191 | fscanf_s(pFile, "%f %f %f", &p.x, &p.y, &p.z); 192 | if (swapYZ) 193 | { 194 | const auto tmp = p.y; 195 | p.y = p.z; 196 | p.z = tmp; 197 | } 198 | p.z = forDX ? -p.z : p.z; 199 | break; 200 | } 201 | case 'n': 202 | normals.emplace_back(); 203 | fscanf_s(pFile, "%f %f %f", 204 | &normals.back().x, 205 | &normals.back().y, 206 | &normals.back().z); 207 | if (swapYZ) 208 | { 209 | const auto tmp = normals.back().y; 210 | normals.back().y = normals.back().z; 211 | normals.back().z = tmp; 212 | } 213 | normals.back().z = forDX ? -normals.back().z : normals.back().z; 214 | default: 215 | break; 216 | } 217 | break; 218 | 219 | default: 220 | fgets(buffer, sizeof(buffer), pFile); 221 | break; 222 | } 223 | } 224 | 225 | computePerVertexNormals(normals, nIndices); 226 | 227 | if ((forDX && !swapYZ) || (!forDX && swapYZ)) reverse(m_indices.begin(), m_indices.end()); 228 | } 229 | 230 | void ObjLoader::loadIndices(FILE* pFile, uint32_t& numTri, uint32_t numTexc, 231 | uint32_t numNorm, vector& nIndices, vector& tIndices) 232 | { 233 | int64_t vi; 234 | uint32_t v[3] = { 0 }; 235 | uint32_t vt[3] = { 0 }; 236 | uint32_t vn[3] = { 0 }; 237 | 238 | const auto numVert = GetNumVertices(); 239 | 240 | for (uint8_t i = 0; i < 3; ++i) 241 | { 242 | fscanf_s(pFile, "%lld", &vi); 243 | v[i] = static_cast(vi < 0 ? vi + numVert : vi - 1); 244 | m_indices[numTri * 3 + i] = v[i]; 245 | 246 | if (tIndices.size() > 0) 247 | { 248 | fscanf_s(pFile, "/%lld", &vi); 249 | vt[i] = static_cast(vi < 0 ? vi + numTexc : vi - 1); 250 | tIndices[numTri * 3 + i] = vt[i]; 251 | } 252 | else if (nIndices.size() > 0) fscanf_s(pFile, "/"); 253 | 254 | if (nIndices.size() > 0) 255 | { 256 | fscanf_s(pFile, "/%lld", &vi); 257 | vn[i] = static_cast(vi < 0 ? vi + numNorm : vi - 1); 258 | nIndices[numTri * 3 + i] = vn[i]; 259 | } 260 | } 261 | ++numTri; 262 | 263 | v[1] = v[2]; 264 | vt[1] = vt[2]; 265 | vn[1] = vn[2]; 266 | 267 | while (fscanf_s(pFile, "%lld", &vi) > 0) 268 | { 269 | v[2] = static_cast(vi < 0 ? vi + numVert : vi - 1); 270 | m_indices[numTri * 3] = v[0]; 271 | m_indices[numTri * 3 + 1] = v[1]; 272 | m_indices[numTri * 3 + 2] = v[2]; 273 | v[1] = v[2]; 274 | 275 | if (tIndices.size() > 0) 276 | { 277 | fscanf_s(pFile, "/%lld", &vi); 278 | vt[2] = static_cast(vi < 0 ? vi + numTexc : vi - 1); 279 | tIndices[numTri * 3] = vt[0]; 280 | tIndices[numTri * 3 + 1] = vt[1]; 281 | tIndices[numTri * 3 + 2] = vt[2]; 282 | vt[1] = vt[2]; 283 | } 284 | else if (nIndices.size() > 0) fscanf_s(pFile, "/"); 285 | 286 | if (nIndices.size() > 0) 287 | { 288 | fscanf_s(pFile, "/%lld", &vi); 289 | vn[2] = static_cast(vi < 0 ? vi + numNorm : vi - 1); 290 | nIndices[numTri * 3] = vn[0]; 291 | nIndices[numTri * 3 + 1] = vn[1]; 292 | nIndices[numTri * 3 + 2] = vn[2]; 293 | vn[1] = vn[2]; 294 | } 295 | 296 | ++numTri; 297 | } 298 | } 299 | 300 | void ObjLoader::computePerVertexNormals(const vector& normals, const vector& nIndices) 301 | { 302 | if (normals.empty()) return; 303 | 304 | const auto stride = GetVertexStride(); 305 | vector vni(GetNumVertices(), UINT32_MAX); 306 | 307 | const auto numIdx = static_cast(m_indices.size()); 308 | for (auto i = 0u; i < numIdx; i++) 309 | { 310 | auto vi = m_indices[i]; 311 | if (vni[vi] == nIndices[i]) continue; 312 | 313 | if (vni[vi] < UINT32_MAX) 314 | { 315 | // Split vertex 316 | vi = GetNumVertices(); 317 | m_vertices.resize(m_vertices.size() + stride); 318 | const auto pDst = getVertex(vi); 319 | const auto pSrc = getVertex(m_indices[i]); 320 | memcpy(pDst, pSrc, stride); 321 | m_indices[i] = vi; 322 | } 323 | else vni[vi] = nIndices[i]; 324 | 325 | float3 n = normals[nIndices[i]]; 326 | const auto l = sqrt(n.x * n.x + n.y * n.y + n.z * n.z); 327 | n.x /= l; 328 | n.y /= l; 329 | n.z /= l; 330 | 331 | getNormal(vi) = n; 332 | } 333 | 334 | m_vertices.shrink_to_fit(); 335 | } 336 | 337 | void ObjLoader::recomputeNormals() 338 | { 339 | float3 e1, e2, n; 340 | 341 | const auto numTri = static_cast(m_indices.size()) / 3; 342 | for (auto i = 0u; i < numTri; i++) 343 | { 344 | const auto pv0 = &getPosition(m_indices[i * 3]); 345 | const auto pv1 = &getPosition(m_indices[i * 3 + 1]); 346 | const auto pv2 = &getPosition(m_indices[i * 3 + 2]); 347 | e1.x = pv1->x - pv0->x; 348 | e1.y = pv1->y - pv0->y; 349 | e1.z = pv1->z - pv0->z; 350 | e2.x = pv2->x - pv1->x; 351 | e2.y = pv2->y - pv1->y; 352 | e2.z = pv2->z - pv1->z; 353 | n.x = e1.y * e2.z - e1.z * e2.y; 354 | n.y = e1.z * e2.x - e1.x * e2.z; 355 | n.z = e1.x * e2.y - e1.y * e2.x; 356 | const auto l = sqrt(n.x * n.x + n.y * n.y + n.z * n.z); 357 | n.x /= l; 358 | n.y /= l; 359 | n.z /= l; 360 | 361 | const auto pVn0 = &getNormal(m_indices[i * 3]); 362 | const auto pVn1 = &getNormal(m_indices[i * 3 + 1]); 363 | const auto pVn2 = &getNormal(m_indices[i * 3 + 2]); 364 | pVn0->x += n.x; 365 | pVn0->y += n.y; 366 | pVn0->z += n.z; 367 | pVn1->x += n.x; 368 | pVn1->y += n.y; 369 | pVn1->z += n.z; 370 | pVn2->x += n.x; 371 | pVn2->y += n.y; 372 | pVn2->z += n.z; 373 | } 374 | 375 | const auto numVert = GetNumVertices(); 376 | for (auto i = 0u; i < numVert; ++i) 377 | { 378 | const auto pVn = &getNormal(i); 379 | const auto l = sqrt(pVn->x * pVn->x + pVn->y * pVn->y + pVn->z * pVn->z); 380 | pVn->x /= l; 381 | pVn->y /= l; 382 | pVn->z /= l; 383 | } 384 | } 385 | 386 | void ObjLoader::computeAABB() 387 | { 388 | float xMax, xMin, yMax, yMin, zMax, zMin; 389 | const auto& p = getPosition(0); 390 | xMax = xMin = p.x; 391 | yMax = yMin = p.y; 392 | zMax = zMin = p.z; 393 | 394 | auto x = 0.0f, y = 0.0f, z = 0.0f; 395 | 396 | const auto numVert = GetNumVertices(); 397 | for (auto i = 1u; i < numVert; ++i) 398 | { 399 | const auto& p = getPosition(i); 400 | x = p.x; 401 | y = p.y; 402 | z = p.z; 403 | 404 | if (x < xMin) xMin = x; 405 | else if (x > xMax) xMax = x; 406 | 407 | if (y < yMin) yMin = y; 408 | else if (y > yMax) yMax = y; 409 | 410 | if (z < zMin) zMin = z; 411 | else if (z > zMax) zMax = z; 412 | } 413 | 414 | m_aabb.Min = float3(xMin, yMin, zMin); 415 | m_aabb.Max = float3(xMax, yMax, zMax); 416 | } 417 | 418 | void* ObjLoader::getVertex(uint32_t i) 419 | { 420 | return &m_vertices[GetVertexStride() * i]; 421 | } 422 | 423 | ObjLoader::float3& ObjLoader::getPosition(uint32_t i) 424 | { 425 | return reinterpret_cast(getVertex(i))[0]; 426 | } 427 | 428 | ObjLoader::float3& ObjLoader::getNormal(uint32_t i) 429 | { 430 | return reinterpret_cast(getVertex(i))[1]; 431 | } 432 | -------------------------------------------------------------------------------- /ComputeRaster/XUSG/Optional/XUSGObjLoader.h: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // Copyright (c) XU, Tianchen. All rights reserved. 3 | //-------------------------------------------------------------------------------------- 4 | 5 | #pragma once 6 | 7 | namespace XUSG 8 | { 9 | class ObjLoader 10 | { 11 | public: 12 | struct float3 13 | { 14 | float x; 15 | float y; 16 | float z; 17 | 18 | float3() = default; 19 | constexpr float3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} 20 | explicit float3(const float* pArray) : x(pArray[0]), y(pArray[1]), z(pArray[2]) {} 21 | 22 | float3& operator= (const float3& Float3) { x = Float3.x; y = Float3.y; z = Float3.z; return *this; } 23 | }; 24 | 25 | struct AABB 26 | { 27 | float3 Min; 28 | float3 Max; 29 | }; 30 | 31 | ObjLoader(); 32 | virtual ~ObjLoader(); 33 | 34 | bool Import(const char* pszFilename, bool needNorm = true, 35 | bool needAABB = true, bool forDX = true, bool swapYZ = false); 36 | 37 | const uint32_t GetNumVertices() const; 38 | const uint32_t GetNumIndices() const; 39 | const uint32_t GetVertexStride() const; 40 | const uint8_t* GetVertices() const; 41 | const uint32_t* GetIndices() const; 42 | 43 | const AABB& GetAABB() const; 44 | 45 | protected: 46 | void importGeometryFirstPass(FILE* pFile, uint32_t& numTexc, uint32_t& numNorm); 47 | void importGeometrySecondPass(FILE* pFile, uint32_t numTexc, uint32_t numNorm, bool forDX, bool swapYZ); 48 | void loadIndices(FILE* pFile, uint32_t& numTri, uint32_t numTexc, uint32_t numNorm, 49 | std::vector& nIndices, std::vector& tIndices); 50 | void computePerVertexNormals(const std::vector& normals, const std::vector& nIndices); 51 | void recomputeNormals(); 52 | void computeAABB(); 53 | 54 | void* getVertex(uint32_t i); 55 | float3& getPosition(uint32_t i); 56 | float3& getNormal(uint32_t i); 57 | 58 | std::vector m_vertices; 59 | std::vector m_indices; 60 | 61 | uint32_t m_stride; 62 | 63 | AABB m_aabb; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /ComputeRaster/stdafx.cpp: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #include "stdafx.h" 13 | -------------------------------------------------------------------------------- /ComputeRaster/stdafx.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | // stdafx.h : include file for standard system include files, 13 | // or project specific include files that are used frequently, but 14 | // are changed infrequently. 15 | 16 | #pragma once 17 | 18 | #ifndef WIN32_LEAN_AND_MEAN 19 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers. 20 | #endif 21 | 22 | #define XUSG_INTERFACE __declspec(dllimport) 23 | 24 | #include 25 | 26 | #include "d3d12.h" 27 | #include 28 | #include 29 | #include 30 | 31 | // C RunTime Header Files 32 | #include 33 | #include 34 | #include 35 | 36 | #if _HAS_CXX17 37 | #include 38 | #else 39 | #include 40 | #include 41 | #include 42 | #include 43 | #endif 44 | #include 45 | #include 46 | #include 47 | 48 | #if defined(DEBUG) | defined(_DEBUG) 49 | #ifndef DBG_NEW 50 | #define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) 51 | #define new DBG_NEW 52 | #endif 53 | #endif // _DEBUG 54 | -------------------------------------------------------------------------------- /Doc/Images/Bunny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Doc/Images/Bunny.jpg -------------------------------------------------------------------------------- /Doc/Images/Venus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarsX/ComputeRaster/ef60bdf6bef4635393b96bd6ef9f871ca98f9438/Doc/Images/Venus.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ComputeRaster 2 | Real-time software rasterizer using compute shaders, including vertex processing stage (IA and vertex shaders), bin rasterization, tile rasterization (coarse rasterization), and pixel rasterization (fine rasterization, which calls the pixel shaders). The execution of the tile rasterization pass adaptively depends on the primitive areas accordingly. In bin rasterization pass, if the primitive area is greater then 4x4 tile sizes, the bin rasterization will be triggered; otherwise, the bin rasterization pass will directly output to the tile space instead, and skip processing the corresponding primitive in the tile rasterization pass. 3 | 4 | ![Bunny result](https://github.com/StarsX/ComputeRaster/blob/master/Doc/Images/Bunny.jpg "Bunny raterized rendering result") 5 | ![Venus result](https://github.com/StarsX/ComputeRaster/blob/master/Doc/Images/Venus.jpg "Venus raterized rendering result") 6 | 7 | Hot keys: 8 | 9 | [F1] show/hide FPS 10 | 11 | [Space] pause/play animation 12 | 13 | Prerequisite: 14 | https://github.com/StarsX/XUSG 15 | --------------------------------------------------------------------------------