ソースを参照

NVIDIA Image Scaling SDK v1.0.1

- Performance optimizations
- fp16 coefficients support
- GLSL support
- DX12 and Vulkan samples
Ariel Bernal 2 年 前
コミット
59677206df
100 ファイル変更10540 行追加14255 行削除
  1. 137 1
      NIS/NIS_Config.h
  2. 93 0
      NIS/NIS_Main.glsl
  3. 7 9
      NIS/NIS_Main.hlsl
  4. 435 432
      NIS/NIS_Scaler.h
  5. 39 11
      README.md
  6. BIN
      docs/NIS_SDK_Programming_Guide.pdf
  7. 28 1
      samples/CMakeLists.txt
  8. 10 3
      samples/DX11/CMakeLists.txt
  9. 6 6
      samples/DX11/include/AppRenderer.h
  10. 4 4
      samples/DX11/include/BilinearUpscale.h
  11. 6 6
      samples/DX11/include/DXUtilities.h
  12. 13 13
      samples/DX11/include/DeviceResources.h
  13. 5 5
      samples/DX11/include/NVScaler.h
  14. 5 5
      samples/DX11/include/NVSharpen.h
  15. 10 10
      samples/DX11/include/UIRenderer.h
  16. 39 14
      samples/DX11/src/AppRenderer.cpp
  17. 35 32
      samples/DX11/src/DeviceResources.cpp
  18. 25 15
      samples/DX11/src/NVScaler.cpp
  19. 14 5
      samples/DX11/src/NVSharpen.cpp
  20. 31 32
      samples/DX11/src/Sample.cpp
  21. 12 12
      samples/DX11/src/UIRenderer.cpp
  22. 94 0
      samples/DX12/CMakeLists.txt
  23. 107 0
      samples/DX12/include/AppRenderer.h
  24. 83 0
      samples/DX12/include/BilinearUpscale.h
  25. 76 0
      samples/DX12/include/DXUtilities.h
  26. 174 0
      samples/DX12/include/DeviceResources.h
  27. 74 0
      samples/DX12/include/NVScaler.h
  28. 61 0
      samples/DX12/include/NVSharpen.h
  29. 75 0
      samples/DX12/include/UIRenderer.h
  30. 3439 0
      samples/DX12/include/d3dx12.h
  31. 236 0
      samples/DX12/src/AppRenderer.cpp
  32. 163 0
      samples/DX12/src/BilinearUpscale.cpp
  33. 328 0
      samples/DX12/src/DeviceResources.cpp
  34. 189 0
      samples/DX12/src/NVScaler.cpp
  35. 148 0
      samples/DX12/src/NVSharpen.cpp
  36. 146 0
      samples/DX12/src/Sample.cpp
  37. 198 0
      samples/DX12/src/UIRenderer.cpp
  38. 62 0
      samples/DX12/src/bilinearUpscale.hlsl
  39. 9 0
      samples/DX12/src/dpi.manifest
  40. 109 0
      samples/VK/CMakeLists.txt
  41. 77 0
      samples/VK/include/AppRenderer.h
  42. 153 0
      samples/VK/include/DeviceResources.h
  43. 61 0
      samples/VK/include/NVScaler.h
  44. 55 0
      samples/VK/include/NVSharpen.h
  45. 75 0
      samples/VK/include/UIRenderer.h
  46. 67 0
      samples/VK/include/VKUtilities.h
  47. 254 0
      samples/VK/src/AppRenderer.cpp
  48. 757 0
      samples/VK/src/DeviceResources.cpp
  49. 242 0
      samples/VK/src/NVScaler.cpp
  50. 201 0
      samples/VK/src/NVSharpen.cpp
  51. 110 0
      samples/VK/src/Sample.cpp
  52. 214 0
      samples/VK/src/UIRenderer.cpp
  53. 289 40
      samples/common/Image.cpp
  54. 23 29
      samples/common/Image.h
  55. 14 10
      samples/common/Utilities.h
  56. BIN
      samples/third_party/DXC/bin/x64/dxc.exe
  57. 459 0
      samples/third_party/DXC/inc/d3d12shader.h
  58. 693 0
      samples/third_party/DXC/inc/dxcapi.h
  59. 71 0
      samples/third_party/DXC/license.txt
  60. 0 47
      samples/third_party/glfw/.appveyor.yml
  61. 0 5
      samples/third_party/glfw/.gitattributes
  62. 0 104
      samples/third_party/glfw/.gitignore
  63. 0 10
      samples/third_party/glfw/.mailmap
  64. 0 34
      samples/third_party/glfw/docs/CMakeLists.txt
  65. 0 10
      samples/third_party/glfw/docs/CODEOWNERS
  66. 0 391
      samples/third_party/glfw/docs/CONTRIBUTING.md
  67. 0 1828
      samples/third_party/glfw/docs/Doxyfile.in
  68. 0 71
      samples/third_party/glfw/docs/DoxygenLayout.xml
  69. 0 14
      samples/third_party/glfw/docs/SUPPORT.md
  70. 0 348
      samples/third_party/glfw/docs/build.dox
  71. 0 285
      samples/third_party/glfw/docs/compat.dox
  72. 0 365
      samples/third_party/glfw/docs/compile.dox
  73. 0 346
      samples/third_party/glfw/docs/context.dox
  74. 0 1
      samples/third_party/glfw/docs/extra.css
  75. 0 1
      samples/third_party/glfw/docs/extra.css.map
  76. 0 430
      samples/third_party/glfw/docs/extra.scss
  77. 0 7
      samples/third_party/glfw/docs/footer.html
  78. 0 34
      samples/third_party/glfw/docs/header.html
  79. 0 950
      samples/third_party/glfw/docs/input.dox
  80. 0 115
      samples/third_party/glfw/docs/internal.dox
  81. 0 454
      samples/third_party/glfw/docs/intro.dox
  82. 0 46
      samples/third_party/glfw/docs/main.dox
  83. 0 268
      samples/third_party/glfw/docs/monitor.dox
  84. 0 513
      samples/third_party/glfw/docs/moving.dox
  85. 0 863
      samples/third_party/glfw/docs/news.dox
  86. 0 365
      samples/third_party/glfw/docs/quick.dox
  87. 0 877
      samples/third_party/glfw/docs/spaces.svg
  88. 0 235
      samples/third_party/glfw/docs/vulkan.dox
  89. 0 1412
      samples/third_party/glfw/docs/window.dox
  90. 0 93
      samples/third_party/glfw/examples/CMakeLists.txt
  91. 0 679
      samples/third_party/glfw/examples/boing.c
  92. 0 360
      samples/third_party/glfw/examples/gears.c
  93. BIN
      samples/third_party/glfw/examples/glfw.icns
  94. BIN
      samples/third_party/glfw/examples/glfw.ico
  95. 0 3
      samples/third_party/glfw/examples/glfw.rc
  96. 0 512
      samples/third_party/glfw/examples/heightmap.c
  97. 0 177
      samples/third_party/glfw/examples/offscreen.c
  98. 0 1073
      samples/third_party/glfw/examples/particles.c
  99. 0 234
      samples/third_party/glfw/examples/sharing.c
  100. 0 0
      samples/third_party/glfw/examples/simple.c

+ 137 - 1
NIS/NIS_Config.h

@@ -25,6 +25,7 @@
 #include <cmath>
 #include <cstdint>
 
+#ifndef NIS_ALIGNED
 #if defined(_MSC_VER)
 #define NIS_ALIGNED(x) __declspec(align(x))
 #else
@@ -32,6 +33,7 @@
 #define NIS_ALIGNED(x) __attribute__ ((aligned(x)))
 #endif
 #endif
+#endif
 
 
 struct NIS_ALIGNED(256) NISConfig
@@ -127,7 +129,7 @@ struct NISOptimizer
     {
         switch (gpuArch) {
         case NISGPUArchitecture::NVIDIA_Generic:
-            return 256;
+            return 128;
         case NISGPUArchitecture::AMD_Generic:
             return 256;
         case NISGPUArchitecture::Intel_Generic:
@@ -388,4 +390,138 @@ namespace {
         {0.0005, -0.0068, -0.5791, 1.1958, -0.6147, 0.0049, 0, 0},
         {0, -0.0029, -0.5903, 1.1987, -0.6084, 0.0029, 0, 0}
     };
+
+    constexpr uint16_t coef_scale_fp16[kPhaseCount][kFilterSize] = {
+       { 0, 0, 15360, 0, 0, 0, 0, 0 },
+       { 6640, 41601, 15360, 8898, 39671, 0, 0, 0 },
+       { 7796, 42592, 15357, 9955, 40695, 0, 0, 0 },
+       { 8321, 43167, 15351, 10576, 41286, 4121, 0, 0 },
+       { 8702, 43537, 15346, 11058, 41797, 4121, 0, 0 },
+       { 9029, 43871, 15339, 11408, 42146, 4121, 0, 0 },
+       { 9280, 44112, 15328, 11672, 42402, 5145, 0, 0 },
+       { 9411, 44256, 15316, 11944, 42690, 5669, 0, 0 },
+       { 9535, 44401, 15304, 12216, 42979, 6169, 0, 0 },
+       { 9667, 44528, 15288, 12396, 43137, 6378, 0, 0 },
+       { 9758, 44656, 15273, 12540, 43282, 6640, 0, 0 },
+       { 9857, 44768, 15255, 12688, 43423, 6903, 0, 0 },
+       { 9922, 44872, 15235, 12844, 43583, 7297, 0, 0 },
+       { 10014, 44959, 15213, 13000, 43744, 7429, 0, 0 },
+       { 10079, 45048, 15190, 13156, 43888, 7691, 0, 0 },
+       { 10112, 45092, 15167, 13316, 44040, 7796, 0, 0 },
+       { 10178, 45124, 15140, 13398, 44120, 8058, 0, 0 },
+       { 10211, 45152, 15112, 13482, 44201, 8256, 0, 0 },
+       { 10211, 45180, 15085, 13566, 44279, 8387, 0, 0 },
+       { 10242, 45200, 15054, 13652, 44360, 8518, 0, 0 },
+       { 10242, 45216, 15023, 13738, 44440, 8636, 0, 0 },
+       { 10242, 45228, 14990, 13826, 44520, 8767, 0, 0 },
+       { 10242, 45236, 14955, 13912, 44592, 8964, 0, 0 },
+       { 10211, 45244, 14921, 14002, 44673, 9082, 0, 0 },
+       { 10178, 45244, 14885, 14090, 44745, 9213, 0, 0 },
+       { 10145, 45244, 14849, 14178, 44817, 9280, 0, 0 },
+       { 10112, 45236, 14810, 14266, 44887, 9378, 0, 0 },
+       { 10079, 45228, 14770, 14346, 44953, 9437, 0, 0 },
+       { 10014, 45216, 14731, 14390, 45017, 9503, 0, 0 },
+       { 9981, 45204, 14689, 14434, 45064, 9601, 0, 0 },
+       { 9922, 45188, 14649, 14478, 45096, 9667, 0, 0 },
+       { 9857, 45168, 14607, 14521, 45120, 9726, 0, 0 },
+       { 9791, 45144, 14564, 14564, 45144, 9791, 0, 0 },
+       { 9726, 45120, 14521, 14607, 45168, 9857, 0, 0 },
+       { 9667, 45096, 14478, 14649, 45188, 9922, 0, 0 },
+       { 9601, 45064, 14434, 14689, 45204, 9981, 0, 0 },
+       { 9503, 45017, 14390, 14731, 45216, 10014, 0, 0 },
+       { 9437, 44953, 14346, 14770, 45228, 10079, 0, 0 },
+       { 9378, 44887, 14266, 14810, 45236, 10112, 0, 0 },
+       { 9280, 44817, 14178, 14849, 45244, 10145, 0, 0 },
+       { 9213, 44745, 14090, 14885, 45244, 10178, 0, 0 },
+       { 9082, 44673, 14002, 14921, 45244, 10211, 0, 0 },
+       { 8964, 44592, 13912, 14955, 45236, 10242, 0, 0 },
+       { 8767, 44520, 13826, 14990, 45228, 10242, 0, 0 },
+       { 8636, 44440, 13738, 15023, 45216, 10242, 0, 0 },
+       { 8518, 44360, 13652, 15054, 45200, 10242, 0, 0 },
+       { 8387, 44279, 13566, 15085, 45180, 10211, 0, 0 },
+       { 8256, 44201, 13482, 15112, 45152, 10211, 0, 0 },
+       { 8058, 44120, 13398, 15140, 45124, 10178, 0, 0 },
+       { 7796, 44040, 13316, 15167, 45092, 10112, 0, 0 },
+       { 7691, 43888, 13156, 15190, 45048, 10079, 0, 0 },
+       { 7429, 43744, 13000, 15213, 44959, 10014, 0, 0 },
+       { 7297, 43583, 12844, 15235, 44872, 9922, 0, 0 },
+       { 6903, 43423, 12688, 15255, 44768, 9857, 0, 0 },
+       { 6640, 43282, 12540, 15273, 44656, 9758, 0, 0 },
+       { 6378, 43137, 12396, 15288, 44528, 9667, 0, 0 },
+       { 6169, 42979, 12216, 15304, 44401, 9535, 0, 0 },
+       { 5669, 42690, 11944, 15316, 44256, 9411, 0, 0 },
+       { 5145, 42402, 11672, 15328, 44112, 9280, 0, 0 },
+       { 4121, 42146, 11408, 15339, 43871, 9029, 0, 0 },
+       { 4121, 41797, 11058, 15346, 43537, 8702, 0, 0 },
+       { 4121, 41286, 10576, 15351, 43167, 8321, 0, 0 },
+       { 0, 40695, 9955, 15357, 42592, 7796, 0, 0 },
+       { 0, 39671, 8898, 15360, 41601, 6640, 0, 0 },
+    };
+
+    constexpr uint16_t coef_usm_fp16[kPhaseCount][kFilterSize] = {
+        { 0, 47309, 15565, 47309, 0, 0, 0, 0 },
+        { 6640, 47326, 15563, 47289, 39408, 0, 0, 0 },
+        { 7429, 47339, 15560, 47266, 40695, 4121, 0, 0 },
+        { 8058, 47349, 15554, 47239, 41286, 0, 0, 0 },
+        { 8387, 47357, 15545, 47209, 41915, 0, 0, 0 },
+        { 8636, 47363, 15534, 47176, 42238, 4121, 0, 0 },
+        { 8767, 47364, 15522, 47141, 42657, 4121, 0, 0 },
+        { 9029, 47367, 15509, 47105, 43023, 4121, 0, 0 },
+        { 9213, 47363, 15490, 47018, 43249, 4121, 0, 0 },
+        { 9280, 47357, 15472, 46928, 43472, 5145, 0, 0 },
+        { 9345, 47347, 15450, 46836, 43727, 5145, 0, 0 },
+        { 9378, 47337, 15427, 46736, 43999, 5669, 0, 0 },
+        { 9437, 47323, 15401, 46630, 44152, 5669, 0, 0 },
+        { 9470, 47310, 15376, 46520, 44312, 6169, 0, 0 },
+        { 9503, 47294, 15338, 46402, 44479, 6378, 0, 0 },
+        { 9503, 47272, 15274, 46280, 44648, 6640, 0, 0 },
+        { 9503, 47253, 15215, 46158, 44817, 6903, 0, 0 },
+        { 9503, 47231, 15150, 45972, 45017, 7165, 0, 0 },
+        { 9535, 47206, 15082, 45708, 45132, 7297, 0, 0 },
+        { 9503, 47180, 15012, 45432, 45232, 7429, 0, 0 },
+        { 9470, 47153, 14939, 45152, 45332, 7560, 0, 0 },
+        { 9470, 47126, 14868, 44681, 45444, 7691, 0, 0 },
+        { 9437, 47090, 14793, 44071, 45560, 7796, 0, 0 },
+        { 9411, 47030, 14714, 42847, 45668, 7927, 0, 0 },
+        { 9411, 46968, 14635, 8387, 45788, 8058, 0, 0 },
+        { 9345, 46902, 14552, 10786, 45908, 8256, 0, 0 },
+        { 9313, 46846, 14478, 11647, 46036, 8321, 0, 0 },
+        { 9247, 46776, 14394, 12292, 46120, 8453, 0, 0 },
+        { 9247, 46714, 14288, 12620, 46184, 8518, 0, 0 },
+        { 9147, 46648, 14130, 12936, 46248, 8570, 0, 0 },
+        { 9029, 46576, 13956, 13268, 46312, 8702, 0, 0 },
+        { 8964, 46512, 13792, 13456, 46378, 8767, 0, 0 },
+        { 8898, 46446, 13624, 13624, 46446, 8898, 0, 0 },
+        { 8767, 46378, 13456, 13792, 46512, 8964, 0, 0 },
+        { 8702, 46312, 13268, 13956, 46576, 9029, 0, 0 },
+        { 8570, 46248, 12936, 14130, 46648, 9147, 0, 0 },
+        { 8518, 46184, 12620, 14288, 46714, 9247, 0, 0 },
+        { 8453, 46120, 12292, 14394, 46776, 9247, 0, 0 },
+        { 8321, 46036, 11647, 14478, 46846, 9313, 0, 0 },
+        { 8256, 45908, 10786, 14552, 46902, 9345, 0, 0 },
+        { 8058, 45788, 8387, 14635, 46968, 9411, 0, 0 },
+        { 7927, 45668, 42847, 14714, 47030, 9411, 0, 0 },
+        { 7796, 45560, 44071, 14793, 47090, 9437, 0, 0 },
+        { 7691, 45444, 44681, 14868, 47126, 9470, 0, 0 },
+        { 7560, 45332, 45152, 14939, 47153, 9470, 0, 0 },
+        { 7429, 45232, 45432, 15012, 47180, 9503, 0, 0 },
+        { 7297, 45132, 45708, 15082, 47206, 9535, 0, 0 },
+        { 7165, 45017, 45972, 15150, 47231, 9503, 0, 0 },
+        { 6903, 44817, 46158, 15215, 47253, 9503, 0, 0 },
+        { 6640, 44648, 46280, 15274, 47272, 9503, 0, 0 },
+        { 6378, 44479, 46402, 15338, 47294, 9503, 0, 0 },
+        { 6169, 44312, 46520, 15376, 47310, 9470, 0, 0 },
+        { 5669, 44152, 46630, 15401, 47323, 9437, 0, 0 },
+        { 5669, 43999, 46736, 15427, 47337, 9378, 0, 0 },
+        { 5145, 43727, 46836, 15450, 47347, 9345, 0, 0 },
+        { 5145, 43472, 46928, 15472, 47357, 9280, 0, 0 },
+        { 4121, 43249, 47018, 15490, 47363, 9213, 0, 0 },
+        { 4121, 43023, 47105, 15509, 47367, 9029, 0, 0 },
+        { 4121, 42657, 47141, 15522, 47364, 8767, 0, 0 },
+        { 4121, 42238, 47176, 15534, 47363, 8636, 0, 0 },
+        { 0, 41915, 47209, 15545, 47357, 8387, 0, 0 },
+        { 0, 41286, 47239, 15554, 47349, 8058, 0, 0 },
+        { 4121, 40695, 47266, 15560, 47339, 7429, 0, 0 },
+        { 0, 39408, 47289, 15563, 47326, 6640, 0, 0 },
+    };
 }

+ 93 - 0
NIS/NIS_Main.glsl

@@ -0,0 +1,93 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+#extension GL_GOOGLE_include_directive : enable
+#extension GL_EXT_shader_16bit_storage : require
+#extension GL_EXT_shader_explicit_arithmetic_types : require
+
+#define NIS_GLSL 1
+
+#ifndef NIS_SCALER
+#define NIS_SCALER 1
+#endif
+
+layout(set=0,binding=0) uniform const_buffer
+{
+    float kDetectRatio;
+    float kDetectThres;
+    float kMinContrastRatio;
+    float kRatioNorm;
+
+    float kContrastBoost;
+    float kEps;
+    float kSharpStartY;
+    float kSharpScaleY;
+
+    float kSharpStrengthMin;
+    float kSharpStrengthScale;
+    float kSharpLimitMin;
+    float kSharpLimitScale;
+
+    float kScaleX;
+    float kScaleY;
+
+    float kDstNormX;
+    float kDstNormY;
+    float kSrcNormX;
+    float kSrcNormY;
+
+    uint kInputViewportOriginX;
+    uint kInputViewportOriginY;
+    uint kInputViewportWidth;
+    uint kInputViewportHeight;
+
+    uint kOutputViewportOriginX;
+    uint kOutputViewportOriginY;
+    uint kOutputViewportWidth;
+    uint kOutputViewportHeight;
+
+    float reserved0;
+    float reserved1;
+};
+
+layout(set=0,binding=1) uniform sampler samplerLinearClamp;
+layout(set=0,binding=2) uniform texture2D in_texture;
+layout(set=0,binding=3,rgba8_snorm) uniform image2D out_texture;
+
+#if NIS_SCALER
+layout(set=0,binding=4) uniform texture2D coef_scaler;
+layout(set=0,binding=5) uniform texture2D coef_usm;
+#endif
+
+#include "NIS_Scaler.h"
+
+layout(local_size_x=NIS_THREAD_GROUP_SIZE) in;
+void main()
+{
+    #if NIS_SCALER
+        NVScaler(gl_WorkGroupID.xy, gl_LocalInvocationID.x);
+    #else
+        NVSharpen(gl_WorkGroupID.xy, gl_LocalInvocationID.x);
+    #endif
+}

+ 7 - 9
NIS/NIS_Main.hlsl

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -19,6 +19,8 @@
 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+#define NIS_HLSL 1
+
 #ifndef NIS_SCALER
 #define NIS_SCALER 1
 #endif
@@ -30,13 +32,9 @@
 #if NIS_DXC
 #define NIS_PUSH_CONSTANT    [[vk::push_constant]]
 #define NIS_BINDING(bindingIndex) [[vk::binding(bindingIndex, 0)]]
-#define NIS_CONSTANT_BUFFER(structName, variableName, bufferRegister) \
-        ConstantBuffer<structName> variableName : register(bufferRegister);
 #else
 #define NIS_PUSH_CONSTANT
 #define NIS_BINDING(bindingIndex)
-#define NIS_CONSTANT_BUFFER(structName, variableName, bufferRegister) \
-        cbuffer cbufferType : register(bufferRegister) { structName variableName; };
 #endif
 
 
@@ -64,7 +62,7 @@ NIS_BINDING(0) cbuffer cb : register(b0)
     float kDstNormY;
     float kSrcNormX;
     float kSrcNormY;
-    
+
     uint kInputViewportOriginX;
     uint kInputViewportOriginY;
     uint kInputViewportWidth;

ファイルの差分が大きいため隠しています
+ 435 - 432
NIS/NIS_Scaler.h


+ 39 - 11
README.md

@@ -80,6 +80,12 @@ specified using non-integer data types such as DXGI_FORMAT_R8G8B8A8_UNORM.
 
 The scaler coefficients and USM coefficients format should be specified using float4 type such as
 DXGI_FORMAT_R32G32B32A32_FLOAT or DXGI_FORMAT_R16G16B16A16_FLOAT.
+The coefficients are included in NIS_Config.h file:
+
+fp32 format: coef_scaler, coef_USM
+
+fp16 format: coef_scaler_fp16, coef_USM_fp16 
+
 
 ### Resource States, Buffers, and Sampler:
 
@@ -96,13 +102,14 @@ the correct state.
 
 ## Adding NVIDIA Image Scaling SDK to a Project
 
-Include NIS_Scaler.h directly in your application or alternative use the provided NIS_Main.hlsl shader file.
+Include NIS_Scaler.h directly in your application or alternative use the provided NIS_Main.hlsl or NIS_Main.glsl shader files.
 Use NIS_Config.h to get the ideal shader dispatch values for your platform, to configure the algorithm constant
-values (NVScalerUpdateConfig, and NVSharpenUpdateConfig), and to access the algorithm coefficients (coef_scale and coef_USM).
+values (NVScalerUpdateConfig, and NVSharpenUpdateConfig), and to access the algorithm coefficients (coef_scale, coef_USM, coef_scale_fp16, coef_USM_fp16).
 
 - Device\
   NIS_Scaler.h    : HLSL shader file\
-  NIS_Main.hlsl   : Main HLSL shader example (can be replaced by your own)
+  NIS_Main.hlsl   : Main HLSL shader example (can be replaced by your own) \
+  NIS_Main.glsl   : Main GLSL shader example (can ge replaced by your own)
 
 - Host Configuration\
   NIS_Config.h    : Configuration structure
@@ -116,7 +123,9 @@ values (NVScalerUpdateConfig, and NVSharpenUpdateConfig), and to access the algo
 **NIS_BLOCK_HEIGHT**: pixels per block height. Use GetOptimalBlockHeight query for your platform\
 **NIS_THREAD_GROUP_SIZE**: number of threads per group. Use GetOptimalThreadGroupSize query for your platform\
 **NIS_USE_HALF_PRECISION**: default(**0**) disabled, (1) enable half pression computation\
-**NIS_HLSL_6_2**: default (**0**) HLSL v5, (1) HLSL v6.2\
+**NIS_HLSL**: default (**1**) enabled, (0) disabled\
+**NIS_HLSL_6_2**: default (**0**) HLSL v5, (1) HLSL v6.2 forces NIS_HLSL=1\
+**NIS_GLSL**: default (**0**) disabled, (1) enabled\
 **NIS_VIEWPORT_SUPPORT**: default(**0**) disabled, (1) enable input/output viewport support\
 
 
@@ -129,6 +138,10 @@ values (NVScalerUpdateConfig, and NVSharpenUpdateConfig), and to access the algo
 [**NIS_BLOCK_WIDTH**, **NIS_BLOCK_HEIGHT**, **NIS_THREAD_GROUP_SIZE**] = [32, 32, 256]
 
 
+*Defines for HLSL with DXC bindings:*
+
+**NIS_DXC**: (0) disabled, (1) enable HLSL DXC Vulkan support
+
 ## Optimal shader settings
 
 To get optimal performance of NvScaler and NvSharpen for current and future hardware, it is recommended that the following API is used to obtain the values for NIS_BLOCK_WIDTH, NIS_BLOCK_HEIGHT, and NIS_THREAD_GROUP_SIZE.
@@ -174,6 +187,7 @@ enum class NISHDRMode : uint32_t
 
 
 ## Integration of NVScaler
+The integration instructions in this section can be applied with minimal changes to your own DX11, DX12, or Vulkan application, using HLSL or GLSL.
 
 ### Compile the NIS_Main.hlsl shader
 
@@ -213,12 +227,12 @@ createConstBuffer(&config, &csBuffer);
 ### Create SRV textures for the scaler and USM phase coefficients
 
 ```
-const int rowPitch = kFilterSize * 4;
-const int imageSize = rowPitch * kPhaseCount;
-
-createTexture2D(kFilterSize / 4, kPhaseCount, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D11_USAGE_DEFAULT, coef_scaler, rowPitch, imageSize, &scalerTex);
+const int rowPitch = kFilterSize * sizeof(float);  // use for fp32: float, fp16: uint16_t
+const int coeffSize = rowPitch * kPhaseCount;
 
-createTexture2D(kFilterSize / 4, kPhaseCount, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D11_USAGE_DEFAULT, coef_usm, rowPitch, imageSize, &usmTex);
+// Since we are using RGBA format the texture width = kFilterSize / 4
+createTexture2D(kFilterSize / 4, kPhaseCount, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D11_USAGE_DEFAULT, coef_scaler, rowPitch, coeffSize, &scalerTex);
+createTexture2D(kFilterSize / 4, kPhaseCount, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D11_USAGE_DEFAULT, coef_usm, rowPitch, coeffSize, &usmTex);
 
 createSRV(scalerTex.Get(), DXGI_FORMAT_R32G32B32A32_FLOAT, &scalerSRV);
 createSRV(usmTex.Get(), DXGI_FORMAT_R32G32B32A32_FLOAT, &usmSRV);
@@ -281,7 +295,7 @@ If your application requires upscaling and sharpening do not use NVSharpen use N
 
 ### Compile the NIS_Main.hlsl shader
 
-NIS_SCALER should be set to 0 and the optimizer isUscaling argument should be set as false.
+NIS_SCALER should be set to 0 and the optimizer isUscaling argument should be set to false.
 
 ```
 bool isUpscaling = false;
@@ -369,8 +383,13 @@ context->Dispatch(UINT(std::ceil(outputWidth / float(blockWidth))),
 - Windows 10 SDK : https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk
 - CMake 3.16 : https://cmake.org/download/
 
+for building the Vulkan sample:
+- Vulkan SDK 1.2.189.2 : https://vulkan.lunarg.com/  
+
 ### Build
 
+For the DirectX11 and DirectX12 samples use the following:
+
 ```
 $> cd samples
 $> mkdir build
@@ -378,4 +397,13 @@ $> cd build
 $> cmake ..
 ```
 
-Open the solution with Visual Studio 2019. Right-click the sample project and select "Set as Startup Project" before building the project
+for building the Vulkan sample:
+
+```
+$> cd samples
+$> mkdir build
+$> cd build
+$> cmake .. -DNIS_VK_SAMPLE=ON
+```
+
+Open the solution with Visual Studio 2019. Right-click the sample project and select "Set as Startup Project" before building the project. For Linux, only the VK sample will be generated.

BIN
docs/NIS_SDK_Programming_Guide.pdf


+ 28 - 1
samples/CMakeLists.txt

@@ -1,8 +1,35 @@
 cmake_minimum_required(VERSION 3.12)
 project(NIS_SDK)
 
+option (NIS_VK_SAMPLE "Vulkan sample" OFF)
+
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS ON)
+set(CMAKE_SUPPRESS_REGENERATION ON)
+
+set(NIS_PATH "${CMAKE_SOURCE_DIR}/../NIS")
+set(THIRD_PARTY "${CMAKE_SOURCE_DIR}/third_party")
+set(IMGUI_PATH    "${THIRD_PARTY}/imgui/")
+set(IMGUI_INCLUDE "${IMGUI_PATH}" "${IMGUI_PATH}/backends/")
+set(SAMPLES_PATH "${CMAKE_SOURCE_DIR}")
+set(COMMON_PATH "${CMAKE_SOURCE_DIR}/common")
+
+if (WIN32)
+    add_subdirectory (DX11)
+    add_subdirectory (DX12)
+else(WIN32)
+    set(NIS_VK_SAMPLE ON CACHE BOOL "Vulkan sample" FORCE)
+endif(WIN32)
+
+if(NIS_VK_SAMPLE)
+    find_package(Vulkan REQUIRED)
+
+    # GLFW
+    set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
+    set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
+    set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
+    add_subdirectory("${THIRD_PARTY}/glfw")
 
-add_subdirectory (DX11)
+    add_subdirectory (VK)
+endif()

+ 10 - 3
samples/DX11/CMakeLists.txt

@@ -15,6 +15,13 @@ set(IMGUI_SRC     "${IMGUI_PATH}/backends/imgui_impl_dx11.cpp"
                   "${IMGUI_PATH}/imgui_widgets.cpp"
 )
 
+set(TINYEXR_PATH    "${CMAKE_SOURCE_DIR}/third_party/tinyexr/")
+set(TINYEXR_INCLUDE "${TINYEXR_PATH}" "${TINYEXR_PATH}/deps/miniz")
+set(TINYEXR_SRC     "${TINYEXR_PATH}/deps/miniz/miniz.c")
+
+set(STB_PATH     "${CMAKE_SOURCE_DIR}/third_party/stb/")
+set(STB_INCLUDE  "${STB_PATH}")
+
 set(NIS_PATH "${CMAKE_SOURCE_DIR}/../NIS")
 
 set(SAMPLES_PATH "${CMAKE_SOURCE_DIR}")
@@ -53,10 +60,10 @@ set(DX_SAMPLE_MEDIA "${SAMPLES_PATH}/media/images/1080.png"
 
 set_source_files_properties(${DX_SAMPLE_SHADERS} PROPERTIES VS_COPY_TO_OUT_DIR TRUE)
 
-source_group("ui" FILES ${IMGUI_SRC})
+source_group("external" FILES ${IMGUI_SRC} ${TINYEXR_SRC})
 source_group("shaders" FILES ${DX_SAMPLE_SHADERS})
-add_executable(${PROJECT_NAME} ${DX_SAMPLE_SRC} ${IMGUI_SRC} ${DX_SAMPLE_HEADERS} ${DX_SAMPLE_SHADERS})
-target_include_directories (${PROJECT_NAME} PUBLIC include ${IMGUI_INCLUDE} ${NIS_PATH} ${SAMPLES_PATH}/common)
+add_executable(${PROJECT_NAME} ${DX_SAMPLE_SRC} ${IMGUI_SRC} ${TINYEXR_SRC} ${DX_SAMPLE_HEADERS} ${DX_SAMPLE_SHADERS})
+target_include_directories (${PROJECT_NAME} PUBLIC include ${IMGUI_INCLUDE} ${TINYEXR_INCLUDE} ${STB_INCLUDE} ${NIS_PATH} ${SAMPLES_PATH}/common)
 
 add_custom_command(
   TARGET ${PROJECT_NAME} POST_BUILD

+ 6 - 6
samples/DX11/include/AppRenderer.h

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -39,11 +39,12 @@ using namespace Microsoft::WRL;
 class AppRenderer
 {
 public:
-    AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::string& shadersFolder);
+    AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::vector<std::string>& shaderPaths);
     bool update();
     void render();
     uint32_t width() { return m_outputWidth; }
     uint32_t height() { return m_outputHeight; }
+    void saveOutput(const std::string& filename);
 private:
     UIData& m_ui;
     DeviceResources& m_deviceResources;
@@ -59,7 +60,6 @@ private:
     ComPtr<ID3D11ShaderResourceView>	m_inputSRV;
     ComPtr<ID3D11UnorderedAccessView>	m_outputUAV;
 
-    Image								m_image;
     std::filesystem::path				m_currentFilePath;
     float							    m_currentScale = 100.f;
     float    							m_currentSharpness = 0.f;

+ 4 - 4
samples/DX11/include/BilinearUpscale.h

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR

+ 6 - 6
samples/DX11/include/DXUtilities.h

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -104,7 +104,7 @@ namespace DX
     }
 
     struct IncludeHeader : ID3DInclude {
-        IncludeHeader(const std::vector<std::string>& includePath) 
+        IncludeHeader(const std::vector<std::string>& includePath)
             : m_includePath(includePath)
             , m_idx(0) {}
 
@@ -159,7 +159,7 @@ namespace DX
             return m_defines.get();
         }
     private:
-        std::vector<std::pair<std::string, std::string>> m_definesVector;        
+        std::vector<std::pair<std::string, std::string>> m_definesVector;
         std::unique_ptr<D3D_SHADER_MACRO[]> m_defines;
     };
 }

+ 13 - 13
samples/DX11/include/DeviceResources.h

@@ -1,34 +1,34 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- 
+
 #pragma once
- 
+
 #include <dxgi1_4.h>
 #include <d3d11.h>
 #include <wrl.h>
 #include <iostream>
 #include <vector>
- 
+
 using namespace Microsoft::WRL;
- 
+
 struct Adapter
 {
     std::string Description;
@@ -40,7 +40,7 @@ struct Adapter
     size_t DedicatedSystemMemory;
     size_t SharedSystemMemory;
 };
- 
+
 class DeviceResources
 {
 public:
@@ -51,8 +51,8 @@ public:
     void present(uint32_t SyncInterval, uint32_t Flags) { m_swapChain->Present(SyncInterval, Flags); }
     ID3D11Device* device() { return m_d3dDevice.Get(); }
     ID3D11DeviceContext* context() { return m_d3dContext.Get(); }
-    bool initialized() { return m_initialized; }
- 
+    bool isInitialized() { return m_initialized; }
+
     IDXGISwapChain* swapChain() { return m_swapChain.Get();  }
     ID3D11Texture2D* renderTarget() { return m_d3dRenderTarget.Get(); }
     void DeviceResources::setRenderTarget() {
@@ -67,8 +67,8 @@ public:
     void createLinearClampSampler(ID3D11SamplerState** ppSampleState);
     void createConstBuffer(void* initialData, uint32_t size, ID3D11Buffer** ppBuffer);
     void updateConstBuffer(void* data, uint32_t size, ID3D11Buffer* ppBuffer);
-    void getTextureData(ID3D11Texture2D* texture, uint8_t* data);
- 
+    void getTextureData(ID3D11Texture2D* texture, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& rowPitch);
+
     uint32_t width() { return m_width; }
     uint32_t height() { return m_height; }
     Adapter getAdapter() { return m_adapter; }

+ 5 - 5
samples/DX11/include/NVScaler.h

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -33,7 +33,7 @@
 
 class NVScaler {
 public:
-    NVScaler(DeviceResources& deviceResources, const std::string& shaderFolder);
+    NVScaler(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths);
 
     void update(float sharpness, uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight);
 

+ 5 - 5
samples/DX11/include/NVSharpen.h

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -33,7 +33,7 @@
 
 class NVSharpen {
 public:
-    NVSharpen(DeviceResources& deviceResources, const std::string& shaderFolder);
+    NVSharpen(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths);
 
     void update(float sharpness, uint32_t inputWidth, uint32_t inputHeight);
     void dispatch(ID3D11ShaderResourceView* const* input, ID3D11UnorderedAccessView* const* output);

+ 10 - 10
samples/DX11/include/UIRenderer.h

@@ -1,26 +1,26 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- 
+
 #pragma once
- 
+
 #include <iomanip>
 #include <iostream>
 #include <filesystem>
@@ -32,7 +32,7 @@
 #include <imgui_impl_dx11.h>
 #include "DeviceResources.h"
 #include "Utilities.h"
- 
+
 enum class OutputSizeMode : uint32_t
 {
 	VARIABLE,
@@ -40,8 +40,8 @@ enum class OutputSizeMode : uint32_t
 	P1440,
 	P2160
 };
- 
- 
+
+
 struct UIData
 {
 	std::vector<std::filesystem::path> Files;
@@ -61,7 +61,7 @@ struct UIData
 	bool ShowSettings = true;
 	int32_t UnitMicroseconds = true;
 };
- 
+
 class UIRenderer
 {
 public:

+ 39 - 14
samples/DX11/src/AppRenderer.cpp

@@ -18,21 +18,21 @@
 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- 
+
 #pragma once
- 
+
 #include "AppRenderer.h"
- 
+
 using namespace Microsoft::WRL;
- 
-AppRenderer::AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::string& shadersFolder)
+
+AppRenderer::AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::vector<std::string>& shaderPaths)
     : m_ui(ui)
     , m_deviceResources(deviceResources)
-    , m_NVSharpen(deviceResources, shadersFolder)
-    , m_NVScaler(deviceResources, shadersFolder)
+    , m_NVSharpen(deviceResources, shaderPaths)
+    , m_NVScaler(deviceResources, shaderPaths)
     , m_upscale(deviceResources)
 {}
- 
+
 bool AppRenderer::update()
 {
     bool updateWindowSize = m_currentFilePath != m_ui.FilePath || m_currentScale != m_ui.Scale;
@@ -41,10 +41,10 @@ bool AppRenderer::update()
     {
         if (m_currentFilePath != m_ui.FilePath)
         {
-            m_image.load(m_ui.FilePath);
-            m_inputWidth = m_image.width();
-            m_inputHeight = m_image.height();
-            m_deviceResources.createTexture2D(m_inputWidth, m_inputHeight, DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_USAGE_DEFAULT, m_image.data(), m_image.rowPitch(), m_image.imageSize(), &m_input);
+            std::vector<uint8_t> image;
+            uint32_t rowPitch;
+            img::load(m_ui.FilePath.string(), image, m_inputWidth, m_inputHeight, rowPitch, img::Fmt::R8G8B8A8);
+            m_deviceResources.createTexture2D(m_inputWidth, m_inputHeight, DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_USAGE_DEFAULT, image.data(), rowPitch, rowPitch * m_inputHeight, &m_input);
             m_deviceResources.createSRV(m_input.Get(), DXGI_FORMAT_R8G8B8A8_UNORM, &m_inputSRV);
             m_currentFilePath = m_ui.FilePath;
         }
@@ -78,7 +78,32 @@ bool AppRenderer::update()
     }
     return updateWindowSize;
 }
- 
+
+void AppRenderer::saveOutput(const std::string& filename)
+{
+    D3D11_TEXTURE2D_DESC desc;
+    m_output->GetDesc(&desc);
+    img::Fmt format = img::Fmt::R8G8B8A8;
+
+    switch (desc.Format)
+    {
+    case DXGI_FORMAT_R8G8B8A8_UNORM:
+        format = img::Fmt::R8G8B8A8;
+        break;
+    case DXGI_FORMAT_R32G32B32A32_FLOAT:
+        format = img::Fmt::R32G32B32A32;
+        break;
+    case DXGI_FORMAT_R16G16B16A16_FLOAT:
+        format = img::Fmt::R16G16B16A16;
+        break;
+    }
+    std::vector<uint8_t> data;
+    uint32_t width, height, rowPitch = 0;
+    constexpr uint32_t channels = 4;
+    m_deviceResources.getTextureData(m_output.Get(), data, width, height, rowPitch);
+    img::save(filename, data.data(), width, height, channels, rowPitch, format);
+}
+
 void AppRenderer::render()
 {
     auto context = m_deviceResources.context();
@@ -112,7 +137,7 @@ void AppRenderer::render()
             m_NVScaler.dispatch(m_inputSRV.GetAddressOf(), m_outputUAV.GetAddressOf());
         }
     }
- 
+
     context->End(m_timeStampEnd.Get());
     context->End(m_timeStampDis.Get());
     D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disData;

+ 35 - 32
samples/DX11/src/DeviceResources.cpp

@@ -18,11 +18,11 @@
 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- 
+
 #include "DeviceResources.h"
 #include "DXUtilities.h"
- 
- 
+
+
 void DeviceResources::create(HWND hWnd, uint32_t adapterIdx)
 {
     DXGI_SWAP_CHAIN_DESC desc;
@@ -40,7 +40,7 @@ void DeviceResources::create(HWND hWnd, uint32_t adapterIdx)
     desc.SampleDesc.Quality = 0;
     desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
     desc.Windowed = TRUE;
- 
+
     ComPtr<IDXGIFactory> pFactory;
     CreateDXGIFactory(__uuidof(IDXGIFactory) ,(void**)&pFactory);
     ComPtr<IDXGIAdapter> pAdapter;
@@ -57,37 +57,35 @@ void DeviceResources::create(HWND hWnd, uint32_t adapterIdx)
         m_adapter.DedicatedVideoMemory = desc.DedicatedVideoMemory;
         m_adapter.SharedSystemMemory = desc.SharedSystemMemory;
     }
-    else 
+    else
     {
         throw std::runtime_error("Adapter not found");
     }
- 
+
     uint32_t createDeviceFlags = 0;
+
+#ifdef DX11_ENABLE_DEBUG_LAYER
     createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
- 
+#endif
+
     D3D_FEATURE_LEVEL featureLevel;
     const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0 };
- 
+
     HRESULT hr = D3D11CreateDeviceAndSwapChain(pAdapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
             createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &desc,
             &m_swapChain, &m_d3dDevice, &featureLevel, &m_d3dContext);
     DX::ThrowIfFailed(hr);
- 
+
     initRenderTarget();
     m_initialized = true;
 }
- 
+
 void DeviceResources::initRenderTarget()
 {
-    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
-    ZeroMemory(&uavDesc, sizeof(D3D11_UNORDERED_ACCESS_VIEW_DESC));
-    uavDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
-    uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
- 
     DX::ThrowIfFailed(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &m_d3dRenderTarget));
     DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(m_d3dRenderTarget.Get(), NULL, &m_d3dRenderTargetView));
 }
- 
+
 void DeviceResources::resizeRenderTarget(uint32_t Width, uint32_t Height, DXGI_FORMAT format)
 {
     m_width = Width;
@@ -98,12 +96,12 @@ void DeviceResources::resizeRenderTarget(uint32_t Width, uint32_t Height, DXGI_F
     DX::ThrowIfFailed(m_swapChain->ResizeBuffers(0, Width, Height, format, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH));
     initRenderTarget();
 }
- 
+
 void DeviceResources::clearRenderTargetView(const float color[4])
 {
     m_d3dContext->ClearRenderTargetView(m_d3dRenderTargetView.Get(), color);
 }
- 
+
 void DeviceResources::createUAV(ID3D11Resource* pResource, DXGI_FORMAT format, ID3D11UnorderedAccessView** ppUAView)
 {
     D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
@@ -112,7 +110,7 @@ void DeviceResources::createUAV(ID3D11Resource* pResource, DXGI_FORMAT format, I
     uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
     DX::ThrowIfFailed(m_d3dDevice->CreateUnorderedAccessView(pResource, &uavDesc, ppUAView));
 }
- 
+
 void DeviceResources::createSRV(ID3D11Resource* pResource, DXGI_FORMAT format, ID3D11ShaderResourceView** ppSRView)
 {
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
@@ -123,7 +121,7 @@ void DeviceResources::createSRV(ID3D11Resource* pResource, DXGI_FORMAT format, I
     srvDesc.Texture2D.MipLevels = 1;
     DX::ThrowIfFailed(m_d3dDevice->CreateShaderResourceView(pResource, &srvDesc, ppSRView));
 }
- 
+
 void DeviceResources::createLinearClampSampler(ID3D11SamplerState** ppSampleState)
 {
     D3D11_SAMPLER_DESC samplerDesc;
@@ -134,10 +132,11 @@ void DeviceResources::createLinearClampSampler(ID3D11SamplerState** ppSampleStat
     samplerDesc.MipLODBias = 0.0f;
     samplerDesc.MaxAnisotropy = 1;
     samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+    samplerDesc.MinLOD = -D3D11_FLOAT32_MAX;
     samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
     DX::ThrowIfFailed(m_d3dDevice->CreateSamplerState(&samplerDesc, ppSampleState));
 }
- 
+
 void DeviceResources::createTexture2D(int w, int h, DXGI_FORMAT format, D3D11_USAGE heapType, const void* data, uint32_t rowPitch, uint32_t imageSize, ID3D11Texture2D** ppTexture2D)
 {
     D3D11_TEXTURE2D_DESC desc;
@@ -148,7 +147,7 @@ void DeviceResources::createTexture2D(int w, int h, DXGI_FORMAT format, D3D11_US
     desc.Format = format;
     desc.SampleDesc.Count = 1;
     desc.SampleDesc.Quality = 0;
- 
+
     desc.MiscFlags = 0;
     desc.Usage = heapType;
     if (heapType == D3D11_USAGE_STAGING)
@@ -162,21 +161,21 @@ void DeviceResources::createTexture2D(int w, int h, DXGI_FORMAT format, D3D11_US
         desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
         desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
     }
- 
+
     D3D11_SUBRESOURCE_DATA* pInitialData = nullptr;
     D3D11_SUBRESOURCE_DATA initData;
     if (data)
     {
         initData.pSysMem = data;
-        initData.SysMemPitch = static_cast<uint32_t>(rowPitch);
-        initData.SysMemSlicePitch = static_cast<uint32_t>(imageSize);
+        initData.SysMemPitch = rowPitch;
+        initData.SysMemSlicePitch = imageSize;
         pInitialData = &initData;
     }
- 
+
     DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&desc, pInitialData, ppTexture2D));
 }
- 
-void DeviceResources::getTextureData(ID3D11Texture2D* texture, uint8_t* data)
+
+void DeviceResources::getTextureData(ID3D11Texture2D* texture, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& rowPitch)
 {
     D3D11_TEXTURE2D_DESC desc;
     texture->GetDesc(&desc);
@@ -189,10 +188,14 @@ void DeviceResources::getTextureData(ID3D11Texture2D* texture, uint8_t* data)
     D3D11_MAPPED_SUBRESOURCE mappedResource;
     DX::ThrowIfFailed(m_d3dContext->Map(stage.Get(), 0, D3D11_MAP_READ, 0, &mappedResource));
     uint8_t* mappData = (uint8_t*)mappedResource.pData;
-    memcpy(data, mappData, mappedResource.DepthPitch);
+    width = desc.Width;
+    height = desc.Height;
+    rowPitch = mappedResource.RowPitch;
+    data.resize(mappedResource.DepthPitch);
+    memcpy(data.data(), mappData, mappedResource.DepthPitch);
     m_d3dContext->Unmap(stage.Get(), 0);
 }
- 
+
 void DeviceResources::updateConstBuffer(void* data, uint32_t size, ID3D11Buffer* ppBuffer)
 {
     D3D11_MAPPED_SUBRESOURCE mappedResource;
@@ -201,7 +204,7 @@ void DeviceResources::updateConstBuffer(void* data, uint32_t size, ID3D11Buffer*
     memcpy(mappData, data, size);
     m_d3dContext->Unmap(ppBuffer, 0);
 }
- 
+
 void DeviceResources::createConstBuffer(void* initialData, uint32_t size, ID3D11Buffer** ppBuffer)
 {
     D3D11_BUFFER_DESC bDesc;
@@ -211,7 +214,7 @@ void DeviceResources::createConstBuffer(void* initialData, uint32_t size, ID3D11
     bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
     bDesc.MiscFlags = 0;
     bDesc.StructureByteStride = 0;
- 
+
     D3D11_SUBRESOURCE_DATA srData;
     srData.pSysMem = initialData;
     DX::ThrowIfFailed(m_d3dDevice->CreateBuffer(&bDesc, &srData, ppBuffer));

+ 25 - 15
samples/DX11/src/NVScaler.cpp

@@ -18,23 +18,20 @@
 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- 
+
 #include "NVScaler.h"
- 
-#pragma once
-#pragma once
- 
+
 #include <dxgi1_4.h>
 #include <d3d11_3.h>
 #include <d3dcompiler.h>
 #include <iostream>
- 
+
 #include "DXUtilities.h"
 #include "DeviceResources.h"
 #include "Utilities.h"
- 
- 
-NVScaler::NVScaler(DeviceResources& deviceResources, const std::string& shaderFolder)
+
+
+NVScaler::NVScaler(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths)
     : m_deviceResources(deviceResources)
     , m_outputWidth(1)
     , m_outputHeight(1)
@@ -43,14 +40,27 @@ NVScaler::NVScaler(DeviceResources& deviceResources, const std::string& shaderFo
     m_blockWidth = opt.GetOptimalBlockWidth();
     m_blockHeight = opt.GetOptimalBlockHeight();
     uint32_t threadGroupSize = opt.GetOptimalThreadGroupSize();
- 
+
     DX::Defines defines;
     defines.add("NIS_SCALER", true);
     defines.add("NIS_HDR_MODE", uint32_t(NISHDRMode::None));
     defines.add("NIS_BLOCK_WIDTH", m_blockWidth);
     defines.add("NIS_BLOCK_HEIGHT", m_blockHeight);
     defines.add("NIS_THREAD_GROUP_SIZE", threadGroupSize);
- 
+
+    std::string shaderName = "NIS_Main.hlsl";
+    std::string shaderFolder;
+    for (auto& e : shaderPaths)
+    {
+        if (std::filesystem::exists(e + "/" + shaderName))
+        {
+            shaderFolder = e;
+            break;
+        }
+    }
+    if (shaderFolder.empty())
+        throw std::runtime_error("Shader file not found" + shaderName);
+
     std::wstring wShaderFilename = widen(shaderFolder + "/" + "NIS_Main.hlsl");
     DX::IncludeHeader includeHeader({ shaderFolder });
     DX::CompileComputeShader(m_deviceResources.device(),
@@ -59,7 +69,7 @@ NVScaler::NVScaler(DeviceResources& deviceResources, const std::string& shaderFo
         &m_computeShader,
         defines.get(),
         &includeHeader);
- 
+
     const int rowPitch = kFilterSize * 4;
     const int imageSize = rowPitch * kPhaseCount;
     m_deviceResources.createTexture2D(kFilterSize / 4, kPhaseCount, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D11_USAGE_DEFAULT,
@@ -71,19 +81,19 @@ NVScaler::NVScaler(DeviceResources& deviceResources, const std::string& shaderFo
     m_deviceResources.createLinearClampSampler(&m_LinearClampSampler);
     m_deviceResources.createConstBuffer(&m_config, sizeof(NISConfig), &m_csBuffer);
 }
- 
+
 void NVScaler::update(float sharpness, uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight)
 {
     NVScalerUpdateConfig(m_config, sharpness,
         0, 0, inputWidth, inputHeight, inputWidth, inputHeight,
         0, 0, outputWidth, outputHeight, outputWidth, outputHeight,
         NISHDRMode::None);
- 
+
     m_deviceResources.updateConstBuffer(&m_config, sizeof(NISConfig), m_csBuffer.Get());
     m_outputWidth = outputWidth;
     m_outputHeight = outputHeight;
 }
- 
+
 void NVScaler::dispatch(ID3D11ShaderResourceView* const* input, ID3D11UnorderedAccessView* const* output)
 {
     auto context = m_deviceResources.context();

+ 14 - 5
samples/DX11/src/NVSharpen.cpp

@@ -21,9 +21,6 @@
 
 #include "NVSharpen.h"
 
-#pragma once
-#pragma once
-
 #include <dxgi1_4.h>
 #include <d3d11_3.h>
 #include <d3dcompiler.h>
@@ -34,7 +31,7 @@
 #include "Utilities.h"
 
 
-NVSharpen::NVSharpen(DeviceResources& deviceResources, const std::string& shaderFolder)
+NVSharpen::NVSharpen(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths)
     : m_deviceResources(deviceResources)
     , m_outputWidth(1)
     , m_outputHeight(1)
@@ -51,6 +48,18 @@ NVSharpen::NVSharpen(DeviceResources& deviceResources, const std::string& shader
     defines.add("NIS_BLOCK_HEIGHT", m_blockHeight);
     defines.add("NIS_THREAD_GROUP_SIZE", threadGroupSize);
 
+    std::string shaderName = "NIS_Main.hlsl";
+    std::string shaderFolder;
+    for (auto& e : shaderPaths)
+    {
+        if (std::filesystem::exists(e + "/" + shaderName))
+        {
+            shaderFolder = e;
+            break;
+        }
+    }
+    if (shaderFolder.empty())
+        throw std::runtime_error("Shader file not found" + shaderName);
     std::wstring wShaderFilename = widen(shaderFolder + "/" + "NIS_Main.hlsl");
     DX::IncludeHeader includeHeader({ shaderFolder });
     DX::CompileComputeShader(m_deviceResources.device(),
@@ -85,4 +94,4 @@ void NVSharpen::dispatch(ID3D11ShaderResourceView* const* input, ID3D11Unordered
     context->CSSetConstantBuffers(0, 1, m_csBuffer.GetAddressOf());
     context->CSSetShader(m_computeShader.Get(), nullptr, 0);
     context->Dispatch(UINT(std::ceil(m_outputWidth / float(m_blockWidth))), UINT(std::ceil(m_outputHeight / float(m_blockHeight))), 1);
-}
+}

+ 31 - 32
samples/DX11/src/Sample.cpp

@@ -23,43 +23,36 @@
 #pragma comment(lib, "dxgi")
 #pragma comment(lib, "d3dcompiler")
 #pragma comment(lib, "windowscodecs")
- 
- 
+
+
 #include <d3d11.h>
 #include <filesystem>
 #include <iostream>
 #include <tchar.h>
 #include <wincodec.h>
- 
+
 #include "AppRenderer.h"
 #include "DeviceResources.h"
 #include "UIRenderer.h"
 #include "Utilities.h"
- 
+
 DeviceResources deviceResources;
 UIData uiData;
- 
+
 LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
- 
+
 int main(int argc, char* argv[])
 {
     // Resources
     std::string mediaFolder = "media/images/";
-    std::string shadersFolder = "NIS/";
- 
+
     if (!std::filesystem::exists(mediaFolder))
         mediaFolder = "media/images/";
     if (!std::filesystem::exists(mediaFolder))
         mediaFolder = "../../media/images/";
     if (!std::filesystem::exists(mediaFolder))
         return -1;
-    if (!std::filesystem::exists(shadersFolder))
-        shadersFolder = "NIS/";
-    if (!std::filesystem::exists(shadersFolder))
-        shadersFolder = "../../../NIS/";
-    if (!std::filesystem::exists(shadersFolder))
-        return -1;
- 
+
     // Create Window
     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr),
                     nullptr, nullptr, nullptr, nullptr, L"NVIDIA Image Scaling Demo", nullptr };
@@ -67,38 +60,44 @@ int main(int argc, char* argv[])
     RECT wr = { 0, 0, 1280, 1080 };
     AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
     HWND hwnd = ::CreateWindow(wc.lpszClassName, L"NVIDIA Image Scaling DX11 Demo", WS_OVERLAPPEDWINDOW,
-                    100, 100, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, wc.hInstance, nullptr);
+                    0, 0, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, wc.hInstance, nullptr);
     ::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX);
     SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
- 
+
     // Initialize DX11
     deviceResources.create(hwnd, 0);
- 
+
     // Show the window
     ::ShowWindow(hwnd, SW_SHOWDEFAULT);
     ::UpdateWindow(hwnd);
- 
+
     // UI settings
     uiData.Files = getFiles(mediaFolder);
     if (uiData.Files.size() == 0)
         throw std::runtime_error("No media files");
     uiData.FileName = uiData.Files[0].filename().string();
     uiData.FilePath = uiData.Files[0];
- 
+
     // Renderers
-    AppRenderer appRenderer(deviceResources, uiData, shadersFolder);
+    std::vector<std::string> shaderPaths{ "NIS/", "../../../NIS/", "../../DX11/src/" };
+    AppRenderer appRenderer(deviceResources, uiData, shaderPaths);
     UIRenderer uiRenderer(hwnd, deviceResources, uiData);
     FPS m_fps;
- 
+
     MSG msg{};
     while (msg.message != WM_QUIT)
     {
         if (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE))
         {
+            // press 's' to dump png file
+            if (msg.message == WM_KEYDOWN && msg.wParam == 'S')
+            {
+                appRenderer.saveOutput("dump.png");
+            }
             ::TranslateMessage(&msg);
             ::DispatchMessage(&msg);
         }
- 
+
         // Update
         m_fps.update();
         if (appRenderer.update())
@@ -108,35 +107,35 @@ int main(int argc, char* argv[])
             SetWindowPos(hwnd, nullptr, 0, 0, wr.right - wr.left, wr.bottom - wr.top, SWP_NOMOVE);
         }
         uiRenderer.update(m_fps.fps());
- 
+
         // Render
         appRenderer.render();
         uiRenderer.render(); // render UI at the end
- 
+
         deviceResources.present(uiData.EnableVsync, 0);
     }
- 
+
     uiRenderer.cleanUp();
- 
+
     ::DestroyWindow(hwnd);
     ::UnregisterClass(wc.lpszClassName, wc.hInstance);
- 
+
     return 0;
 }
- 
+
 // Forward declare message handler from imgui_impl_win32.cpp
 extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
- 
+
 // Win32 message handler
 LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
         return true;
- 
+
     switch (msg)
     {
     case WM_SIZE:
-        if (deviceResources.initialized() && wParam != SIZE_MINIMIZED)
+        if (deviceResources.isInitialized() && wParam != SIZE_MINIMIZED)
         {
             deviceResources.resizeRenderTarget((UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_R8G8B8A8_UNORM);
         }

+ 12 - 12
samples/DX11/src/UIRenderer.cpp

@@ -1,26 +1,26 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- 
+
 #include <UIRenderer.h>
- 
+
 UIRenderer::UIRenderer(HWND hwnd, DeviceResources& deviceResources, UIData& ui)
 : m_ui(ui)
 , m_deviceResources(deviceResources)
@@ -29,15 +29,15 @@ UIRenderer::UIRenderer(HWND hwnd, DeviceResources& deviceResources, UIData& ui)
     IMGUI_CHECKVERSION();
     ImGui::CreateContext();
     ImGuiIO& io = ImGui::GetIO(); (void)io;
- 
+
     ImGui::StyleColorsDark();
     ImGui::GetStyle().WindowRounding = 6;
     ImGui::GetStyle().FrameBorderSize = 1;
- 
+
     ImGui_ImplWin32_Init(hwnd);
     ImGui_ImplDX11_Init(m_deviceResources.device(), m_deviceResources.context());
 }
- 
+
 void UIRenderer::cleanUp()
 {
     // Cleanup
@@ -45,7 +45,7 @@ void UIRenderer::cleanUp()
     ImGui_ImplWin32_Shutdown();
     ImGui::DestroyContext();
 }
- 
+
 void UIRenderer::update(double fps)
 {
     m_elapsedTimer.start();
@@ -183,13 +183,13 @@ void UIRenderer::update(double fps)
             ImGui::Text("Presnt Time : %9.2f %s", totalTime - filterTime - uiTime, unitStr.c_str());
             ImGui::Text("Total Time  : %9.2f %s", totalTime, unitStr.c_str());
         }
- 
+
         ImGui::End();
     }
     ImGui::Render();
     m_elapsedTimer.end();
 }
- 
+
 void UIRenderer::render()
 {
     ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

+ 94 - 0
samples/DX12/CMakeLists.txt

@@ -0,0 +1,94 @@
+project(dx12_sample)
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /UMBCS /D_UNICODE /DUNICODE")
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin/DX12/)
+
+set(IMGUI_PATH    "${CMAKE_SOURCE_DIR}/third_party/imgui/")
+set(IMGUI_INCLUDE "${IMGUI_PATH}" "${IMGUI_PATH}/backends/")
+set(IMGUI_SRC     "${IMGUI_PATH}/backends/imgui_impl_dx12.cpp"
+                  "${IMGUI_PATH}/backends/imgui_impl_win32.cpp"
+                  "${IMGUI_PATH}/imgui.cpp"
+                  "${IMGUI_PATH}/imgui_demo.cpp"
+                  "${IMGUI_PATH}/imgui_draw.cpp"
+                  "${IMGUI_PATH}/imgui_tables.cpp"
+                  "${IMGUI_PATH}/imgui_widgets.cpp"
+)
+
+set(TINYEXR_PATH    "${CMAKE_SOURCE_DIR}/third_party/tinyexr/")
+set(TINYEXR_INCLUDE "${TINYEXR_PATH}" "${TINYEXR_PATH}/deps/miniz")
+set(TINYEXR_SRC     "${TINYEXR_PATH}/deps/miniz/miniz.c")
+
+set(STB_PATH     "${CMAKE_SOURCE_DIR}/third_party/stb/")
+set(STB_INCLUDE  "${STB_PATH}")
+
+set(DXC_PATH "${CMAKE_SOURCE_DIR}/third_party/DXC/")
+set(DXC_INCLUDE "${CMAKE_SOURCE_DIR}/third_party/DXC/inc/")
+set(DXC_LIB "${CMAKE_SOURCE_DIR}/third_party/DXC/lib/x64/dxcompiler.lib")
+set(DXC_BIN "${CMAKE_SOURCE_DIR}/third_party/DXC/bin/x64/")
+
+set(NIS_PATH "${CMAKE_SOURCE_DIR}/../NIS")
+
+set(SAMPLES_PATH "${CMAKE_SOURCE_DIR}")
+
+set(DX_SAMPLE_SRC "src/Sample.cpp"
+                  "src/AppRenderer.cpp"
+                  "src/UIRenderer.cpp"
+                  "src/DeviceResources.cpp"
+                  "src/NVScaler.cpp"
+                  "src/NVSharpen.cpp"
+                  "src/BilinearUpscale.cpp"
+                  "${SAMPLES_PATH}/common/Image.cpp"
+                  "src/dpi.manifest"
+)
+
+set(DX_SAMPLE_HEADERS "include/AppRenderer.h"
+                      "include/DeviceResources.h"
+                      "include/NVScaler.h"
+                      "include/NVSharpen.h"
+                      "include/UIRenderer.h"
+                      "include/BilinearUpscale.h"
+                      "include/DXUtilities.h"
+                      "include/d3dx12.h"
+                      "${NIS_PATH}/NIS_Config.h"
+                      "${SAMPLES_PATH}/common/Image.h"
+                      "${SAMPLES_PATH}/common/Utilities.h"
+)
+
+set(DX_SAMPLE_SHADERS  "${NIS_PATH}/NIS_Scaler.h"
+                       "${NIS_PATH}/NIS_Main.hlsl"
+                       "src/bilinearUpscale.hlsl"
+)
+
+set(DX_SAMPLE_MEDIA "${SAMPLES_PATH}/media/images/1080.png"
+                    "${SAMPLES_PATH}/media/images/1440.png"
+                    "${SAMPLES_PATH}/media/images/1660.png"
+)
+
+set_source_files_properties(${DX_SAMPLE_SHADERS} PROPERTIES VS_COPY_TO_OUT_DIR TRUE)
+
+source_group("external" FILES ${IMGUI_SRC} ${TINYEXR_SRC})
+source_group("shaders" FILES ${DX_SAMPLE_SHADERS})
+add_executable(${PROJECT_NAME} ${DX_SAMPLE_SRC} ${IMGUI_SRC} ${TINYEXR_SRC} ${DX_SAMPLE_HEADERS} ${DX_SAMPLE_SHADERS})
+target_link_libraries(${PROJECT_NAME} PUBLIC ${DXC_LIB})
+target_include_directories(${PROJECT_NAME} PUBLIC include ${IMGUI_INCLUDE} ${TINYEXR_INCLUDE} ${STB_INCLUDE} ${NIS_PATH} ${SAMPLES_PATH}/common)
+
+add_custom_command(
+  TARGET ${PROJECT_NAME} POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+  COMMAND ${CMAKE_COMMAND} -E copy_directory ${NIS_PATH} $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SAMPLES_PATH}"/DX12/src/bilinearUpscale.hlsl" $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+)
+
+add_custom_command(
+  TARGET ${PROJECT_NAME} POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DXC_BIN}/dxcompiler.dll $<TARGET_FILE_DIR:${PROJECT_NAME}>/
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DXC_BIN}/dxil.dll $<TARGET_FILE_DIR:${PROJECT_NAME}>/
+)
+
+add_custom_command(
+  TARGET ${PROJECT_NAME} POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/media/images
+  COMMAND ${CMAKE_COMMAND} -E copy_directory ${SAMPLES_PATH}/media/images $<TARGET_FILE_DIR:${PROJECT_NAME}>/media/images
+)
+

+ 107 - 0
samples/DX12/include/AppRenderer.h

@@ -0,0 +1,107 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <d3d11.h>
+#include <wrl.h>
+
+#include "DeviceResources.h"
+#include "NVScaler.h"
+#include "NVSharpen.h"
+#include "UIRenderer.h"
+#include "BilinearUpscale.h"
+#include "Image.h"
+#include "d3dx12.h"
+
+using namespace Microsoft::WRL;
+
+class AppRenderer
+{
+public:
+    AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::vector<std::string>& shaderPaths);
+    bool updateSize();
+    void update();
+    void render();
+    uint32_t width() { return m_outputWidth; }
+    uint32_t height() { return m_outputHeight; }
+    bool isInitialized() { return m_init; }
+    void saveOutput(const std::string& filename);
+protected:
+    void scheduleCopyOutput();
+    void saveOutputToFile();
+private:
+    UIData& m_ui;
+    DeviceResources& m_deviceResources;
+    NVScaler							m_NVScaler;
+    NVSharpen							m_NVSharpen;
+    BilinearUpscale						m_upscale;
+
+    uint32_t							m_inputWidth = 0;
+    uint32_t							m_inputHeight = 0;
+    uint32_t							m_outputWidth = 0;
+    uint32_t							m_outputHeight = 0;
+
+    ComPtr<ID3D12Resource>				m_input;
+    ComPtr<ID3D12Resource>				m_output;
+    ComPtr<ID3D12Resource>              m_inputUpload;
+
+    DescriptorHeap                      m_samplerDescriptorHeap;
+    DescriptorHeap                      m_RVDescriptorHeap;
+
+    std::vector<uint8_t>                m_image;
+    uint32_t                            m_rowPitch;
+    std::filesystem::path				m_currentFilePath;
+
+    uint32_t                            m_currentOutputWidth;
+    uint32_t                            m_currentOutputHeight;
+    float							    m_currentScale = 100;
+    float   							m_currentSharpness = 0;
+    bool                                m_updateWindowSize = false;
+    bool                                m_updateSharpness = false;
+    bool                                m_uploadCoefficients = true;
+    bool                                m_init = false;
+
+    bool                                m_saveOutput = false;
+    bool                                m_saveReadBack = false;
+    std::string                         m_saveFileName = "";
+    ComPtr<ID3D12Resource>              m_outputReadBack;
+    uint32_t                            m_saveWidth = 0;
+    uint32_t                            m_saveHeight = 0;
+    uint32_t                            m_saveRowPitch = 0;
+
+    enum DescriptorHeapCount : uint32_t
+    {
+        cCB = 3,
+        cUAV = 1,
+        cSRV = 3,
+    };
+    enum DescriptorHeapIndex : uint32_t
+    {
+        iCB = 0,
+        iUAV = iCB + cCB,
+        iSRV = iUAV + cUAV,
+        iHeapEnd = iSRV + cSRV
+    };
+};

+ 83 - 0
samples/DX12/include/BilinearUpscale.h

@@ -0,0 +1,83 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <dxgi1_4.h>
+#include <d3d12.h>
+#include "d3dx12.h"
+extern "C" {
+#include <dxcapi.h>
+}
+
+#include "DeviceResources.h"
+
+__declspec(align(256))
+struct BilinearUpscaleConfig
+{
+    uint32_t kInputViewportOriginX;
+    uint32_t kInputViewportOriginY;
+    uint32_t kInputViewportWidth;
+    uint32_t kInputViewportHeight;
+    uint32_t kOutputViewportOriginX;
+    uint32_t kOutputViewportOriginY;
+    uint32_t kOutputViewportWidth;
+    uint32_t kOutputViewportHeight;
+    float    kScaleX;
+    float    kScaleY;
+    float    kDstNormX;
+    float    kDstNormY;
+    float    kSrcNormX;
+    float    kSrcNormY;
+};
+
+void BilinearUpdateConfig(BilinearUpscaleConfig& config,
+    uint32_t inputViewportOriginX, uint32_t inputViewportOriginY,
+    uint32_t inputViewportWidth, uint32_t inputViewportHeight,
+    uint32_t inputTextureWidth, uint32_t inputTextureHeight,
+    uint32_t outputViewportOriginX, uint32_t outputViewportOriginY,
+    uint32_t outputViewportWidth, uint32_t outputViewportHeight,
+    uint32_t outputTextureWidth, uint32_t outputTextureHeight);
+
+class BilinearUpscale {
+public:
+    BilinearUpscale(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths);
+    void update(uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight);
+    ID3D12PipelineState* getComputePSO() { return m_computePSO.Get(); }
+    ID3D12Resource* getConstantBuffer() { return m_constatBuffer.Get(); }
+    ID3D12RootSignature* getRootSignature() { return m_computeRootSignature.Get(); }
+    std::vector<UINT> getDispatchDim() {
+        return { UINT(std::ceil(m_outputWidth / float(m_BlockWidth))), UINT(std::ceil(m_outputHeight / float(m_BlockHeight))), 1 };
+    }
+private:
+    DeviceResources& m_deviceResources;
+    BilinearUpscaleConfig               m_config;
+    ComPtr<ID3D12RootSignature>         m_computeRootSignature;
+    ComPtr<ID3D12PipelineState>         m_computePSO;
+
+    ComPtr<ID3D12Resource>              m_constatBuffer;
+    ComPtr<ID3D12Resource>              m_stagingBuffer;
+
+    uint32_t                            m_outputWidth;
+    uint32_t                            m_outputHeight;
+    uint32_t                            m_BlockWidth = 16;
+    uint32_t                            m_BlockHeight = 16;
+};

+ 76 - 0
samples/DX12/include/DXUtilities.h

@@ -0,0 +1,76 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <stdio.h>
+#include <tchar.h>
+#include <dxgi1_4.h>
+#include <d3d12.h>
+#include <d3dcompiler.h>
+#include <wrl.h>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+namespace DX
+{
+    using namespace Microsoft::WRL;
+
+    inline LPTSTR GetErrorDescription(HRESULT hr, WCHAR* buffer, size_t size)
+    {
+        if (FACILITY_WINDOWS == HRESULT_FACILITY(hr))
+            hr = HRESULT_CODE(hr);
+
+        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+            nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, DWORD(size), nullptr);
+        return buffer;
+    }
+
+    inline void ThrowIfFailed(HRESULT hr)
+    {
+        if (FAILED(hr))
+        {
+            // Set a breakpoint on this line to catch Win32 API errors.
+            const size_t size = 1024;
+            WCHAR buffer[size];
+            GetErrorDescription(hr, buffer, size);
+            char str[size];
+            size_t i = 0;
+            wcstombs_s(&i, str, 1024, buffer, 1024);
+            throw std::runtime_error(str);
+        }
+    }
+    inline std::vector<uint8_t> ReadBinaryFile(const std::string& filename)
+    {
+        std::ifstream ifs(filename, std::ios::in | std::ios::binary | std::ios::ate);
+        if (!ifs)
+            throw std::runtime_error("ReadBinaryFile");
+        std::streampos len = ifs.tellg();
+        std::vector<uint8_t> data;
+        data.resize(size_t(len));
+        ifs.seekg(0, std::ios::beg);
+        ifs.read(reinterpret_cast<char*>(data.data()), len);
+        ifs.close();
+        return data;
+    }
+}

+ 174 - 0
samples/DX12/include/DeviceResources.h

@@ -0,0 +1,174 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <d3d12.h>
+#include <dxgi1_4.h>
+#include <wrl.h>
+#include <iostream>
+#include <vector>
+#include "DXUtilities.h"
+
+using namespace Microsoft::WRL;
+
+constexpr uint32_t NUM_BACK_BUFFERS = 4;
+
+struct Adapter
+{
+    std::string Description;
+    uint32_t VendorId;
+    uint32_t DeviceId;
+    uint32_t SubSysId;
+    uint32_t Revision;
+    size_t DedicatedVideoMemory;
+    size_t DedicatedSystemMemory;
+    size_t SharedSystemMemory;
+};
+
+class DescriptorHeap
+{
+public:
+    DescriptorHeap() {}
+    void Create(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE Type, uint32_t numDescriptors, D3D12_DESCRIPTOR_HEAP_FLAGS flags, LPCWSTR debugHeapName = L"") {
+        m_HeapDesc.Type = Type;
+        m_HeapDesc.NumDescriptors = numDescriptors;
+        m_HeapDesc.Flags = flags;
+        m_HeapDesc.NodeMask = 1;
+
+        DX::ThrowIfFailed(device->CreateDescriptorHeap(&m_HeapDesc, __uuidof(ID3D12DescriptorHeap), &m_Heap));
+        m_Heap->SetName(debugHeapName);
+        m_DescriptorSize = device->GetDescriptorHandleIncrementSize(m_HeapDesc.Type);
+        D3D12_CPU_DESCRIPTOR_HANDLE ret = m_Heap->GetCPUDescriptorHandleForHeapStart();
+    }
+    ID3D12DescriptorHeap* getDescriptorHeap() { return m_Heap.Get(); }
+    D3D12_CPU_DESCRIPTOR_HANDLE getCPUDescriptorHandle(uint32_t idx) {
+        D3D12_CPU_DESCRIPTOR_HANDLE ret = m_Heap->GetCPUDescriptorHandleForHeapStart();
+        ret.ptr += m_DescriptorSize * idx;
+        return ret;
+    }
+    D3D12_GPU_DESCRIPTOR_HANDLE getGPUDescriptorHandle(uint32_t idx) {
+        D3D12_GPU_DESCRIPTOR_HANDLE ret = m_Heap->GetGPUDescriptorHandleForHeapStart();
+        ret.ptr += m_DescriptorSize * idx;
+        return ret;
+    }
+private:
+    ComPtr<ID3D12DescriptorHeap> m_Heap;
+    D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc = {};
+    uint64_t m_DescriptorSize = 0;
+};
+
+class DeviceResources;
+
+class GPUTimer
+{
+public:
+    void Initialize(DeviceResources* deviceResources);
+    void StartTimer(ID3D12GraphicsCommandList* commandList) {
+        commandList->EndQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, 0);
+    }
+    void StopTimer(ID3D12GraphicsCommandList* commandList) {
+        commandList->EndQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, 1);
+    }
+    void ResolveQuery(ID3D12GraphicsCommandList* commandList) {
+        commandList->ResolveQueryData(m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, 0, 2, m_readBackBuffer.Get(), 0);
+    }
+    void ReadBack();
+    double GetTime_us() {
+        return static_cast<double>(m_gpuTickDelta * (m_timeEnd - m_timeStart)) * 1E6;
+    }
+private:
+    ComPtr<ID3D12Resource> m_readBackBuffer;
+    ComPtr<ID3D12QueryHeap> m_queryHeap;
+    uint64_t m_fenceValue = 0;
+    uint64_t m_timeStart = 0;
+    uint64_t m_timeEnd = 0;
+    double m_gpuTickDelta = 0.0;
+};
+
+class DeviceResources
+{
+public:
+    void create(HWND hWnd, uint32_t adapterIdx);
+    bool isInitialized() { return m_initialized; }
+    ID3D12Device* device() { return m_device.Get(); }
+    ID3D12DescriptorHeap* SRVDescHeap() { return m_SRVDescHeap.getDescriptorHeap(); }
+    ID3D12CommandQueue* commandQueue() { return m_commandQueue.Get(); }
+    ID3D12GraphicsCommandList* commandList() { return m_commandList.Get(); }
+
+    void WaitForGPU();
+    void MoveToNextFrame();
+    void PopulateCommandList();
+    void Present(uint32_t SyncInterval, uint32_t Flags);
+    void resizeRenderTarget(uint32_t width, uint32_t height);
+
+    void CreateTexture2D(uint32_t width, uint32_t height, DXGI_FORMAT format, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource);
+    void CreateTexture1D(uint32_t width, DXGI_FORMAT format, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource);
+    void CreateBuffer(uint32_t size, D3D12_HEAP_TYPE heapType, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource);
+    void UploadTextureData(void* data, uint32_t size, uint32_t rowPitch, ID3D12Resource* pResource, ID3D12Resource* pStagingResource);
+    void UploadBufferData(void* data, uint32_t size, ID3D12Resource* pResource, ID3D12Resource* pStagingResource);
+    void CopyToRenderTarget(ID3D12Resource* pSrc);
+
+    ID3D12Resource* getRenderTarget();
+    Adapter adapter() { return m_adapter; }
+    ID3D12GraphicsCommandList* computeCommandList() { return m_computeCommandList.Get(); }
+    void StartComputeTimer() { m_timer.StartTimer(m_computeCommandList.Get()); }
+    void StopComputeTimer() { m_timer.StopTimer(m_computeCommandList.Get()); }
+    void ResolveComputeTimerQuery() { m_timer.ResolveQuery(m_computeCommandList.Get()); }
+    double GetTime_us() { return m_timer.GetTime_us(); }
+    ID3D12Resource* m_output;
+protected:
+    void CreateRenderTarget();
+    void ReleaseRenderTarget();
+private:
+    struct FrameContext
+    {
+        ComPtr<ID3D12CommandAllocator> m_allocator;
+        ComPtr<ID3D12CommandAllocator> m_computeAllocator;
+        ComPtr<ID3D12Fence>            m_fence;
+        uint64_t                       m_fenceValue = 0;
+    };
+
+    ComPtr<ID3D12Device>               m_device;
+    ComPtr<ID3D12CommandQueue>         m_commandQueue;
+    ComPtr<ID3D12GraphicsCommandList>  m_commandList;
+    ComPtr<ID3D12GraphicsCommandList>  m_computeCommandList;
+    ComPtr<ID3D12PipelineState>        m_pipelineState;
+
+    FrameContext                       m_frameContext[NUM_BACK_BUFFERS] = {};
+
+    uint32_t                           m_frameIndex = 0;
+
+    Wrappers::Event                    m_fenceEvent;
+
+    ComPtr<IDXGISwapChain3>            m_swapChain;
+    HANDLE                             m_swapChainWaitableObject = nullptr;
+
+    ComPtr<ID3D12Resource>             m_RTResource[NUM_BACK_BUFFERS] = {};
+    DescriptorHeap                     m_RTVDescHeap;
+    DescriptorHeap                     m_SRVDescHeap;
+
+    GPUTimer                           m_timer;
+
+    bool                               m_initialized = false;
+    bool                               m_windowResized = false;
+    Adapter                            m_adapter;
+};

+ 74 - 0
samples/DX12/include/NVScaler.h

@@ -0,0 +1,74 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <dxgi1_4.h>
+#include <d3d12.h>
+#include <iostream>
+
+#include "DXUtilities.h"
+#include "DeviceResources.h"
+#include "Utilities.h"
+#include "NIS_Config.h"
+#include "d3dx12.h"
+
+extern "C" {
+    #include <dxcapi.h>
+}
+
+class NVScaler {
+public:
+    NVScaler(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths);
+    void update(float sharpness, uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight);
+    void uploadCoefficients();
+    ID3D12PipelineState* getComputePSO() { return m_computePSO.Get(); }
+    ID3D12Resource* getConstantBuffer() { return m_constatBuffer.Get(); }
+    ID3D12RootSignature* getRootSignature() { return m_computeRootSignature.Get(); }
+    std::vector<UINT> getDispatchDim() {
+        return {UINT(std::ceil(m_outputWidth / float(m_blockWidth))), UINT(std::ceil(m_outputHeight / float(m_blockHeight))), 1 };
+    }
+    ID3D12Resource* getCoefScaler() { return m_coefScaler.Get(); }
+    ID3D12Resource* getCoefUSM() { return m_coefUSM.Get(); }
+protected:
+    void createAlignedCoefficients(uint16_t* data, std::vector<uint16_t>& coef, uint32_t rowPitchAligned);
+private:
+    DeviceResources&                    m_deviceResources;
+    NISConfig                           m_config;
+    ComPtr<ID3D12RootSignature>         m_computeRootSignature;
+    ComPtr<ID3D12PipelineState>         m_computePSO;
+
+    ComPtr<ID3D12Resource>				m_constatBuffer;
+    ComPtr<ID3D12Resource>              m_stagingBuffer;
+
+    ComPtr<ID3D12Resource>				m_coefScaler;
+    ComPtr<ID3D12Resource>				m_coefUSM;
+    ComPtr<ID3D12Resource>				m_coefScalerUpload;
+    ComPtr<ID3D12Resource>				m_coefUSMUpload;
+    std::vector<uint16_t>               m_coefScalerHost;
+    std::vector<uint16_t>               m_coefUSMHost;
+    uint32_t                            m_rowPitch;
+
+    uint32_t                            m_outputWidth;
+    uint32_t                            m_outputHeight;
+    uint32_t                            m_blockWidth;
+    uint32_t                            m_blockHeight;
+};

+ 61 - 0
samples/DX12/include/NVSharpen.h

@@ -0,0 +1,61 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <dxgi1_4.h>
+#include <d3d12.h>
+#include <iostream>
+
+#include "DXUtilities.h"
+#include "DeviceResources.h"
+#include "Utilities.h"
+#include "NIS_Config.h"
+#include "d3dx12.h"
+
+extern "C" {
+#include <dxcapi.h>
+}
+
+class NVSharpen {
+public:
+    NVSharpen(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths);
+    void update(float sharpness, uint32_t inputWidth, uint32_t inputHeight);
+    ID3D12PipelineState* getComputePSO() { return m_computePSO.Get(); }
+    ID3D12Resource* getConstantBuffer() { return m_constatBuffer.Get(); }
+    ID3D12RootSignature* getRootSignature() { return m_computeRootSignature.Get(); }
+    std::vector<UINT> getDispatchDim() {
+        return { UINT(std::ceil(m_outputWidth / float(m_blockWidth))), UINT(std::ceil(m_outputHeight / float(m_blockHeight))), 1 };
+    }
+private:
+    DeviceResources& m_deviceResources;
+    NISConfig                           m_config;
+    ComPtr<ID3D12RootSignature>         m_computeRootSignature;
+    ComPtr<ID3D12PipelineState>         m_computePSO;
+
+    ComPtr<ID3D12Resource>				m_constatBuffer;
+    ComPtr<ID3D12Resource>              m_stagingBuffer;
+
+    uint32_t                            m_outputWidth;
+    uint32_t                            m_outputHeight;
+    uint32_t                            m_blockWidth;
+    uint32_t                            m_blockHeight;
+};

+ 75 - 0
samples/DX12/include/UIRenderer.h

@@ -0,0 +1,75 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <iomanip>
+#include <iostream>
+#include <filesystem>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <imgui.h>
+#include <imgui_impl_win32.h>
+#include <imgui_impl_dx12.h>
+#include "DeviceResources.h"
+#include "Utilities.h"
+
+enum class OutputSizeMode : uint32_t
+{
+	VARIABLE,
+	P1080,
+	P1440,
+	P2160
+};
+
+struct UIData
+{
+	std::vector<std::filesystem::path> Files;
+	std::filesystem::path FilePath;
+	std::string FileName;
+	float Scale = 75.f;
+	bool EnableNVScaler = true;
+	int FilterMode = 0;
+	float Sharpness = 50.f;
+	bool EnableVsync = false;
+	OutputSizeMode OutputMode;
+	uint32_t InputWidth;
+	uint32_t InputHeight;
+	uint32_t OutputWidth;
+	uint32_t OutputHeight;
+	double FilterTime;
+	bool ShowSettings = true;
+	int32_t UnitMicroseconds = true;
+};
+
+class UIRenderer
+{
+public:
+	UIRenderer(HWND hwnd, DeviceResources& deviceResources, UIData& ui);
+	void cleanUp();
+	void update(double fps);
+	void render();
+private:
+	UIData& m_ui;
+	DeviceResources& m_deviceResources;
+	ElapsedTimer m_elapsedTimer;
+};

ファイルの差分が大きいため隠しています
+ 3439 - 0
samples/DX12/include/d3dx12.h


+ 236 - 0
samples/DX12/src/AppRenderer.cpp

@@ -0,0 +1,236 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include "AppRenderer.h"
+
+using namespace Microsoft::WRL;
+
+AppRenderer::AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::vector<std::string>& shaderPaths)
+    : m_ui(ui)
+    , m_deviceResources(deviceResources)
+    , m_NVScaler(deviceResources, shaderPaths)
+    , m_NVSharpen(deviceResources, shaderPaths)
+    , m_upscale(deviceResources, shaderPaths)
+{
+
+    D3D12_SAMPLER_DESC samplerDesc;
+    samplerDesc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT;
+    samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+    samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+    samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+    samplerDesc.MipLODBias = 0.0f;
+    samplerDesc.MaxAnisotropy = 1;
+    samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
+    samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
+
+    m_samplerDescriptorHeap.Create(m_deviceResources.device(), D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, L"samplerDescriptorHeap");
+    m_deviceResources.device()->CreateSampler(&samplerDesc, m_samplerDescriptorHeap.getCPUDescriptorHandle(0));
+
+    m_RVDescriptorHeap.Create(m_deviceResources.device(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, DescriptorHeapIndex::iHeapEnd, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, L"RVDescriptorHeap");
+
+    D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
+    // Bilinear
+    cbvDesc.BufferLocation = m_upscale.getConstantBuffer()->GetGPUVirtualAddress();
+    cbvDesc.SizeInBytes = sizeof(BilinearUpscaleConfig);
+    m_deviceResources.device()->CreateConstantBufferView(&cbvDesc, m_RVDescriptorHeap.getCPUDescriptorHandle(iCB));
+
+    // NVScaler
+    cbvDesc.BufferLocation = m_NVScaler.getConstantBuffer()->GetGPUVirtualAddress();
+    cbvDesc.SizeInBytes = sizeof(NISConfig);
+    m_deviceResources.device()->CreateConstantBufferView(&cbvDesc, m_RVDescriptorHeap.getCPUDescriptorHandle(iCB + 1));
+    m_deviceResources.device()->CreateShaderResourceView(m_NVScaler.getCoefScaler(), nullptr, m_RVDescriptorHeap.getCPUDescriptorHandle(iSRV + 1));
+    m_deviceResources.device()->CreateShaderResourceView(m_NVScaler.getCoefUSM(), nullptr, m_RVDescriptorHeap.getCPUDescriptorHandle(iSRV + 2));
+
+    // NVSharpen
+    cbvDesc.BufferLocation = m_NVSharpen.getConstantBuffer()->GetGPUVirtualAddress();
+    cbvDesc.SizeInBytes = sizeof(NISConfig);
+    m_deviceResources.device()->CreateConstantBufferView(&cbvDesc, m_RVDescriptorHeap.getCPUDescriptorHandle(iCB + 2));
+}
+
+bool AppRenderer::updateSize()
+{
+    bool updateWindowSize = m_currentFilePath != m_ui.FilePath || m_currentScale != m_ui.Scale;
+    bool updateSharpness = m_ui.Sharpness != m_currentSharpness;
+    if (updateWindowSize)
+    {
+        if (m_currentFilePath != m_ui.FilePath)
+        {
+            img::load(m_ui.FilePath.string(), m_image, m_inputWidth, m_inputHeight, m_rowPitch, img::Fmt::R16G16B16A16, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
+            m_currentFilePath = m_ui.FilePath;
+        }
+        if (m_ui.Scale == 100)
+        {
+            m_outputWidth = m_inputWidth;
+            m_outputHeight = m_inputHeight;
+        }
+        else
+        {
+            m_outputWidth = uint32_t(std::ceil(m_inputWidth * 100.f / m_ui.Scale));
+            m_outputHeight = uint32_t(std::ceil(m_inputHeight * 100.f / m_ui.Scale));
+        }
+
+        m_currentScale = m_ui.Scale;
+        m_ui.InputWidth = m_inputWidth;
+        m_ui.InputHeight = m_inputHeight;
+        m_ui.OutputWidth = m_outputWidth;
+        m_ui.OutputHeight = m_outputHeight;
+        m_updateWindowSize = true;
+    }
+    if (updateSharpness) {
+        m_currentSharpness = m_ui.Sharpness;
+        m_updateSharpness = true;
+    }
+    m_init = true;
+    return updateWindowSize;
+}
+
+void AppRenderer::update()
+{
+    if (m_updateWindowSize) {
+        m_deviceResources.CreateBuffer(uint32_t(m_image.size()), D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, &m_inputUpload);
+        m_deviceResources.CreateTexture2D(m_inputWidth, m_inputHeight, DXGI_FORMAT_R16G16B16A16_FLOAT, D3D12_RESOURCE_STATE_COMMON, &m_input);
+        m_deviceResources.UploadTextureData(m_image.data(), uint32_t(m_image.size()), m_rowPitch , m_input.Get(), m_inputUpload.Get());
+
+        m_deviceResources.device()->CreateShaderResourceView(m_input.Get(), nullptr, m_RVDescriptorHeap.getCPUDescriptorHandle(iSRV));
+
+        m_deviceResources.CreateTexture2D(m_outputWidth, m_outputHeight, DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RESOURCE_STATE_COMMON, &m_output);
+        m_deviceResources.device()->CreateShaderResourceView(m_output.Get(), nullptr, m_RVDescriptorHeap.getCPUDescriptorHandle(iUAV));
+    }
+    if (m_updateSharpness || m_updateWindowSize) {
+        m_upscale.update(m_inputWidth, m_inputHeight, m_outputWidth, m_outputHeight);
+        m_NVScaler.update(m_currentSharpness / 100.f, m_inputWidth, m_inputHeight, m_outputWidth, m_outputHeight);
+        m_NVSharpen.update(m_currentSharpness / 100.f, m_inputWidth, m_inputHeight);
+        m_updateWindowSize = false;
+        m_updateSharpness = false;
+    }
+    if (m_uploadCoefficients) {
+        m_NVScaler.uploadCoefficients();
+        m_uploadCoefficients = false;
+    }
+    if (m_saveOutput && m_saveReadBack) {
+        saveOutputToFile();
+        m_saveOutput = false;
+        m_saveReadBack = false;
+    }
+}
+
+void AppRenderer::render()
+{
+    auto computeCommandList = m_deviceResources.computeCommandList();
+    std::vector<ID3D12DescriptorHeap*> pHeaps{ m_RVDescriptorHeap.getDescriptorHeap(), m_samplerDescriptorHeap.getDescriptorHeap() };
+    computeCommandList->SetDescriptorHeaps(uint32_t(pHeaps.size()), pHeaps.data());
+    std::vector<uint32_t> dispatch;
+    if (m_ui.EnableNVScaler) {
+        if (m_currentScale != 100) {
+            dispatch = m_NVScaler.getDispatchDim();
+            computeCommandList->SetComputeRootSignature(m_NVScaler.getRootSignature());
+            computeCommandList->SetComputeRootDescriptorTable(0, m_RVDescriptorHeap.getGPUDescriptorHandle(iCB + 1));  // ConstantBuffer config
+            computeCommandList->SetComputeRootDescriptorTable(4, m_RVDescriptorHeap.getGPUDescriptorHandle(iSRV + 1)); // coef_scaler
+            computeCommandList->SetComputeRootDescriptorTable(5, m_RVDescriptorHeap.getGPUDescriptorHandle(iSRV + 2)); // coef_USM
+            computeCommandList->SetPipelineState(m_NVScaler.getComputePSO());
+        }
+        else
+        {
+            dispatch = m_NVSharpen.getDispatchDim();
+            computeCommandList->SetComputeRootSignature(m_NVSharpen.getRootSignature());
+            computeCommandList->SetComputeRootDescriptorTable(0, m_RVDescriptorHeap.getGPUDescriptorHandle(iCB + 2)); // ConstantBuffer config
+            computeCommandList->SetPipelineState(m_NVSharpen.getComputePSO());
+        }
+    }
+    else {
+        dispatch = m_upscale.getDispatchDim();
+        computeCommandList->SetComputeRootSignature(m_upscale.getRootSignature());
+        computeCommandList->SetComputeRootDescriptorTable(0, m_RVDescriptorHeap.getGPUDescriptorHandle(iCB));    // ConstantBuffer config
+        computeCommandList->SetPipelineState(m_upscale.getComputePSO());
+
+    }
+    computeCommandList->SetComputeRootDescriptorTable(1, m_samplerDescriptorHeap.getGPUDescriptorHandle(0));   // sampler
+    computeCommandList->SetComputeRootDescriptorTable(2, m_RVDescriptorHeap.getGPUDescriptorHandle(iSRV));     // input
+    computeCommandList->SetComputeRootDescriptorTable(3, m_RVDescriptorHeap.getGPUDescriptorHandle(iUAV));     // output
+    m_deviceResources.StartComputeTimer();
+    computeCommandList->Dispatch(dispatch[0], dispatch[1], dispatch[2]);
+    m_deviceResources.StopComputeTimer();
+    m_deviceResources.ResolveComputeTimerQuery();
+    if (m_saveOutput) {
+        scheduleCopyOutput();
+        m_saveReadBack = true;
+    }
+    computeCommandList->Close();
+    m_deviceResources.CopyToRenderTarget(m_output.Get());
+    m_deviceResources.m_output = m_output.Get();
+}
+
+void AppRenderer::saveOutput(const std::string& filename)
+{
+    m_saveOutput = true;
+    m_saveFileName = filename;
+}
+
+void AppRenderer::saveOutputToFile()
+{
+    D3D12_RESOURCE_DESC desc = m_output->GetDesc();
+    img::Fmt format = img::Fmt::R8G8B8A8;
+
+    switch (desc.Format)
+    {
+    case DXGI_FORMAT_R8G8B8A8_UNORM:
+        format = img::Fmt::R8G8B8A8;
+        break;
+    case DXGI_FORMAT_R32G32B32A32_FLOAT:
+        format = img::Fmt::R32G32B32A32;
+        break;
+    case DXGI_FORMAT_R16G16B16A16_FLOAT:
+        format = img::Fmt::R16G16B16A16;
+        break;
+    }
+    std::vector<uint8_t> data;
+    constexpr uint32_t channels = 4;
+    uint32_t imageSize = m_saveRowPitch * m_saveHeight;
+    data.resize(imageSize);
+    uint8_t* mappedData = nullptr;
+    m_outputReadBack->Map(0, nullptr, reinterpret_cast<void**>(&mappedData));
+    memcpy(data.data(), mappedData, imageSize);
+    m_outputReadBack->Unmap(0, nullptr);
+    img::save(m_saveFileName, data.data(), m_saveWidth, m_saveHeight, channels, m_saveRowPitch, format);
+}
+
+void AppRenderer::scheduleCopyOutput()
+{
+    static std::unordered_map<DXGI_FORMAT, uint32_t> Bpp{ {DXGI_FORMAT_R32G32B32A32_FLOAT, 16}, { DXGI_FORMAT_R16G16B16A16_FLOAT, 8}, {DXGI_FORMAT_R8G8B8A8_UNORM, 4} };
+    D3D12_RESOURCE_DESC desc = m_output->GetDesc();
+    if (Bpp.find(desc.Format) == Bpp.end())
+        return;
+    m_saveWidth = uint32_t(desc.Width);
+    m_saveHeight = uint32_t(desc.Height);
+    m_saveRowPitch = Align(m_saveWidth * Bpp[desc.Format], D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
+    m_deviceResources.CreateBuffer(m_saveRowPitch * desc.Height, D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST, &m_outputReadBack);
+    CD3DX12_TEXTURE_COPY_LOCATION src(m_output.Get(), 0);
+    D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = {};
+    footprint.Footprint.Width = m_saveWidth;
+    footprint.Footprint.Height = m_saveHeight;
+    footprint.Footprint.Depth = 1;
+    footprint.Footprint.RowPitch = m_saveRowPitch;
+    footprint.Footprint.Format = desc.Format;
+    CD3DX12_TEXTURE_COPY_LOCATION dst(m_outputReadBack.Get(), footprint);
+    m_deviceResources.computeCommandList()->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
+}

+ 163 - 0
samples/DX12/src/BilinearUpscale.cpp

@@ -0,0 +1,163 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "BilinearUpscale.h"
+#include "DXUtilities.h"
+#include "Utilities.h"
+#include <iostream>
+
+void BilinearUpdateConfig(BilinearUpscaleConfig& config,
+    uint32_t inputViewportOriginX, uint32_t inputViewportOriginY,
+    uint32_t inputViewportWidth, uint32_t inputViewportHeight,
+    uint32_t inputTextureWidth, uint32_t inputTextureHeight,
+    uint32_t outputViewportOriginX, uint32_t outputViewportOriginY,
+    uint32_t outputViewportWidth, uint32_t outputViewportHeight,
+    uint32_t outputTextureWidth, uint32_t outputTextureHeight)
+{
+    config.kInputViewportHeight = inputViewportHeight;
+    config.kInputViewportWidth = inputViewportWidth;
+    config.kOutputViewportHeight = outputViewportHeight;
+    config.kOutputViewportWidth = outputViewportWidth;
+
+    config.kInputViewportOriginX = inputViewportOriginX;
+    config.kInputViewportOriginY = inputViewportOriginY;
+    config.kOutputViewportOriginX = outputViewportOriginX;
+    config.kOutputViewportOriginY = outputViewportOriginY;
+
+    config.kScaleX = inputTextureWidth / float(outputTextureWidth);
+    config.kScaleY = inputTextureWidth / float(outputTextureWidth);
+    config.kDstNormX = 1.f / outputTextureWidth;
+    config.kDstNormY = 1.f / outputTextureHeight;
+    config.kSrcNormX = 1.f / inputTextureWidth;
+    config.kSrcNormY = 1.f / inputTextureHeight;
+}
+
+BilinearUpscale::BilinearUpscale(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths)
+    : m_deviceResources(deviceResources)
+    , m_outputWidth(0)
+    , m_outputHeight(0)
+{
+    std::string shaderName = "bilinearUpscale.hlsl";
+    std::string shaderPath;
+    for (auto& e : shaderPaths)
+    {
+        if (std::filesystem::exists(e + "/" + shaderName))
+        {
+            shaderPath = e + "/" + shaderName;
+            break;
+        }
+    }
+    if (shaderPath.empty())
+        throw std::runtime_error("Shader file not found" + shaderName);
+
+    ComPtr<IDxcLibrary> library;
+    DX::ThrowIfFailed(DxcCreateInstance(CLSID_DxcLibrary, __uuidof(IDxcLibrary), &library));
+    ComPtr<IDxcCompiler> compiler;
+    DX::ThrowIfFailed(DxcCreateInstance(CLSID_DxcCompiler, __uuidof(IDxcCompiler), &compiler));
+    std::wstring wShaderFilename = widen(shaderPath);
+
+    uint32_t codePage = CP_UTF8;
+    ComPtr<IDxcBlobEncoding> sourceBlob;
+    DX::ThrowIfFailed(library->CreateBlobFromFile(wShaderFilename.c_str(), &codePage, &sourceBlob));
+
+    constexpr uint32_t nDefines = 2;
+    std::wstring wBlockWidth = widen(toStr(m_BlockWidth));
+    std::wstring wBlockHeight = widen(toStr(m_BlockHeight));
+    DxcDefine defines[nDefines] = {
+        {L"BLOCK_WIDTH", wBlockWidth.c_str()},
+        {L"BLOCK_HEIGHT", wBlockHeight.c_str()},
+    };
+
+    ComPtr<IDxcOperationResult> result;
+    HRESULT hr = compiler->Compile(sourceBlob.Get(), wShaderFilename.c_str(), L"main", L"cs_6_2", nullptr, 0, defines, nDefines, nullptr, &result);
+    if (SUCCEEDED(hr))
+    {
+        result->GetStatus(&hr);
+    }
+    if (FAILED(hr))
+    {
+        if (result)
+        {
+            ComPtr<IDxcBlobEncoding> errorsBlob;
+            hr = result->GetErrorBuffer(&errorsBlob);
+            if (SUCCEEDED(hr) && errorsBlob)
+            {
+                wprintf(L"Compilation failed with errors:\n%hs\n", (const char*)errorsBlob->GetBufferPointer());
+            }
+        }
+        DX::ThrowIfFailed(hr);
+    }
+    ComPtr<IDxcBlob> computeShaderBlob;
+    result->GetResult(&computeShaderBlob);
+
+    m_deviceResources.CreateBuffer(sizeof(BilinearUpscaleConfig), D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, &m_stagingBuffer);
+    m_deviceResources.CreateBuffer(sizeof(BilinearUpscaleConfig), D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_COMMON, &m_constatBuffer);
+
+    // Define root table layout
+    constexpr uint32_t nParams = 4;
+    CD3DX12_DESCRIPTOR_RANGE descriptorRange[nParams] = {};
+    descriptorRange[0] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
+    descriptorRange[1] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);
+    descriptorRange[2] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
+    descriptorRange[3] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0);
+    CD3DX12_ROOT_PARAMETER m_rootParams[nParams] = {};
+    m_rootParams[0].InitAsDescriptorTable(1, &descriptorRange[0]);
+    m_rootParams[1].InitAsDescriptorTable(1, &descriptorRange[1]);
+    m_rootParams[2].InitAsDescriptorTable(1, &descriptorRange[2]);
+    m_rootParams[3].InitAsDescriptorTable(1, &descriptorRange[3]);
+
+    D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
+    rootSignatureDesc.NumParameters = nParams;
+    rootSignatureDesc.pParameters = m_rootParams;
+    rootSignatureDesc.NumStaticSamplers = 0;
+    rootSignatureDesc.pStaticSamplers = nullptr;
+    rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
+
+    ComPtr<ID3DBlob> serializedSignature;
+    DX::ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &serializedSignature, nullptr));
+
+    // Create the root signature
+    DX::ThrowIfFailed(
+        m_deviceResources.device()->CreateRootSignature(
+            0,
+            serializedSignature->GetBufferPointer(),
+            serializedSignature->GetBufferSize(),
+            __uuidof(ID3D12RootSignature),
+            &m_computeRootSignature));
+    m_computeRootSignature->SetName(L"BilinearUpscale");
+
+    D3D12_COMPUTE_PIPELINE_STATE_DESC descComputePSO = {};
+    descComputePSO.pRootSignature = m_computeRootSignature.Get();
+    descComputePSO.CS.pShaderBytecode = computeShaderBlob->GetBufferPointer();
+    descComputePSO.CS.BytecodeLength = computeShaderBlob->GetBufferSize();
+
+    DX::ThrowIfFailed(
+        m_deviceResources.device()->CreateComputePipelineState(&descComputePSO, __uuidof(ID3D12PipelineState), &m_computePSO));
+    m_computePSO->SetName(L"BilinearUpscale Compute PSO");
+}
+
+void BilinearUpscale::update(uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight)
+{
+    BilinearUpdateConfig(m_config, 0, 0, inputWidth, inputHeight, inputWidth, inputHeight, 0, 0, outputWidth, outputHeight, outputWidth, outputHeight);
+    m_deviceResources.UploadBufferData(&m_config, sizeof(BilinearUpscaleConfig), m_constatBuffer.Get(), m_stagingBuffer.Get());
+    m_outputWidth = outputWidth;
+    m_outputHeight = outputHeight;
+}

+ 328 - 0
samples/DX12/src/DeviceResources.cpp

@@ -0,0 +1,328 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "DeviceResources.h"
+#include "d3dx12.h"
+#include "Utilities.h"
+#include "DXUtilities.h"
+
+
+void GPUTimer::Initialize(DeviceResources* deviceResources) {
+    uint64_t GpuFrequency;
+    deviceResources->commandQueue()->GetTimestampFrequency(&GpuFrequency);
+    m_gpuTickDelta = 1.0 / static_cast<double>(GpuFrequency);
+    deviceResources->CreateBuffer(sizeof(uint64_t) * 2, D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST, &m_readBackBuffer);
+    m_readBackBuffer->SetName(L"GpuTimeStamp Buffer");
+    D3D12_QUERY_HEAP_DESC QueryHeapDesc;
+    QueryHeapDesc.Count = 2;
+    QueryHeapDesc.NodeMask = 1;
+    QueryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
+    deviceResources->device()->CreateQueryHeap(&QueryHeapDesc, __uuidof(ID3D12QueryHeap), &m_queryHeap);
+    m_queryHeap->SetName(L"GpuTimeStamp QueryHeap");
+}
+
+void GPUTimer::ReadBack() {
+    uint64_t* mappedBuffer = nullptr;
+    D3D12_RANGE range{ 0, sizeof(uint64_t) * 2 };
+    m_readBackBuffer->Map(0, &range, reinterpret_cast<void**>(&mappedBuffer));
+    m_timeStart = mappedBuffer[0];
+    m_timeEnd = mappedBuffer[1];
+    m_readBackBuffer->Unmap(0, nullptr);
+    if (m_timeEnd < m_timeStart)
+    {
+        m_timeStart = 0;
+        m_timeEnd = 0;
+    }
+}
+
+void DeviceResources::create(HWND hWnd, uint32_t adapterIdx)
+{
+
+    ComPtr<IDXGIFactory> pFactory;
+    CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pFactory);
+    ComPtr<IDXGIAdapter> pAdapter;
+    if (pFactory->EnumAdapters(adapterIdx, &pAdapter) != DXGI_ERROR_NOT_FOUND)
+    {
+        DXGI_ADAPTER_DESC desc;
+        pAdapter->GetDesc(&desc);
+        char description[256]{};
+        snprintf(description, sizeof(description), "%ls", desc.Description);
+        m_adapter.Description = description;
+        m_adapter.DeviceId = desc.DeviceId;
+        m_adapter.VendorId = desc.VendorId;
+        m_adapter.DedicatedSystemMemory = desc.DedicatedSystemMemory;
+        m_adapter.DedicatedVideoMemory = desc.DedicatedVideoMemory;
+        m_adapter.SharedSystemMemory = desc.SharedSystemMemory;
+    }
+    else
+    {
+        throw std::runtime_error("Adapter not found");
+    }
+
+
+#ifdef DX12_ENABLE_DEBUG_LAYER
+    ComPtr<ID3D12Debug> pdx12Debug = nullptr;
+    if (D3D12GetDebugInterface(__uuidof(ID3D12Debug), &pdx12Debug) == S_OK)
+        pdx12Debug->EnableDebugLayer();
+#endif
+
+    // Create device
+    D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_12_0;
+    HRESULT hr = D3D12CreateDevice(nullptr, featureLevel, __uuidof(ID3D12Device), &m_device);
+    //m_device->SetStablePowerState(true);
+
+    // [DEBUG] Setup debug interface to break on any warnings/errors
+#ifdef DX12_ENABLE_DEBUG_LAYER
+    ComPtr<ID3D12InfoQueue> pInfoQueue;
+    m_device->QueryInterface(__uuidof(ID3D12InfoQueue), &pInfoQueue);
+    pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
+    pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
+    pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, true);
+    pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_INFO, true);
+    pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_MESSAGE, true);
+#endif
+    {
+        // Command Queue
+        D3D12_COMMAND_QUEUE_DESC desc = {};
+        desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+        desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+        desc.NodeMask = 1;
+        DX::ThrowIfFailed(m_device->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), &m_commandQueue));
+    }
+
+    {
+        // Setup swap chain
+        DXGI_SWAP_CHAIN_DESC1 desc;
+        ZeroMemory(&desc, sizeof(DXGI_SWAP_CHAIN_DESC1));
+        desc.BufferCount = NUM_BACK_BUFFERS;
+        desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+        desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
+        desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+        desc.SampleDesc.Count = 1;
+        desc.SampleDesc.Quality = 0;
+        desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
+        desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+        desc.Scaling = DXGI_SCALING_NONE;
+        desc.Stereo = false;
+        ComPtr<IDXGIFactory4> dxgiFactory;
+        ComPtr<IDXGISwapChain1> swapChain1;
+        DX::ThrowIfFailed(CreateDXGIFactory1(__uuidof(IDXGIFactory4), &dxgiFactory));
+        DX::ThrowIfFailed(dxgiFactory->CreateSwapChainForHwnd(m_commandQueue.Get(), hWnd, &desc, nullptr, nullptr, &swapChain1));
+        DX::ThrowIfFailed(swapChain1->QueryInterface(__uuidof(IDXGISwapChain3), &m_swapChain));
+        m_swapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS);
+        m_swapChainWaitableObject = m_swapChain->GetFrameLatencyWaitableObject();
+        m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
+    }
+
+    m_RTVDescHeap.Create(m_device.Get(), D3D12_DESCRIPTOR_HEAP_TYPE_RTV, NUM_BACK_BUFFERS, D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
+    m_SRVDescHeap.Create(m_device.Get(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
+
+    for (UINT i = 0; i < NUM_BACK_BUFFERS; i++)
+    {
+        DX::ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), &m_frameContext[i].m_allocator));
+        DX::ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), &m_frameContext[i].m_computeAllocator));
+    }
+
+    DX::ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_frameContext[0].m_allocator.Get(), nullptr, __uuidof(ID3D12GraphicsCommandList), &m_commandList));
+    DX::ThrowIfFailed(m_commandList->Close());
+
+    DX::ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_frameContext[0].m_computeAllocator.Get(), nullptr, __uuidof(ID3D12CommandList), &m_computeCommandList));
+    m_computeCommandList->Close();
+
+    CreateRenderTarget();
+    m_initialized = true;
+
+    m_timer.Initialize(this);
+}
+
+void DeviceResources::CreateRenderTarget()
+{
+    for (uint32_t i = 0; i < NUM_BACK_BUFFERS; i++)
+    {
+        m_swapChain->GetBuffer(i, __uuidof(ID3D12Resource), &m_RTResource[i]);
+        m_RTResource[i]->SetName(widen("RenderTarget_" + toStr(i)).c_str());
+        m_device->CreateRenderTargetView(m_RTResource[i].Get(), nullptr, m_RTVDescHeap.getCPUDescriptorHandle(i));
+        DX::ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_frameContext[i].m_fence));
+    }
+}
+
+void DeviceResources::ReleaseRenderTarget()
+{
+    for (uint32_t i = 0; i < NUM_BACK_BUFFERS; i++)
+    {
+        m_RTResource[i].Reset();
+        m_frameContext[i].m_fenceValue = 0;
+    }
+}
+
+void DeviceResources::resizeRenderTarget(uint32_t width, uint32_t height)
+{
+    WaitForGPU();
+    ReleaseRenderTarget();
+    DXGI_MODE_DESC desc;
+    desc.Width = width;
+    desc.Height = height;
+    desc.RefreshRate = DXGI_RATIONAL{ 60, 1 };
+    desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+    desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+    desc.Scaling = DXGI_MODE_SCALING_STRETCHED;
+    DX::ThrowIfFailed(m_swapChain->ResizeTarget(&desc));
+    DX::ThrowIfFailed(m_swapChain->ResizeBuffers(NUM_BACK_BUFFERS, width, height, DXGI_FORMAT_R8G8B8A8_UNORM,
+        DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT));
+    CreateRenderTarget();
+    m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
+    m_windowResized = true;
+}
+
+void DeviceResources::WaitForGPU()
+{
+    for (int i = 0; i < NUM_BACK_BUFFERS; i++)
+    {
+        FrameContext* ctx = &m_frameContext[i];
+        uint64_t fenceValueForSignal = ctx->m_fenceValue + 1;
+        m_commandQueue->Signal(ctx->m_fence.Get(), fenceValueForSignal);
+        if (ctx->m_fence.Get()->GetCompletedValue() < fenceValueForSignal)
+        {
+            ctx->m_fence.Get()->SetEventOnCompletion(fenceValueForSignal, m_fenceEvent.Get());
+            WaitForSingleObject(m_fenceEvent.Get(), INFINITE);
+        }
+    }
+}
+
+void DeviceResources::PopulateCommandList()
+{
+    FrameContext* ctx = &m_frameContext[m_frameIndex];
+    DX::ThrowIfFailed(ctx->m_allocator->Reset());
+    m_commandList->Reset(ctx->m_allocator.Get(), nullptr);
+    DX::ThrowIfFailed(ctx->m_computeAllocator->Reset());
+    m_computeCommandList->Reset(ctx->m_computeAllocator.Get(), nullptr);
+
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_RTResource[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
+
+    const float clear_color_with_alpha[4] = { 0.45f, 0.55f, 0.6f, 1.f };
+    m_commandList->ClearRenderTargetView(m_RTVDescHeap.getCPUDescriptorHandle(m_frameIndex), clear_color_with_alpha, 0, nullptr);
+    m_commandList->OMSetRenderTargets(1, &m_RTVDescHeap.getCPUDescriptorHandle(m_frameIndex), false, nullptr);
+    std::vector<ID3D12DescriptorHeap*> pHeaps{ m_SRVDescHeap.getDescriptorHeap() };
+    m_commandList->SetDescriptorHeaps(uint32_t(pHeaps.size()), pHeaps.data());
+}
+
+void DeviceResources::MoveToNextFrame()
+{
+    FrameContext* ctx = &m_frameContext[m_frameIndex];
+    DX::ThrowIfFailed(m_commandQueue->Signal(ctx->m_fence.Get(), ctx->m_fenceValue));
+    m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
+    if (ctx->m_fence->GetCompletedValue() < ctx->m_fenceValue)
+    {
+        DX::ThrowIfFailed(ctx->m_fence->SetEventOnCompletion(ctx->m_fenceValue, m_fenceEvent.Get()));
+        WaitForSingleObjectEx(m_fenceEvent.Get(), INFINITE, false);
+    }
+    ctx->m_fenceValue++;
+}
+
+void DeviceResources::Present(uint32_t SyncInterval, uint32_t Flags)
+{
+    FrameContext* ctx = &m_frameContext[m_frameIndex];
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_RTResource[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
+    ID3D12CommandList* commandList[] = { m_computeCommandList.Get(), m_commandList.Get() };
+    m_commandList->Close();
+    m_commandQueue->ExecuteCommandLists(2, commandList);
+    if (m_windowResized)
+    {
+        m_windowResized = false;
+        WaitForGPU();
+    }
+    else
+    {
+        m_swapChain->Present(SyncInterval, Flags);
+        m_timer.ReadBack();
+    }    
+    MoveToNextFrame();
+}
+
+void DeviceResources::CreateTexture2D(uint32_t width, uint32_t height, DXGI_FORMAT format, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource)
+{
+    auto heapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
+    auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(format, width, height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+    DX::ThrowIfFailed(m_device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, resourceState, nullptr, __uuidof(ID3D12Resource), (void**)pResource));
+}
+
+void DeviceResources::CreateTexture1D(uint32_t width, DXGI_FORMAT format, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource)
+{
+    auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex1D(format, width, 1, 1, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+    auto heapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
+    DX::ThrowIfFailed(m_device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, resourceState, nullptr, __uuidof(ID3D12Resource), (void**)pResource));
+}
+
+void DeviceResources::CreateBuffer(uint32_t size, D3D12_HEAP_TYPE heapType, D3D12_RESOURCE_STATES resourceState, ID3D12Resource** pResource)
+{
+    auto resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(size);
+    auto heapProperties = CD3DX12_HEAP_PROPERTIES(heapType);
+    DX::ThrowIfFailed(m_device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, resourceState, nullptr, __uuidof(ID3D12Resource), (void**)pResource));
+}
+
+void DeviceResources::UploadBufferData(void* data, uint32_t size, ID3D12Resource* pResource, ID3D12Resource* pStagingResource)
+{
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pResource, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST));
+    uint8_t* mappedData = nullptr;
+    pStagingResource->Map(0, nullptr, reinterpret_cast<void**>(&mappedData));
+    memcpy(mappedData, data, size);
+    pStagingResource->Unmap(0, nullptr);
+    m_commandList->CopyBufferRegion(pResource, 0, pStagingResource, 0, size);
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pResource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON));
+}
+
+void DeviceResources::UploadTextureData(void* data, uint32_t size, uint32_t rowPitch, ID3D12Resource* pResource, ID3D12Resource* pStagingResource)
+{
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pResource, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST));
+    uint8_t* mappedData = nullptr;
+    pStagingResource->Map(0, nullptr, reinterpret_cast<void**>(&mappedData));
+    memcpy(mappedData, data, size);
+    pStagingResource->Unmap(0, nullptr);
+    D3D12_RESOURCE_DESC desc = pResource->GetDesc();
+    D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = {};
+    footprint.Footprint.Width = uint32_t(desc.Width);
+    footprint.Footprint.Height = uint32_t(desc.Height);
+    footprint.Footprint.Depth = 1;
+    footprint.Footprint.RowPitch = Align(rowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
+    footprint.Footprint.Format = desc.Format;
+    CD3DX12_TEXTURE_COPY_LOCATION src(pStagingResource, footprint);
+    CD3DX12_TEXTURE_COPY_LOCATION dst(pResource, 0);
+    m_commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pResource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON));
+}
+
+ID3D12Resource* DeviceResources::getRenderTarget()
+{
+    uint32_t backBufferIdx = m_swapChain->GetCurrentBackBufferIndex();
+    return m_RTResource[backBufferIdx].Get();
+}
+
+void DeviceResources::CopyToRenderTarget(ID3D12Resource* pSrc)
+{
+    auto pDst = getRenderTarget();
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pDst, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_DEST));
+    D3D12_RESOURCE_DESC desc = pDst->GetDesc();
+    CD3DX12_TEXTURE_COPY_LOCATION src(pSrc, 0);
+    CD3DX12_TEXTURE_COPY_LOCATION dst(pDst, 0);
+    D3D12_BOX box{ 0, 0, 0, uint32_t(desc.Width), uint32_t(desc.Height), 1 };
+    m_commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, &box);
+    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pDst, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_RENDER_TARGET));
+}

+ 189 - 0
samples/DX12/src/NVScaler.cpp

@@ -0,0 +1,189 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "NVScaler.h"
+
+#include <iostream>
+#include "DXUtilities.h"
+#include "DeviceResources.h"
+#include "Utilities.h"
+#include <DirectXPackedVector.h>
+
+NVScaler::NVScaler(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths)
+    : m_deviceResources(deviceResources)
+    , m_outputWidth(1)
+    , m_outputHeight(1)
+{
+    std::string shaderName = "NIS_Main.hlsl";
+    std::string shaderPath;
+    for (auto& e : shaderPaths)
+    {
+        if (std::filesystem::exists(e + "/" + shaderName))
+        {
+            shaderPath = e + "/" + shaderName;
+            break;
+        }
+    }
+    if (shaderPath.empty())
+        throw std::runtime_error("Shader file not found" + shaderName);
+
+    NISOptimizer opt(true, NISGPUArchitecture::NVIDIA_Generic);
+    m_blockWidth = opt.GetOptimalBlockWidth();
+    m_blockHeight = opt.GetOptimalBlockHeight();
+    uint32_t threadGroupSize = opt.GetOptimalThreadGroupSize();
+
+    std::wstring wNIS_BLOCK_WIDTH = widen(toStr(m_blockWidth));
+    std::wstring wNIS_BLOCK_HEIGHT = widen(toStr(m_blockHeight));
+    std::wstring wNIS_THREAD_GROUP_SIZE = widen(toStr(threadGroupSize));
+    std::wstring wNIS_HDR_MODE = widen(toStr(uint32_t(NISHDRMode::None)));
+    std::vector<DxcDefine> defines{
+        {L"NIS_SCALER", L"1"},
+        {L"NIS_HDR_MODE", wNIS_HDR_MODE.c_str()},
+        {L"NIS_BLOCK_WIDTH", wNIS_BLOCK_WIDTH.c_str()},
+        {L"NIS_BLOCK_HEIGHT", wNIS_BLOCK_HEIGHT.c_str()},
+        {L"NIS_THREAD_GROUP_SIZE", wNIS_THREAD_GROUP_SIZE.c_str()},
+        {L"NIS_USE_HALF_PRECISION", L"1"},
+        {L"NIS_HLSL_6_2", L"1"},
+    };
+
+    ComPtr<IDxcLibrary> library;
+    DX::ThrowIfFailed(DxcCreateInstance(CLSID_DxcLibrary, __uuidof(IDxcLibrary), &library));
+    ComPtr<IDxcCompiler> compiler;
+    DX::ThrowIfFailed(DxcCreateInstance(CLSID_DxcCompiler, __uuidof(IDxcCompiler), &compiler));
+
+    std::wstring wShaderFilename = widen(shaderPath);
+
+    uint32_t codePage = CP_UTF8;
+    ComPtr<IDxcBlobEncoding> sourceBlob;
+    DX::ThrowIfFailed(library->CreateBlobFromFile(wShaderFilename.c_str(), &codePage, &sourceBlob));
+
+    ComPtr<IDxcIncludeHandler> includeHandler;
+    library->CreateIncludeHandler(&includeHandler);
+
+    std::vector<LPCWSTR> args{ L"-O3", L"-enable-16bit-types" };
+    ComPtr<IDxcOperationResult> result;
+    HRESULT hr = compiler->Compile(sourceBlob.Get(), wShaderFilename.c_str(), L"main", L"cs_6_2", args.data(), uint32_t(args.size()),
+        defines.data(), uint32_t(defines.size()), includeHandler.Get(), &result);
+    if (SUCCEEDED(hr))
+        result->GetStatus(&hr);
+    if (FAILED(hr))
+    {
+        if (result)
+        {
+            ComPtr<IDxcBlobEncoding> errorsBlob;
+            hr = result->GetErrorBuffer(&errorsBlob);
+            if (SUCCEEDED(hr) && errorsBlob)
+            {
+                wprintf(L"Compilation failed with errors:\n%hs\n", (const char*)errorsBlob->GetBufferPointer());
+            }
+        }
+        DX::ThrowIfFailed(hr);
+    }
+    ComPtr<IDxcBlob> computeShaderBlob;
+    result->GetResult(&computeShaderBlob);
+
+    m_deviceResources.CreateBuffer(sizeof(NISConfig), D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, &m_stagingBuffer);
+    m_deviceResources.CreateBuffer(sizeof(NISConfig), D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_COMMON, &m_constatBuffer);
+
+    // Define root table layout
+    constexpr uint32_t nParams = 6;
+    CD3DX12_DESCRIPTOR_RANGE descriptorRange[nParams] = {};
+    descriptorRange[0] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
+    descriptorRange[1] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);
+    descriptorRange[2] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
+    descriptorRange[3] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0);
+    descriptorRange[4] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1);
+    descriptorRange[5] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 2);
+    CD3DX12_ROOT_PARAMETER m_rootParams[nParams] = {};
+    m_rootParams[0].InitAsDescriptorTable(1, &descriptorRange[0]);
+    m_rootParams[1].InitAsDescriptorTable(1, &descriptorRange[1]);
+    m_rootParams[2].InitAsDescriptorTable(1, &descriptorRange[2]);
+    m_rootParams[3].InitAsDescriptorTable(1, &descriptorRange[3]);
+    m_rootParams[4].InitAsDescriptorTable(1, &descriptorRange[4]);
+    m_rootParams[5].InitAsDescriptorTable(1, &descriptorRange[5]);
+
+    D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
+    rootSignatureDesc.NumParameters = nParams;
+    rootSignatureDesc.pParameters = m_rootParams;
+    rootSignatureDesc.NumStaticSamplers = 0;
+    rootSignatureDesc.pStaticSamplers = nullptr;
+    rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
+    ComPtr<ID3DBlob> serializedSignature;
+    DX::ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &serializedSignature, nullptr));
+    // Create the root signature
+    DX::ThrowIfFailed(m_deviceResources.device()->CreateRootSignature(0, serializedSignature->GetBufferPointer(), serializedSignature->GetBufferSize(),
+            __uuidof(ID3D12RootSignature), &m_computeRootSignature));
+    m_computeRootSignature->SetName(L"NVScaler");
+    // Create compute pipeline state
+    D3D12_COMPUTE_PIPELINE_STATE_DESC descComputePSO = {};
+    descComputePSO.pRootSignature = m_computeRootSignature.Get();
+    descComputePSO.CS.pShaderBytecode = computeShaderBlob->GetBufferPointer();
+    descComputePSO.CS.BytecodeLength = computeShaderBlob->GetBufferSize();
+
+    DX::ThrowIfFailed(m_deviceResources.device()->CreateComputePipelineState(&descComputePSO, __uuidof(ID3D12PipelineState), &m_computePSO));
+    m_computePSO->SetName(L"NVScaler Compute PSO");
+    // Coefficients assuming DXGI_FORMAT_R32G32B32A32_FLOAT, since filter size = 8, we pack 2 float4 in one row
+    // CopyTextureRegion requires the buffer to be aligned to D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
+    m_rowPitch = kFilterSize * 4;
+    const int rowPitchAligned = Align(m_rowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
+    const int coefSize = rowPitchAligned * kPhaseCount;
+
+    m_deviceResources.CreateBuffer(coefSize, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, &m_coefScalerUpload);
+    m_deviceResources.CreateTexture2D(kFilterSize / 4, kPhaseCount, DXGI_FORMAT_R16G16B16A16_FLOAT, D3D12_RESOURCE_STATE_COMMON, &m_coefScaler);
+
+    m_deviceResources.CreateBuffer(coefSize, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, &m_coefUSMUpload);
+    m_deviceResources.CreateTexture2D(kFilterSize / 4, kPhaseCount, DXGI_FORMAT_R16G16B16A16_FLOAT, D3D12_RESOURCE_STATE_COMMON, &m_coefUSM);
+
+    createAlignedCoefficients((uint16_t*)coef_scale_fp16, m_coefScalerHost, rowPitchAligned);
+    createAlignedCoefficients((uint16_t*)coef_usm_fp16, m_coefUSMHost, rowPitchAligned);
+}
+
+void NVScaler::createAlignedCoefficients(uint16_t* data, std::vector<uint16_t>& coef, uint32_t rowPitchAligned)
+{
+    const int rowElements = rowPitchAligned / sizeof(uint16_t);
+    const int coefSize = rowElements * kPhaseCount;
+    coef.resize(coefSize);
+    for (uint32_t y = 0; y < kPhaseCount; ++y)
+    {
+        for (uint32_t x = 0; x < kFilterSize; ++x) {
+            coef[x + y * uint64_t(rowElements)] = data[x + y * kFilterSize];
+        }
+    }
+}
+
+void NVScaler::uploadCoefficients()
+{
+    m_deviceResources.UploadTextureData((void*)m_coefScalerHost.data(), sizeof(m_coefScalerHost[0]) * uint32_t(m_coefScalerHost.size()),
+        m_rowPitch, m_coefScaler.Get(), m_coefScalerUpload.Get());
+    m_deviceResources.UploadTextureData((void*)m_coefUSMHost.data(), sizeof(m_coefUSMHost[0]) * uint32_t(m_coefUSMHost.size()),
+        m_rowPitch, m_coefUSM.Get(), m_coefUSMUpload.Get());
+}
+
+void NVScaler::update(float sharpness, uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight)
+{
+    NVScalerUpdateConfig(m_config, sharpness,
+        0, 0, inputWidth, inputHeight, inputWidth, inputHeight,
+        0, 0, outputWidth, outputHeight, outputWidth, outputHeight,
+        NISHDRMode::None);
+    m_deviceResources.UploadBufferData(&m_config, sizeof(NISConfig), m_constatBuffer.Get(), m_stagingBuffer.Get());
+    m_outputWidth = outputWidth;
+    m_outputHeight = outputHeight;
+}

+ 148 - 0
samples/DX12/src/NVSharpen.cpp

@@ -0,0 +1,148 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "NVSharpen.h"
+
+#include <iostream>
+#include "DXUtilities.h"
+#include "DeviceResources.h"
+#include "Utilities.h"
+
+
+NVSharpen::NVSharpen(DeviceResources& deviceResources,  const std::vector<std::string>& shaderPaths)
+    : m_deviceResources(deviceResources)
+    , m_outputWidth(1)
+    , m_outputHeight(1)
+{
+    std::string shaderName = "NIS_Main.hlsl";
+    std::string shaderPath;
+    for (auto& e : shaderPaths)
+    {
+        if (std::filesystem::exists(e + "/" + shaderName))
+        {
+            shaderPath = e + "/" + shaderName;
+            break;
+        }
+    }
+    if (shaderPath.empty())
+        throw std::runtime_error("Shader file not found" + shaderName);
+
+    NISOptimizer opt(false, NISGPUArchitecture::NVIDIA_Generic);
+    m_blockWidth = opt.GetOptimalBlockWidth();
+    m_blockHeight = opt.GetOptimalBlockHeight();
+    uint32_t threadGroupSize = opt.GetOptimalThreadGroupSize();
+
+    std::wstring wNIS_BLOCK_WIDTH = widen(toStr(m_blockWidth));
+    std::wstring wNIS_BLOCK_HEIGHT = widen(toStr(m_blockHeight));
+    std::wstring wNIS_THREAD_GROUP_SIZE = widen(toStr(threadGroupSize));
+    std::wstring wNIS_HDR_MODE = widen(toStr(uint32_t(NISHDRMode::None)));
+    std::vector<DxcDefine> defines {
+        {L"NIS_SCALER", L"0"},
+        {L"NIS_HDR_MODE", wNIS_HDR_MODE.c_str()},
+        {L"NIS_USE_HALF_PRECISION", L"1"},
+        {L"NIS_HLSL_6_2", L"1"},
+        {L"NIS_BLOCK_WIDTH", wNIS_BLOCK_WIDTH.c_str()},
+        {L"NIS_BLOCK_HEIGHT", wNIS_BLOCK_WIDTH.c_str()},
+        {L"NIS_THREAD_GROUP_SIZE", wNIS_BLOCK_HEIGHT.c_str()},
+    };
+
+    ComPtr<IDxcLibrary> library;
+    DX::ThrowIfFailed(DxcCreateInstance(CLSID_DxcLibrary, __uuidof(IDxcLibrary), &library));
+    ComPtr<IDxcCompiler> compiler;
+    DX::ThrowIfFailed(DxcCreateInstance(CLSID_DxcCompiler, __uuidof(IDxcCompiler), &compiler));
+    std::wstring wShaderFilename = widen(shaderPath);
+
+    uint32_t codePage = CP_UTF8;
+    ComPtr<IDxcBlobEncoding> sourceBlob;
+    DX::ThrowIfFailed(library->CreateBlobFromFile(wShaderFilename.c_str(), &codePage, &sourceBlob));
+
+    ComPtr<IDxcIncludeHandler> includeHandler;
+    library->CreateIncludeHandler(&includeHandler);
+    std::vector<LPCWSTR> args{ L"-O3", L"-enable-16bit-types" };
+    ComPtr<IDxcOperationResult> result;
+    HRESULT hr = compiler->Compile(sourceBlob.Get(), wShaderFilename.c_str(), L"main", L"cs_6_2", args.data(), uint32_t(args.size()), 
+        defines.data(), uint32_t(defines.size()), includeHandler.Get(), &result);
+    if (SUCCEEDED(hr))
+        result->GetStatus(&hr);
+    if (FAILED(hr))
+    {
+        if (result)
+        {
+            ComPtr<IDxcBlobEncoding> errorsBlob;
+            hr = result->GetErrorBuffer(&errorsBlob);
+            if (SUCCEEDED(hr) && errorsBlob)
+            {
+                wprintf(L"Compilation failed with errors:\n%hs\n", (const char*)errorsBlob->GetBufferPointer());
+            }
+        }
+        DX::ThrowIfFailed(hr);
+    }
+    ComPtr<IDxcBlob> computeShaderBlob;
+    result->GetResult(&computeShaderBlob);
+
+    m_deviceResources.CreateBuffer(sizeof(NISConfig), D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, &m_stagingBuffer);
+    m_deviceResources.CreateBuffer(sizeof(NISConfig), D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_COMMON, &m_constatBuffer);
+
+    constexpr uint32_t nParams = 4;
+    CD3DX12_DESCRIPTOR_RANGE descriptorRange[nParams] = {};
+    descriptorRange[0] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
+    descriptorRange[1] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);
+    descriptorRange[2] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
+    descriptorRange[3] = CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0);
+    CD3DX12_ROOT_PARAMETER m_rootParams[nParams] = {};
+    m_rootParams[0].InitAsDescriptorTable(1, &descriptorRange[0]);
+    m_rootParams[1].InitAsDescriptorTable(1, &descriptorRange[1]);
+    m_rootParams[2].InitAsDescriptorTable(1, &descriptorRange[2]);
+    m_rootParams[3].InitAsDescriptorTable(1, &descriptorRange[3]);
+
+    D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
+    rootSignatureDesc.NumParameters = nParams;
+    rootSignatureDesc.pParameters = m_rootParams;
+    rootSignatureDesc.NumStaticSamplers = 0;
+    rootSignatureDesc.pStaticSamplers = nullptr;
+    rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
+
+    ComPtr<ID3DBlob> serializedSignature;
+    DX::ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &serializedSignature, nullptr));
+
+    // Create the root signature
+    DX::ThrowIfFailed(m_deviceResources.device()->CreateRootSignature(0, serializedSignature->GetBufferPointer(),serializedSignature->GetBufferSize(),
+            __uuidof(ID3D12RootSignature),&m_computeRootSignature));
+    m_computeRootSignature->SetName(L"NVSharpen");
+    // Create compute pipeline state
+    D3D12_COMPUTE_PIPELINE_STATE_DESC descComputePSO = {};
+    descComputePSO.pRootSignature = m_computeRootSignature.Get();
+    descComputePSO.CS.pShaderBytecode = computeShaderBlob->GetBufferPointer();
+    descComputePSO.CS.BytecodeLength = computeShaderBlob->GetBufferSize();
+
+    DX::ThrowIfFailed(m_deviceResources.device()->CreateComputePipelineState(&descComputePSO, __uuidof(ID3D12PipelineState), &m_computePSO));
+    m_computePSO->SetName(L"NVSharpen Compute PSO");
+}
+
+void NVSharpen::update(float sharpness, uint32_t inputWidth, uint32_t inputHeight)
+{
+    NVSharpenUpdateConfig(m_config, sharpness,
+        0, 0, inputWidth, inputHeight, inputWidth, inputHeight,
+        0, 0, NISHDRMode::None);
+    m_deviceResources.UploadBufferData(&m_config, sizeof(NISConfig), m_constatBuffer.Get(), m_stagingBuffer.Get());
+    m_outputWidth = inputWidth;
+    m_outputHeight = inputHeight;
+}

+ 146 - 0
samples/DX12/src/Sample.cpp

@@ -0,0 +1,146 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#pragma comment(lib, "user32")
+#pragma comment(lib, "d3d12")
+#pragma comment(lib, "dxgi")
+#pragma comment(lib, "windowscodecs")
+
+#include <filesystem>
+#include <iostream>
+#include <tchar.h>
+#include <wincodec.h>
+
+#include "AppRenderer.h"
+#include "DeviceResources.h"
+#include "UIRenderer.h"
+#include "Utilities.h"
+
+
+DeviceResources deviceResources;
+UIData uiData;
+
+LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int main(int argc, char* argv[])
+{
+    // Resources
+    std::string mediaFolder = "media/images/";
+    std::string shadersFolder = "NIS/";
+
+    if (!std::filesystem::exists(mediaFolder))
+        mediaFolder = "media/images/";
+    if (!std::filesystem::exists(mediaFolder))
+        mediaFolder = "../../media/images/";
+    if (!std::filesystem::exists(mediaFolder))
+        return -1;
+
+    // UI settings
+    uiData.Files = getFiles(mediaFolder);
+    if (uiData.Files.size() == 0)
+        throw std::runtime_error("No media files");
+    uiData.FileName = uiData.Files[0].filename().string();
+    uiData.FilePath = uiData.Files[0];
+
+    // Create Window
+    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"NVIDIA Image Scaling Demo", nullptr };
+    ::RegisterClassEx(&wc);
+    RECT wr = { 0, 0, 1280, 1080 };
+    AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
+    HWND hwnd = ::CreateWindow(wc.lpszClassName, L"NVIDIA Image Scaling DX12 Demo", WS_OVERLAPPEDWINDOW, 0, 0, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, wc.hInstance, nullptr);
+    ::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX);
+    SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
+
+    // Initialize DX12
+    deviceResources.create(hwnd, 0);
+
+    // Renderers
+    UIRenderer uiRenderer(hwnd, deviceResources, uiData);
+    std::vector<std::string> shaderPaths{ "NIS/", "../../../NIS/", "../../DX12/src/" };
+    AppRenderer appRenderer(deviceResources, uiData, shaderPaths);
+
+    // Show the window
+    ::ShowWindow(hwnd, SW_SHOWDEFAULT);
+    ::UpdateWindow(hwnd);
+
+    FPS m_fps;
+
+    MSG msg{};
+    while (msg.message != WM_QUIT)
+    {
+        if (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE))
+        {
+            // press 's' to dump png file
+            if (msg.message == WM_KEYDOWN && msg.wParam == 'S')
+            {
+                appRenderer.saveOutput("dump.png");
+            }
+            ::TranslateMessage(&msg);
+            ::DispatchMessage(&msg);
+        }
+        m_fps.update();
+        bool update = false;
+        if (appRenderer.updateSize())
+        {
+            deviceResources.resizeRenderTarget(appRenderer.width(), appRenderer.height());
+        }
+        deviceResources.PopulateCommandList();
+        uiRenderer.update(m_fps.fps());
+        appRenderer.update();
+        appRenderer.render();
+        uiRenderer.render();
+        deviceResources.Present(uiData.EnableVsync, 0);
+    }
+    deviceResources.WaitForGPU();
+    uiRenderer.cleanUp();
+
+    ::DestroyWindow(hwnd);
+    ::UnregisterClass(wc.lpszClassName, wc.hInstance);
+
+    return 0;
+}
+
+// Forward declare message handler from imgui_impl_win32.cpp
+extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// Win32 message handler
+LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
+        return true;
+
+    switch (msg)
+    {
+    case WM_SYSCOMMAND:
+        if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
+            return 0;
+        break;
+    case WM_KEYUP:
+    case WM_SYSKEYUP:
+        if (wParam == VK_F1)
+            uiData.ShowSettings = !uiData.ShowSettings;
+        break;
+    case WM_CLOSE:
+    case WM_DESTROY:
+        ::PostQuitMessage(0);
+        return 0;
+    }
+    return ::DefWindowProc(hWnd, msg, wParam, lParam);
+}

+ 198 - 0
samples/DX12/src/UIRenderer.cpp

@@ -0,0 +1,198 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include <UIRenderer.h>
+
+UIRenderer::UIRenderer(HWND hwnd, DeviceResources& deviceResources, UIData& ui)
+: m_ui(ui)
+, m_deviceResources(deviceResources)
+{
+    IMGUI_CHECKVERSION();
+    ImGui::CreateContext();
+    ImGuiIO& io = ImGui::GetIO(); (void)io;
+
+    ImGui::StyleColorsDark();
+    ImGui::GetStyle().WindowRounding = 6;
+    ImGui::GetStyle().FrameBorderSize = 1;
+
+    ImGui_ImplWin32_Init(hwnd);
+    ImGui_ImplDX12_Init(m_deviceResources.device(), 3,
+        DXGI_FORMAT_R8G8B8A8_UNORM, m_deviceResources.SRVDescHeap(),
+        m_deviceResources.SRVDescHeap()->GetCPUDescriptorHandleForHeapStart(),
+        m_deviceResources.SRVDescHeap()->GetGPUDescriptorHandleForHeapStart());
+}
+
+void UIRenderer::cleanUp()
+{
+    // Cleanup
+    ImGui_ImplDX12_Shutdown();
+    ImGui_ImplWin32_Shutdown();
+    ImGui::DestroyContext();
+}
+
+void UIRenderer::update(double fps)
+{
+    m_elapsedTimer.start();
+    ImGui_ImplDX12_NewFrame();
+    ImGui_ImplWin32_NewFrame();
+    ImGui::NewFrame();
+    if (m_ui.ShowSettings)
+    {
+        ImGui::Begin("Settings", 0, ImGuiWindowFlags_AlwaysAutoResize);
+        if (ImGui::CollapsingHeader("GPU Info", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            Adapter adapter = m_deviceResources.adapter();
+            ImGui::Text("Description: %s", adapter.Description.c_str());
+            ImGui::Text("VendorID: 0x%x DeviceID: 0x%x", adapter.VendorId, adapter.DeviceId);
+            ImGui::Text("DedicatedSystemMemory: %d [MB]", adapter.DedicatedVideoMemory / 1024 / 1024);
+            ImGui::Text("SharedSystemMemory   : %d [MB]", adapter.SharedSystemMemory / 1024 / 1024);
+        }
+        if (ImGui::CollapsingHeader("Images", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            if (ImGui::BeginCombo("Filename", m_ui.FileName.c_str()))
+            {
+                for (auto& e : m_ui.Files)
+                {
+                    bool is_selected = (m_ui.FileName == e.filename().string());
+                    if (ImGui::Selectable(e.filename().string().c_str(), is_selected))
+                    {
+                        m_ui.FileName = e.filename().string();
+                        m_ui.FilePath = e;
+                    }
+                    if (is_selected)
+                    {
+                        ImGui::SetItemDefaultFocus();
+                    }
+                }
+                ImGui::EndCombo();
+            }
+        }
+        if (ImGui::CollapsingHeader("Filter", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            ImGui::RadioButton("NVScaler", &m_ui.FilterMode, 0); ImGui::SameLine();
+            ImGui::RadioButton("Bilinear", &m_ui.FilterMode, 2); ImGui::SameLine();
+            ImGui::RadioButton("NVSharpen", &m_ui.FilterMode, 1);
+            ;
+            ImGui::Separator();
+            if (m_ui.FilterMode == 0 || m_ui.FilterMode == 1)
+            {
+                m_ui.EnableNVScaler = true;
+                ImGui::SliderFloat("Sharpness (0% - 100%)", &m_ui.Sharpness, 0, 100, "%2.1f%%");
+            }
+            else
+            {
+                m_ui.EnableNVScaler = false;
+            }
+            if (m_ui.FilterMode == 0 || m_ui.FilterMode == 2)
+            {
+                ImGui::Separator();
+                std::vector<const char*> outputSizes = { "Variable", "1920x1080", "2560x1440", "3840x2160" };
+                ImGui::Combo("Height Size", (int*)&m_ui.OutputMode, outputSizes.data(), int(outputSizes.size()));
+                float fixScaleSize = 0;
+                switch (m_ui.OutputMode) {
+                case OutputSizeMode::VARIABLE:
+                    ImGui::SliderFloat("Scale (50% - 100%)", &m_ui.Scale, 50, 100, "%2.1f%%");
+                    break;
+                case OutputSizeMode::P1080:
+                    fixScaleSize = 1080.f;
+                    break;
+                case OutputSizeMode::P1440:
+                    fixScaleSize = 1440.f;
+                    break;
+                case OutputSizeMode::P2160:
+                    fixScaleSize = 2160.f;
+                    break;
+                }
+                if (fixScaleSize > 0)
+                {
+                    m_ui.Scale = std::min<float>(100.f, std::max<float>(50.f, m_ui.InputHeight / fixScaleSize * 100.f));
+                    ImGui::Text("Fix Scale : %2.1f%%", m_ui.Scale);
+                }
+            }
+            else
+            {
+                m_ui.Scale = 100;
+            }
+            ImGui::Separator();
+            if (m_ui.Scale == 100)
+            {
+                if (m_ui.EnableNVScaler)
+                {
+                    ImGui::Text("Using NVSharpen shader:");
+                    ImGui::Text("Scale 100 %% performs only sharpening");
+                }
+                else
+                {
+                    ImGui::Text("Using CopyResource");
+                }
+            }
+            else
+            {
+                if (m_ui.EnableNVScaler)
+                {
+                    ImGui::Text("Using NVScaler shader:");
+                    ImGui::Text("Performs scaling and sharpening");
+                }
+                else
+                {
+                    ImGui::Text("Using bilinear upscale shader");
+                }
+            }
+            ImGui::Separator();
+            ImGui::Text("Input Size  : %d x %d", m_ui.InputWidth, m_ui.InputHeight);
+            ImGui::Text("Output Size : %d x %d", m_ui.OutputWidth, m_ui.OutputHeight);
+        }
+        if (ImGui::CollapsingHeader("Display", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            ImGui::Checkbox("VSync", &m_ui.EnableVsync);
+        }
+        if (ImGui::CollapsingHeader("Profiling", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            ImGui::RadioButton("microseconds", &m_ui.UnitMicroseconds, 1); ImGui::SameLine();
+            ImGui::RadioButton("milliseconds", &m_ui.UnitMicroseconds, 0);
+            ImGui::Separator();
+            double unitConst = 1E6;
+            std::string unitStr = "us";
+            if (!m_ui.UnitMicroseconds)
+            {
+                unitConst = 1E3;
+                unitStr = "ms";
+            }
+            double filterTime = m_deviceResources.GetTime_us() / 1E6 * unitConst;
+            double totalTime = 1. / fps * unitConst;
+            double uiTime = m_elapsedTimer.averageTime_us() / 1E6 * unitConst;
+            ImGui::Text("FPS         : %9.2f", fps);
+            ImGui::Text("Filter Time : %9.2f %s", filterTime, unitStr.c_str());
+            ImGui::Text("UI Time     : %9.2f %s", uiTime, unitStr.c_str());
+            ImGui::Text("Presnt Time : %9.2f %s", totalTime - filterTime - uiTime, unitStr.c_str());
+            ImGui::Text("Total Time  : %9.2f %s", totalTime, unitStr.c_str());
+        }
+
+        ImGui::End();
+    }
+    ImGui::Render();
+    m_elapsedTimer.end();
+}
+
+void UIRenderer::render()
+{
+    ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), m_deviceResources.commandList());
+}

+ 62 - 0
samples/DX12/src/bilinearUpscale.hlsl

@@ -0,0 +1,62 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef BLOCK_WIDTH
+#define BLOCK_WIDTH 16
+#endif
+
+#ifndef BLOCK_HEIGHT
+#define BLOCK_HEIGHT 16
+#endif
+
+SamplerState  samplerLinearClamp : register(s0);
+cbuffer cb : register(b0) {
+    uint     kInputViewportOriginX;
+    uint     kInputViewportOriginY;
+    uint     kInputViewportWidth;
+    uint     kInputViewportHeight;
+    uint     kOutputViewportOriginX;
+    uint     kOutputViewportOriginY;
+    uint     kOutputViewportWidth;
+    uint     kOutputViewportHeight;
+    float    kScaleX;
+    float    kScaleY;
+    float    kDstNormX;
+    float    kDstNormY;
+    float    kSrcNormX;
+    float    kSrcNormY;
+}
+Texture2D                 in_texture   : register(t0); // image srv
+RWTexture2D<unorm float4> out_texture  : register(u0); // working uav
+
+
+[numthreads(BLOCK_WIDTH, BLOCK_HEIGHT, 1)]
+void main(uint3 id : SV_DispatchThreadID) {
+    float dX = (id.x + 0.5f) * kScaleX;
+    float dY = (id.y + 0.5f) * kScaleY;
+    if (id.x < kOutputViewportWidth && id.y < kOutputViewportHeight && dX < kInputViewportWidth && dY < kInputViewportHeight) {
+        float uvX = (dX + kInputViewportOriginX) * kSrcNormX;
+        float uvY = (dY + kInputViewportOriginY) * kSrcNormY;
+        uint dstX = id.x + kOutputViewportOriginX;
+        uint dstY = id.y + kOutputViewportOriginY;
+        out_texture[uint2(dstX, dstY)] = in_texture.SampleLevel(samplerLinearClamp, float2(uvX, uvY), 0);
+    }
+}

+ 9 - 0
samples/DX12/src/dpi.manifest

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+  <asmv3:application>
+    <asmv3:windowsSettings>
+      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
+    </asmv3:windowsSettings>
+  </asmv3:application>
+</assembly>

+ 109 - 0
samples/VK/CMakeLists.txt

@@ -0,0 +1,109 @@
+project(vk_sample)
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin/VK/)
+
+find_program(Vulkan_NIS_GLSLC_EXECUTABLE
+    NAMES glslc
+    HINTS
+      "$ENV{VULKAN_SDK}/bin"
+)
+find_program(Vulkan_NIS_DXC_EXECUTABLE
+    NAMES dxc
+    HINTS
+      "$ENV{VULKAN_SDK}/bin"
+)
+
+set(IMGUI_SRC     "${IMGUI_PATH}/backends/imgui_impl_vulkan.cpp"
+                  "${IMGUI_PATH}/backends/imgui_impl_glfw.cpp"
+                  "${IMGUI_PATH}/imgui.cpp"
+                  "${IMGUI_PATH}/imgui_demo.cpp"
+                  "${IMGUI_PATH}/imgui_draw.cpp"
+                  "${IMGUI_PATH}/imgui_tables.cpp"
+                  "${IMGUI_PATH}/imgui_widgets.cpp"
+)
+
+set(TINYEXR_PATH    "${CMAKE_SOURCE_DIR}/third_party/tinyexr/")
+set(TINYEXR_INCLUDE "${TINYEXR_PATH}" "${TINYEXR_PATH}/deps/miniz")
+set(TINYEXR_SRC     "${TINYEXR_PATH}/deps/miniz/miniz.c")
+
+set(STB_PATH     "${CMAKE_SOURCE_DIR}/third_party/stb/")
+set(STB_INCLUDE  "${STB_PATH}")
+
+set(SAMPLE_SRC      "src/AppRenderer.cpp"
+                    "src/DeviceResources.cpp"
+                    "src/NVScaler.cpp"
+                    "src/NVSharpen.cpp"
+                    "src/Sample.cpp"
+                    "${COMMON_PATH}/Image.cpp"
+                    "src/UIRenderer.cpp"
+
+)
+
+set(SAMPLE_HEADERS  "include/AppRenderer.h"
+                    "include/DeviceResources.h"
+                    "include/NVScaler.h"
+                    "include/NVSharpen.h"
+                    "include/UIRenderer.h"
+                    "include/VKUtilities.h"
+                    "${COMMON_PATH}/Utilities.h"
+)
+
+add_definitions(-DNIS_VK_SAMPLE -DNIS_DXC)
+
+source_group("external" FILES ${IMGUI_SRC} ${TINYEXR_SRC})
+source_group("shaders" FILES ${SAMPLE_SHADERS})
+
+add_executable(${PROJECT_NAME} ${SAMPLE_SRC} ${IMGUI_SRC} ${TINYEXR_SRC} ${SAMPLE_HEADERS} ${SPIRV_BLOB_SCALER}
+               ${SPIRV_BLOB_SHARPEN} ${SPIRV_BLOB_SCALER_GLSL} ${SPIRV_BLOB_SHARPEN_GLSL})
+target_include_directories (${PROJECT_NAME} PUBLIC include ${IMGUI_INCLUDE} ${TINYEXR_INCLUDE} ${STB_INCLUDE} ${COMMON_PATH} ${NIS_PATH})
+target_link_libraries(${PROJECT_NAME} LINK_PUBLIC glfw Vulkan::Vulkan)
+
+set(SAMPLE_SHADERS  "${NIS_PATH}/NIS_Main.hlsl")
+set(DXC_ARGS_HLSL -spirv -T cs_6_2 -D NIS_DXC=1 -DNIS_USE_HALF_PRECISION=1 -D NIS_BLOCK_WIDTH=32 -D NIS_THREAD_GROUP_SIZE=256)
+set(SPIRV_BLOB_SCALER "nis_scaler.spv")
+add_custom_command(
+    TARGET ${PROJECT_NAME} POST_BUILD
+    # OUTPUT ${SPIRV_BLOB_SCALER}
+    COMMAND ${Vulkan_NIS_DXC_EXECUTABLE} -D NIS_SCALER=1 -D NIS_BLOCK_HEIGHT=24 ${DXC_ARGS_HLSL} -Fo ${SPIRV_BLOB_SCALER} ${SAMPLE_SHADERS}
+    DEPENDS ${SAMPLE_SHADERS}
+)
+set(SPIRV_BLOB_SHARPEN "nis_sharpen.spv")
+add_custom_command(
+    TARGET ${PROJECT_NAME} POST_BUILD
+    # OUTPUT ${SPIRV_BLOB_SHARPEN}
+    COMMAND ${Vulkan_NIS_DXC_EXECUTABLE} -D NIS_SCALER=0 -D NIS_BLOCK_HEIGHT=32 ${DXC_ARGS_HLSL} -Fo ${SPIRV_BLOB_SHARPEN} ${SAMPLE_SHADERS}
+    DEPENDS ${SAMPLE_SHADERS}
+)
+
+set(SAMPLE_SHADERS_GLSL  "${NIS_PATH}/NIS_Main.glsl")
+set(SPIRV_BLOB_SCALER_GLSL "nis_scaler_glsl.spv")
+set(GLSLC_ARGS -x glsl -DNIS_BLOCK_WIDTH=32 -DNIS_THREAD_GROUP_SIZE=256 -DNIS_USE_HALF_PRECISION=1 -DNIS_GLSL=1 -fshader-stage=comp)
+add_custom_command(
+    TARGET ${PROJECT_NAME} POST_BUILD
+    # OUTPUT ${SPIRV_BLOB_SCALER_GLSL}
+    COMMAND ${Vulkan_NIS_GLSLC_EXECUTABLE} -DNIS_SCALER=1 -DNIS_BLOCK_HEIGHT=24 ${GLSLC_ARGS} -o ${SPIRV_BLOB_SCALER_GLSL} ${SAMPLE_SHADERS_GLSL}
+    DEPENDS ${SAMPLE_SHADERS_GLSL}
+)
+set(SPIRV_BLOB_SHARPEN_GLSL "nis_sharpen_glsl.spv")
+add_custom_command(
+    TARGET ${PROJECT_NAME} POST_BUILD
+    # OUTPUT ${SPIRV_BLOB_SHARPEN_GLSL}
+    COMMAND ${Vulkan_NIS_GLSLC_EXECUTABLE} -DNIS_SCALER=0 -DNIS_BLOCK_HEIGHT=32 ${GLSLC_ARGS} -o ${SPIRV_BLOB_SHARPEN_GLSL} ${SAMPLE_SHADERS_GLSL}
+    DEPENDS ${SAMPLE_SHADERS_GLSL}
+)
+
+add_custom_command(
+  TARGET ${PROJECT_NAME} POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+  COMMAND ${CMAKE_COMMAND} -E copy_directory ${NIS_PATH} $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different "nis_scaler.spv" $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different "nis_sharpen.spv" $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different "nis_scaler_glsl.spv" $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different "nis_sharpen_glsl.spv" $<TARGET_FILE_DIR:${PROJECT_NAME}>/NIS
+)
+
+add_custom_command(
+  TARGET ${PROJECT_NAME} POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/media/images
+  COMMAND ${CMAKE_COMMAND} -E copy_directory ${SAMPLES_PATH}/media/images $<TARGET_FILE_DIR:${PROJECT_NAME}>/media/images
+)

+ 77 - 0
samples/VK/include/AppRenderer.h

@@ -0,0 +1,77 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+#include "DeviceResources.h"
+#include "NVScaler.h"
+#include "NVSharpen.h"
+#include "UIRenderer.h"
+#include "Image.h"
+
+
+class AppRenderer
+{
+public:
+    AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::vector<std::string>& shaderPaths, bool glsl);
+    bool update();
+    void render();
+    void present();
+    void cleanUp();
+    uint32_t width() { return m_outputWidth; }
+    uint32_t height() { return m_outputHeight; }
+private:
+    void blitInputToTemp();
+    void blitCopyToRenderTarget();
+
+    UIData&                             m_ui;
+    DeviceResources&                    m_deviceResources;
+    NVSharpen							m_NVSharpen;
+    NVScaler							m_NVScaler;
+    uint32_t							m_inputWidth = 0;
+    uint32_t							m_inputHeight = 0;
+    uint32_t							m_outputWidth = 0;
+    uint32_t							m_outputHeight = 0;
+    VkImage				                m_input = VK_NULL_HANDLE;
+    VkDeviceMemory                      m_inputDeviceMemory;
+    VkImageView	                        m_inputSRV;
+
+    std::vector<uint8_t>                m_image;
+    uint32_t                            m_rowPitch;
+    std::filesystem::path				m_currentFilePath;
+
+    VkImage				                m_temp = VK_NULL_HANDLE;
+    VkDeviceMemory                      m_tempDeviceMemory;
+    VkImageView	                        m_tempSRV;
+
+    uint32_t                            m_currentOutputWidth;
+    uint32_t                            m_currentOutputHeight;
+    float							    m_currentScale = 100;
+    float   							m_currentSharpness = 0;
+    bool                                m_updateWindowSize = false;
+    bool                                m_updateSharpness = false;
+    bool                                m_uploadCoefficients = true;
+    bool                                m_init = false;
+};

+ 153 - 0
samples/VK/include/DeviceResources.h

@@ -0,0 +1,153 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#if defined(_WIN32)
+#define VK_USE_PLATFORM_WIN32_KHR
+#endif // _WIN32
+
+#define GLFW_INCLUDE_VULKAN
+#include <GLFW/glfw3.h>
+#include <imgui_impl_vulkan.h>
+
+#include <stdio.h>
+#include <cstdint>
+#include <cassert>
+#include <vector>
+
+#define IMGUI_VK_HELPERS
+
+#define VK_OK(exp) \
+    { \
+        const auto _result = (exp); \
+        if (_result != VK_SUCCESS) { \
+            fprintf(stderr, "%s(%d): %d=%s\n", __FUNCTION__, __LINE__, _result, #exp); \
+            assert(0); \
+        } \
+    }
+
+
+#define VK_DIE(reason) \
+    fprintf(stderr, "%s(%d): %s\n", __FUNCTION__, __LINE__, (reason)); \
+    assert(0);
+
+struct PerFrameResources
+{
+    VkCommandPool       commandPool = VK_NULL_HANDLE;
+    VkCommandBuffer     commandBuffer = VK_NULL_HANDLE;
+    VkFence             fence = VK_NULL_HANDLE;
+    VkImage             backbuffer = VK_NULL_HANDLE;
+    VkImageView         backbufferView = VK_NULL_HANDLE;
+    VkFramebuffer       framebuffer = VK_NULL_HANDLE;
+};
+
+struct FrameSync
+{
+    VkSemaphore         imageAcquired = VK_NULL_HANDLE;
+    VkSemaphore         renderComplete = VK_NULL_HANDLE;
+};
+
+class DeviceResources
+{
+public:
+    static const VkFormat SwapchainFormat;
+    static const VkColorSpaceKHR SwapchainColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
+    static const uint32_t NumQueryValues = 2;
+
+    void create(GLFWwindow* hWnd);
+    void cleanUp();
+    void update();
+    void beginRender();
+    void resizeRenderTarget(uint32_t Width, uint32_t Height);
+    void clearRenderTargetView(const float color[4]) {}
+    void present(uint32_t SyncInterval, uint32_t Flags);
+
+    VkInstance instance() { return m_instance; }
+    VkPhysicalDevice physicalDevice() { return m_physicalDevice; }
+    VkDevice logicalDevice() { return m_device; }
+    VkQueue queue() { return m_queue; }
+    VkDescriptorPool descriptorPool() { return m_descriptorPool; }
+    VkSampler* sampler() { return &m_sampler; }
+    VkRenderPass UIrenderPass() { return m_renderPass; }
+    VkFramebuffer UIframeBuffer() { return currentFrame()->framebuffer; }
+    uint32_t numSwapchainImages() { return static_cast<uint32_t>(m_frames.size()); }
+    uint32_t swapchainIndex() { return m_frameIndex; }
+    VkCommandBuffer commandBuffer() { return currentFrame()->commandBuffer; }
+    VkCommandPool commandPool() { return currentFrame()->commandPool; }
+    VkImage backBuffer() { return currentFrame()->backbuffer; }
+    VkImageView backBufferView() { return currentFrame()->backbufferView; }
+    VkSwapchainKHR swapchain() { return m_swapchain; }
+    VkQueryPool queryPool() { return m_queryPool; }
+
+    bool initialized() const { return m_initialized; }
+
+    void requestSwapChainRebuild() { m_swapChainRebuild = true; }
+    VkCommandBuffer beginOneTimeSubmitCmd();
+    void endOneTimeSubmitCmd();
+
+    void createTexture2D(int w, int h, VkFormat format, const void* data, uint32_t rowPitch, uint32_t imageSize, VkImage* outImage, VkDeviceMemory* outDeviceMemory);
+    void createTexture2D(int w, int h, VkFormat format, VkImage* outImage, VkDeviceMemory* outDeviceMemory);
+    void createSRV(VkImage inputImage, VkFormat format, VkImageView* outSrv);
+    void createConstBuffer(void* initialData, uint32_t size, VkBuffer* outBuffer, VkDeviceMemory* outBuffMem, VkDeviceSize* outOffset);
+    void createBuffer(VkDeviceSize size, VkBufferUsageFlags buffUsage, VkMemoryPropertyFlags memProps, VkBuffer* outBuffer, VkDeviceMemory* outBuffMem);
+
+    uint32_t minImageCount() const { return m_minImageCount; }
+    float timestampPeriod() const { return m_physicalDeviceProperties.limits.timestampPeriod; }
+    uint32_t width() const { return m_width; }
+    uint32_t height() const { return m_height; }
+private:
+    void createSurfaceResources();
+    void destroySurfaceResources();
+    void selectPhysicalDeviceAndQueueFamily();
+    uint32_t findMemoryTypeIndex(uint32_t memoryTypeBits, VkMemoryPropertyFlags memPropFlags);
+    PerFrameResources* currentFrame() { return &m_frames[m_frameIndex]; }
+    VkSemaphore imageAcquired() { return m_semaphores[m_semaphoreIndex].imageAcquired; }
+    VkSemaphore renderComplete() { return m_semaphores[m_semaphoreIndex].renderComplete; }
+
+    GLFWwindow*                         m_window = nullptr;
+    const VkAllocationCallbacks*        m_allocator = nullptr;
+    VkInstance                          m_instance = VK_NULL_HANDLE;
+    VkPhysicalDevice                    m_physicalDevice = VK_NULL_HANDLE;
+    VkPhysicalDeviceProperties          m_physicalDeviceProperties;
+    VkDevice                            m_device = VK_NULL_HANDLE;
+    VkQueue                             m_queue = VK_NULL_HANDLE;
+    VkSurfaceKHR                        m_surface = VK_NULL_HANDLE;
+    int                                 m_queueFamilyIndex = -1;
+    VkSurfaceFormatKHR                  m_surfaceFormat;
+    VkDescriptorPool                    m_descriptorPool = VK_NULL_HANDLE;
+    VkSampler                           m_sampler = VK_NULL_HANDLE;
+    VkQueryPool                         m_queryPool = VK_NULL_HANDLE;
+
+    VkSwapchainKHR                      m_swapchain = VK_NULL_HANDLE;
+    VkRenderPass                        m_renderPass = VK_NULL_HANDLE;
+
+    std::vector<PerFrameResources>      m_frames;
+    std::vector<FrameSync>              m_semaphores;
+    uint32_t                            m_frameIndex = 0; // Index into m_frames
+    uint32_t                            m_semaphoreIndex = 0; // Index into m_semaphores
+
+    uint32_t                            m_minImageCount = 2;
+    uint32_t                            m_width;
+    uint32_t                            m_height;
+    bool                                m_initialized = false;
+    bool                                m_swapChainRebuild = false;
+};

+ 61 - 0
samples/VK/include/NVScaler.h

@@ -0,0 +1,61 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <iostream>
+
+#include "DeviceResources.h"
+#include "Utilities.h"
+#include "NIS_Config.h"
+
+class NVScaler {
+public:
+    NVScaler(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths, bool glsl);
+    void cleanUp();
+    void update(float sharpness, uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight);
+    void dispatch(VkImageView inputSrv, VkImageView outputUav);
+private:
+    DeviceResources&                    m_deviceResources;
+    NISConfig                           m_config;
+
+    VkShaderModule                      m_shaderModule = VK_NULL_HANDLE;
+    VkDescriptorSetLayout               m_descriptorSetLayout = VK_NULL_HANDLE;
+    VkDescriptorSet                     m_descriptorSet = VK_NULL_HANDLE;
+    VkBuffer                            m_buffer = VK_NULL_HANDLE;
+    VkDeviceMemory                      m_constantBufferDeviceMemory = VK_NULL_HANDLE;
+    VkPipelineLayout                    m_pipelineLayout = VK_NULL_HANDLE;
+    VkPipeline                          m_pipeline = VK_NULL_HANDLE;
+    VkImage                             m_coefScale = VK_NULL_HANDLE;
+    VkImage                             m_coefUsm = VK_NULL_HANDLE;
+    VkDeviceMemory                      m_coefScaleDeviceMemory = VK_NULL_HANDLE;
+    VkDeviceMemory                      m_coefUsmDeviceMemory = VK_NULL_HANDLE;
+    VkImageView                         m_coefScaleSrv = VK_NULL_HANDLE;
+    VkImageView                         m_coefUsmSrv = VK_NULL_HANDLE;
+
+    uint8_t*                            m_constantMemory = nullptr;
+    VkDeviceSize                        m_constantBufferStride = 0;
+
+    uint32_t                            m_outputWidth;
+    uint32_t                            m_outputHeight;
+    uint32_t                            m_blockWidth;
+    uint32_t                            m_blockHeight;
+};

+ 55 - 0
samples/VK/include/NVSharpen.h

@@ -0,0 +1,55 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <iostream>
+
+#include "DeviceResources.h"
+#include "Utilities.h"
+#include "NIS_Config.h"
+
+class NVSharpen {
+public:
+    NVSharpen(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths, bool glsl);
+    void update(float sharpness, uint32_t inputWidth, uint32_t inputHeight);
+    void dispatch(VkImageView inputSrv, VkImageView outputUav);
+    void cleanUp();
+private:
+    DeviceResources&                    m_deviceResources;
+    NISConfig                           m_config;
+
+    VkShaderModule                      m_shaderModule = VK_NULL_HANDLE;
+    VkDescriptorSetLayout               m_descriptorSetLayout = VK_NULL_HANDLE;
+    VkPipelineLayout                    m_pipelineLayout = VK_NULL_HANDLE;
+    VkDescriptorSet                     m_descriptorSet = VK_NULL_HANDLE;
+    VkBuffer                            m_buffer = VK_NULL_HANDLE;
+    VkDeviceMemory                      m_constantBufferDeviceMemory = VK_NULL_HANDLE;
+    VkPipeline                          m_pipeline = VK_NULL_HANDLE;
+
+    uint8_t*                            m_constantMemory = nullptr;
+    VkDeviceSize                        m_constantBufferStride = 0;
+
+    uint32_t                            m_outputWidth;
+    uint32_t                            m_outputHeight;
+    uint32_t                            m_blockWidth;
+    uint32_t                            m_blockHeight;
+};

+ 75 - 0
samples/VK/include/UIRenderer.h

@@ -0,0 +1,75 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <iomanip>
+#include <iostream>
+#include <filesystem>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <imgui.h>
+#include <imgui_impl_glfw.h>
+#include <imgui_impl_vulkan.h>
+#include <DeviceResources.h>
+#include "Utilities.h"
+
+enum class OutputSizeMode : uint32_t
+{
+    VARIABLE,
+    P1080,
+    P1440,
+    P2160
+};
+
+struct UIData
+{
+    std::vector<std::filesystem::path> Files;
+    std::filesystem::path FilePath;
+    std::string FileName;
+    float Scale = 75.f;
+    bool EnableNVScaler = true;
+    int FilterMode = 0;
+    float Sharpness = 50.f;
+    bool EnableVsync = false;
+    OutputSizeMode OutputMode = OutputSizeMode::VARIABLE;
+    uint32_t InputWidth;
+    uint32_t InputHeight;
+    uint32_t OutputWidth;
+    uint32_t OutputHeight;
+    double FilterTime;
+    bool ShowSettings = true;
+    int32_t UnitMicroseconds = true;
+};
+
+class UIRenderer
+{
+public:
+    UIRenderer(void* hwnd, DeviceResources& deviceResources, UIData& ui);
+    void cleanUp();
+    void update(double fps);
+    void render();
+private:
+    DeviceResources&	m_deviceResources;
+    UIData&				m_ui;
+    ElapsedTimer		m_elapsedTimer;
+};

+ 67 - 0
samples/VK/include/VKUtilities.h

@@ -0,0 +1,67 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#pragma once
+
+#include <fstream>
+#include <vector>
+
+// With NIS_DXC, bindings are specified in HLSL shader.
+// Otherwise, we adjust bindings at build-time using arguments to dxc.exe
+#ifdef NIS_DXC
+static const uint32_t CB_BINDING = 0;
+static const uint32_t IN_TEX_BINDING = 2;
+static const uint32_t OUT_TEX_BINDING = 3;
+static const uint32_t COEF_SCALAR_BINDING = 4;
+static const uint32_t COEF_USM_BINDING = 5;
+#else
+static const uint32_t CB_BINDING = 0;
+static const uint32_t IN_TEX_BINDING = 3;
+static const uint32_t OUT_TEX_BINDING = 2;
+static const uint32_t COEF_SCALAR_BINDING = 4;
+static const uint32_t COEF_USM_BINDING = 5;
+#endif
+static const VkDescriptorType CB_DESC_TYPE = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+static const VkDescriptorType IN_TEX_DESC_TYPE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+static const VkDescriptorType OUT_TEX_DESC_TYPE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+
+#define VK_COMMON_DESC_LAYOUT(immutableSampler) \
+    { CB_BINDING, CB_DESC_TYPE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, \
+    { 1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, (immutableSampler) }, \
+    { OUT_TEX_BINDING, OUT_TEX_DESC_TYPE, 1, VK_SHADER_STAGE_COMPUTE_BIT }, \
+    { IN_TEX_BINDING, IN_TEX_DESC_TYPE, 1, VK_SHADER_STAGE_COMPUTE_BIT }
+
+// TODO: combine with DXUtilities.h:IncludeHeader::Open()
+inline std::vector<char> readBytes(const std::string& filename)
+{
+    std::ifstream file(filename, std::ios::ate | std::ios::binary);
+    if (!file.is_open())
+    {
+        fprintf(stderr, "Failed to open: %s\n", filename.c_str());
+        assert(0);
+    }
+    const auto sizeBytes = file.tellg();
+    std::vector<char> buffer(sizeBytes);
+    file.seekg(0);
+    file.read(buffer.data(), sizeBytes);
+    file.close();
+    return buffer;
+}

+ 254 - 0
samples/VK/src/AppRenderer.cpp

@@ -0,0 +1,254 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "AppRenderer.h"
+
+#include <array>
+
+AppRenderer::AppRenderer(DeviceResources& deviceResources, UIData& ui, const std::vector<std::string>& shaderPaths, bool glsl)
+    : m_ui(ui)
+    , m_deviceResources(deviceResources)
+    , m_NVSharpen(deviceResources, shaderPaths, glsl)
+    , m_NVScaler(deviceResources, shaderPaths, glsl)
+{}
+
+bool AppRenderer::update()
+{
+    bool updateWindowSize = m_currentFilePath != m_ui.FilePath || m_currentScale != m_ui.Scale;
+    bool updateSharpeness = m_ui.Sharpness != m_currentSharpness;
+    if (updateWindowSize)
+    {
+        if (m_currentFilePath != m_ui.FilePath)
+        {
+            img::load(m_ui.FilePath.string(), m_image, m_inputWidth, m_inputHeight, m_rowPitch, img::Fmt::R8G8B8A8);
+            if (m_input) {
+                vkDestroyImage(m_deviceResources.logicalDevice(), m_input, nullptr);
+                vkFreeMemory(m_deviceResources.logicalDevice(), m_inputDeviceMemory, nullptr);
+                vkDestroyImageView(m_deviceResources.logicalDevice(), m_inputSRV, nullptr);
+            }
+            m_deviceResources.createTexture2D(m_inputWidth, m_inputHeight, DeviceResources::SwapchainFormat, m_image.data(), m_rowPitch, m_rowPitch * m_inputHeight, &m_input, &m_inputDeviceMemory);
+            m_deviceResources.createSRV(m_input, DeviceResources::SwapchainFormat, &m_inputSRV);
+            m_currentFilePath = m_ui.FilePath;
+        }
+
+        if (m_ui.Scale == 100)
+        {
+            m_outputWidth = m_inputWidth;
+            m_outputHeight = m_inputHeight;
+        }
+        else
+        {
+            m_outputWidth = uint32_t(std::ceil(m_inputWidth * 100.f / m_ui.Scale));
+            m_outputHeight = uint32_t(std::ceil(m_inputHeight * 100.f / m_ui.Scale));
+        }
+
+        if (m_temp) {
+            vkDestroyImage(m_deviceResources.logicalDevice(), m_temp, nullptr);
+            vkDestroyImageView(m_deviceResources.logicalDevice(), m_tempSRV, nullptr);
+            vkFreeMemory(m_deviceResources.logicalDevice(), m_tempDeviceMemory, nullptr);
+        }
+        m_deviceResources.createTexture2D(m_outputWidth, m_outputHeight, DeviceResources::SwapchainFormat, &m_temp, &m_tempDeviceMemory);
+        m_deviceResources.createSRV(m_temp, DeviceResources::SwapchainFormat, &m_tempSRV);
+
+        m_currentScale = m_ui.Scale;
+        m_ui.InputWidth = m_inputWidth;
+        m_ui.InputHeight = m_inputHeight;
+        m_ui.OutputWidth = m_outputWidth;
+        m_ui.OutputHeight = m_outputHeight;
+        m_updateWindowSize = true;
+    }
+    if (updateSharpeness) {
+        m_currentSharpness = m_ui.Sharpness;
+    }
+    if (updateSharpeness || updateWindowSize) {
+        m_NVScaler.update(m_currentSharpness / 100.f, m_inputWidth, m_inputHeight, m_outputWidth, m_outputHeight);
+        m_NVSharpen.update(m_currentSharpness / 100.f, m_inputWidth, m_inputHeight);
+    }
+    return updateWindowSize;
+}
+
+void AppRenderer::render()
+{
+    if (m_deviceResources.queryPool() != VK_NULL_HANDLE)
+    {
+        auto cmdBuff = m_deviceResources.commandBuffer();
+        vkCmdResetQueryPool(cmdBuff, m_deviceResources.queryPool(), 0, DeviceResources::NumQueryValues);
+        vkCmdWriteTimestamp(cmdBuff, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_deviceResources.queryPool(), 0);
+    }
+
+    if (!m_ui.EnableNVScaler)
+    {
+        blitInputToTemp();
+    }
+    else
+    {
+        if (m_ui.Scale == 100)
+        {
+            m_NVSharpen.dispatch(m_inputSRV, m_tempSRV);
+        }
+        else
+        {
+            m_NVScaler.dispatch(m_inputSRV, m_tempSRV);
+        }
+    }
+
+    if (m_deviceResources.queryPool() != VK_NULL_HANDLE)
+    {
+        vkCmdWriteTimestamp(m_deviceResources.commandBuffer(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_deviceResources.queryPool(), 1);
+    }
+    blitCopyToRenderTarget();
+}
+
+void AppRenderer::present()
+{
+    if (m_deviceResources.queryPool() != VK_NULL_HANDLE)
+    {
+        VK_OK(vkDeviceWaitIdle(m_deviceResources.logicalDevice()));
+        typedef uint64_t QueryType; // because of VK_QUERY_RESULT_64_BIT
+        const uint32_t numQueryResultInts = 2; // because of VK_QUERY_RESULT_WITH_AVAILABILITY_BIT (an additional word)
+        const auto stride = numQueryResultInts * sizeof(QueryType); // Bytes for single query result and its availability "bit"
+        constexpr auto allQueriesSize = DeviceResources::NumQueryValues * stride;
+        std::array<QueryType, numQueryResultInts * DeviceResources::NumQueryValues> query;
+        VK_OK(vkGetQueryPoolResults(m_deviceResources.logicalDevice(), m_deviceResources.queryPool(), 0, DeviceResources::NumQueryValues, allQueriesSize, query.data(), stride, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
+        const bool checkAvailabilityBits = query[1] != 0 && query[3] != 0;
+        if (checkAvailabilityBits)
+        {
+            const auto topOfPipeTimestamp = query[0]; // "start"
+            const auto bottomOfPipeTimestamp = query[2]; // "end"
+            m_ui.FilterTime = double(bottomOfPipeTimestamp - topOfPipeTimestamp) * m_deviceResources.timestampPeriod() / 1E3; // ns => us
+        }
+    }
+}
+
+void AppRenderer::cleanUp()
+{
+    vkDestroyImageView(m_deviceResources.logicalDevice(), m_inputSRV, nullptr);
+    vkFreeMemory(m_deviceResources.logicalDevice(), m_inputDeviceMemory, nullptr);
+    vkDestroyImage(m_deviceResources.logicalDevice(), m_input, nullptr);
+    m_NVScaler.cleanUp();
+    m_NVSharpen.cleanUp();
+}
+
+void AppRenderer::blitCopyToRenderTarget()
+{
+    // Layout transition source texture for copy
+    {
+        VkImageMemoryBarrier barrier{};
+        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+        barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+        barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+        barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.image = m_temp;
+        barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        barrier.subresourceRange.levelCount = 1;
+        barrier.subresourceRange.layerCount = 1;
+        vkCmdPipelineBarrier(m_deviceResources.commandBuffer(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
+    }
+    // Copy source texture to backbuffer
+    VkImageBlit region{};
+    region.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
+    region.srcOffsets[0] = { 0, 0, 0 };
+    region.srcOffsets[1] = { (int32_t)m_outputWidth, (int32_t)m_outputHeight, 1 };
+    region.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
+    region.dstOffsets[0] = { 0, 0, 0 };
+    region.dstOffsets[1] = { (int32_t)m_deviceResources.width(), (int32_t)m_deviceResources.height(), 1 };
+
+    // Must use vkCmdBlitImage instead of vkCmdCopyImage to handle RGBA to BGRA conversion for backbuffer.  Plus, it can also scale.
+    vkCmdBlitImage(m_deviceResources.commandBuffer(), m_temp,
+        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+        m_deviceResources.backBuffer(),
+        VK_IMAGE_LAYOUT_GENERAL,
+        1, &region, VK_FILTER_LINEAR);
+
+    // Layout transition source texture for shader access
+    {
+        VkImageMemoryBarrier barrier{};
+        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+        barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+        barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+        barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.image = m_input;
+        barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        barrier.subresourceRange.levelCount = 1;
+        barrier.subresourceRange.layerCount = 1;
+        vkCmdPipelineBarrier(m_deviceResources.commandBuffer(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
+    }
+}
+
+
+void AppRenderer::blitInputToTemp()
+{
+    // Layout transition source texture for copy
+    {
+        VkImageMemoryBarrier barrier{};
+        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+        barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+        barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+        barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.image = m_input;
+        barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        barrier.subresourceRange.levelCount = 1;
+        barrier.subresourceRange.layerCount = 1;
+        vkCmdPipelineBarrier(m_deviceResources.commandBuffer(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
+    }
+
+    // Copy source texture to backbuffer
+    VkImageBlit region{};
+    region.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
+    region.srcOffsets[0] = { 0, 0, 0 };
+    region.srcOffsets[1] = { (int32_t)m_inputWidth, (int32_t)m_inputHeight, 1 };
+    region.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
+    region.dstOffsets[0] = { 0, 0, 0 };
+    region.dstOffsets[1] = { (int32_t)m_outputWidth, (int32_t)m_outputHeight, 1 };
+    
+    // Must use vkCmdBlitImage instead of vkCmdCopyImage to handle RGBA to BGRA conversion for backbuffer.  Plus, it can also scale.
+    vkCmdBlitImage(m_deviceResources.commandBuffer(), m_input,
+        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+        m_temp,
+        VK_IMAGE_LAYOUT_GENERAL,
+        1, &region, VK_FILTER_LINEAR);
+
+    // Layout transition source texture for shader access
+    {
+        VkImageMemoryBarrier barrier{};
+        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+        barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+        barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+        barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.image = m_input;
+        barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        barrier.subresourceRange.levelCount = 1;
+        barrier.subresourceRange.layerCount = 1;
+        vkCmdPipelineBarrier(m_deviceResources.commandBuffer(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
+    }
+}

+ 757 - 0
samples/VK/src/DeviceResources.cpp

@@ -0,0 +1,757 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "DeviceResources.h"
+#include <algorithm>
+#include <array>
+#include <vector>
+#include <imgui_impl_vulkan.h>
+
+static void glfw_window_size_callback(GLFWwindow* window, int width, int height)
+{
+    auto devRes = reinterpret_cast<DeviceResources*>(glfwGetWindowUserPointer(window));
+    devRes->resizeRenderTarget(width, height);
+}
+
+const VkFormat DeviceResources::SwapchainFormat = VK_FORMAT_R8G8B8A8_UNORM;
+
+void DeviceResources::create(GLFWwindow* hWnd)
+{
+    m_window = hWnd;
+    assert(glfwGetWindowUserPointer(hWnd) == nullptr);
+
+    uint32_t extensionCount;
+    auto extensions = glfwGetRequiredInstanceExtensions(&extensionCount);
+    if (extensions == nullptr)
+    {
+        VK_DIE("glfwGetRequiredInstanceExtensions");
+    }
+
+    VkInstanceCreateInfo createInfo{};
+    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+    createInfo.enabledExtensionCount = extensionCount;
+    createInfo.ppEnabledExtensionNames = extensions;
+    VK_OK(vkCreateInstance(&createInfo, nullptr, &m_instance));
+
+    selectPhysicalDeviceAndQueueFamily();
+    VkDeviceQueueCreateInfo qCreateInfo{};
+    qCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+    qCreateInfo.queueFamilyIndex = m_queueFamilyIndex;
+    qCreateInfo.queueCount = 1;
+    const float qPriority = 1.f;
+    qCreateInfo.pQueuePriorities = &qPriority;
+
+    VkPhysicalDeviceFeatures physDevFeatures;
+    vkGetPhysicalDeviceFeatures(m_physicalDevice, &physDevFeatures);
+
+    const char* logicalDevExt[] = {
+        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+        VK_KHR_MAINTENANCE2_EXTENSION_NAME, // For VkImageViewUsageCreateInfo
+    };
+    VkDeviceCreateInfo devCreateInfo{};
+    devCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+    devCreateInfo.pQueueCreateInfos = &qCreateInfo;
+    devCreateInfo.queueCreateInfoCount = 1;
+    devCreateInfo.pEnabledFeatures = &physDevFeatures;
+    devCreateInfo.enabledExtensionCount = static_cast<uint32_t>(std::size(logicalDevExt));
+    devCreateInfo.ppEnabledExtensionNames = logicalDevExt;
+
+    VK_OK(vkCreateDevice(m_physicalDevice, &devCreateInfo, nullptr, &m_device));
+    vkGetPhysicalDeviceProperties(m_physicalDevice, &m_physicalDeviceProperties);
+
+    vkGetDeviceQueue(m_device, m_queueFamilyIndex, 0, &m_queue);
+
+    //See: vkCreateWin32SurfaceKHR
+    VK_OK(glfwCreateWindowSurface(m_instance, m_window, nullptr, &m_surface));
+
+    VkBool32 isSurfaceSupported;
+    VK_OK(vkGetPhysicalDeviceSurfaceSupportKHR(m_physicalDevice, m_queueFamilyIndex, m_surface, &isSurfaceSupported));
+    if (isSurfaceSupported != VK_TRUE)
+    {
+        VK_DIE("vkGetPhysicalDeviceSurfaceSupportKHR");
+    }
+
+    m_surfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(m_physicalDevice, m_surface, &SwapchainFormat, 1, SwapchainColorSpace);
+
+    // Imgui needs a descriptor pool.
+    // This is probably excessive, but it's what's in the sample and should cover all our other needs.
+    // https://github.com/ocornut/imgui/wiki/Integrating-with-Vulkan
+    // https://github.com/ocornut/imgui/blob/master/examples/example_glfw_vulkan/main.cpp
+    {
+        const uint32_t POOL_COUNT = 1000;
+
+        VkDescriptorPoolSize pool_sizes[] =
+        {
+            { VK_DESCRIPTOR_TYPE_SAMPLER, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, POOL_COUNT },
+            { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, POOL_COUNT }
+        };
+        constexpr uint32_t NUM_POOLS = static_cast<uint32_t>(std::size(pool_sizes));
+        VkDescriptorPoolCreateInfo pool_info{};
+        pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+        pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+        pool_info.maxSets = POOL_COUNT * NUM_POOLS;
+        pool_info.poolSizeCount = NUM_POOLS;
+        pool_info.pPoolSizes = pool_sizes;
+        VK_OK(vkCreateDescriptorPool(m_device, &pool_info, nullptr, &m_descriptorPool));
+    }
+
+    // Texture sampler
+    {
+        VkSamplerCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+        info.magFilter = VK_FILTER_LINEAR;
+        info.minFilter = VK_FILTER_LINEAR;
+        info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+        info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        info.minLod = -1000;
+        info.maxLod = 1000;
+        info.maxAnisotropy = 1.0f;
+        VK_OK(vkCreateSampler(m_device, &info, nullptr, &m_sampler));
+    }
+
+    if (m_physicalDeviceProperties.limits.timestampComputeAndGraphics)
+    {
+        VkQueryPoolCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+        info.queryType = VK_QUERY_TYPE_TIMESTAMP;
+        info.queryCount = DeviceResources::NumQueryValues;
+        VK_OK(vkCreateQueryPool(m_device, &info, m_allocator, &m_queryPool));
+    }
+
+    int width, height;
+    glfwGetFramebufferSize(m_window, &width, &height);
+    resizeRenderTarget(width, height);
+
+    m_initialized = true;
+    glfwSetWindowUserPointer(m_window, this);
+    glfwSetWindowSizeCallback(m_window, glfw_window_size_callback);
+}
+
+void DeviceResources::createSurfaceResources()
+{
+    destroySurfaceResources();
+
+    // Swapchain
+    {
+        const auto oldSwapchain = m_swapchain;
+
+        VkSurfaceCapabilitiesKHR surfCaps{};
+        VK_OK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_physicalDevice, m_surface, &surfCaps));
+
+        VkSwapchainCreateInfoKHR swapCreateInfo{};
+        swapCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+        swapCreateInfo.surface = m_surface;
+        swapCreateInfo.minImageCount = surfCaps.minImageCount;
+        swapCreateInfo.imageFormat = m_surfaceFormat.format;
+        swapCreateInfo.imageColorSpace = m_surfaceFormat.colorSpace;
+        swapCreateInfo.imageArrayLayers = 1;
+        // `TRANSFER_DST` allows us to blit into the swapchain images
+        // `STORAGE` allows us to bind to compute shader output
+        swapCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
+        swapCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+        swapCreateInfo.preTransform = surfCaps.currentTransform;
+        swapCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+        swapCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
+        swapCreateInfo.clipped = VK_TRUE;
+        swapCreateInfo.oldSwapchain = oldSwapchain;
+
+        if (surfCaps.currentExtent.width != UINT32_MAX)
+        {
+            swapCreateInfo.imageExtent = surfCaps.currentExtent;
+        }
+        else
+        {
+            int width, height;
+            glfwGetFramebufferSize(m_window, &width, &height);
+            swapCreateInfo.imageExtent = {
+                std::clamp<uint32_t>(width, surfCaps.minImageExtent.width, surfCaps.maxImageExtent.width),
+                std::clamp<uint32_t>(height, surfCaps.minImageExtent.height, surfCaps.maxImageExtent.height)
+            };
+        }
+        m_width = swapCreateInfo.imageExtent.width;
+        m_height = swapCreateInfo.imageExtent.height;
+
+
+        VK_OK(vkCreateSwapchainKHR(m_device, &swapCreateInfo, m_allocator, &m_swapchain));
+
+        if (oldSwapchain != VK_NULL_HANDLE)
+        {
+            vkDestroySwapchainKHR(m_device, oldSwapchain, m_allocator);
+        }
+    }
+
+    // Render pass
+    {
+        VkAttachmentDescription colorAttachDesc {};
+        colorAttachDesc.format = m_surfaceFormat.format;
+        colorAttachDesc.samples = VK_SAMPLE_COUNT_1_BIT;
+        // Don't VK_ATTACHMENT_LOAD_OP_CLEAR because this pass is only used for imgui
+        // and compute shader has already populated buffer
+        colorAttachDesc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+        colorAttachDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+        colorAttachDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+        colorAttachDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+        colorAttachDesc.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
+        colorAttachDesc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+        VkAttachmentReference colorRef{};
+        colorRef.attachment = 0;
+        colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+        VkSubpassDescription subpassDesc{};
+        subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+        subpassDesc.colorAttachmentCount = 1;
+        subpassDesc.pColorAttachments = &colorRef;
+        VkSubpassDependency subpassDep{};
+        subpassDep.srcSubpass = VK_SUBPASS_EXTERNAL;
+        subpassDep.dstSubpass = 0;
+        subpassDep.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+        subpassDep.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+        subpassDep.srcAccessMask = 0;
+        subpassDep.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+        VkRenderPassCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+        info.attachmentCount = 1;
+        info.pAttachments = &colorAttachDesc;
+        info.subpassCount = 1;
+        info.pSubpasses = &subpassDesc;
+        info.dependencyCount = 1;
+        info.pDependencies = &subpassDep;
+
+        VK_OK(vkCreateRenderPass(m_device, &info, m_allocator, &m_renderPass));
+    }
+
+    // Swapchain entourage
+    {
+        uint32_t imageCount;
+        VK_OK(vkGetSwapchainImagesKHR(m_device, m_swapchain, &imageCount, nullptr));
+        std::vector<VkImage> swapchainImages(imageCount);
+        VK_OK(vkGetSwapchainImagesKHR(m_device, m_swapchain, &imageCount, swapchainImages.data()));
+        m_frames.resize(imageCount);
+        m_semaphores.resize(imageCount);
+        for (uint32_t i = 0; i < imageCount; ++i)
+        {
+            m_frames[i].backbuffer = swapchainImages[i];
+
+            // Image views
+            {
+                const VkImageViewUsageCreateInfo usageInfo{
+                    VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
+                    nullptr,
+                    VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT
+                };
+                VkImageViewCreateInfo info{};
+                info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+                info.pNext = &usageInfo;
+                info.image = m_frames[i].backbuffer;
+                info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+                info.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
+                info.format = m_surfaceFormat.format;
+                info.subresourceRange.layerCount = 1;
+                info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+                info.subresourceRange.levelCount = 1;
+                VK_OK(vkCreateImageView(m_device, &info, m_allocator, &m_frames[i].backbufferView));
+            }
+
+            // Framebuffers
+            {
+                VkFramebufferCreateInfo info{};
+                info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+                info.renderPass = m_renderPass;
+                info.attachmentCount = 1;
+                info.pAttachments = &m_frames[i].backbufferView;
+                info.width = m_width;
+                info.height = m_height;
+                info.layers = 1;
+                VK_OK(vkCreateFramebuffer(m_device, &info, m_allocator, &m_frames[i].framebuffer));
+            }
+
+            // Command pool
+            {
+                VkCommandPoolCreateInfo info{};
+                info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+                info.queueFamilyIndex = m_queueFamilyIndex;
+                VK_OK(vkCreateCommandPool(m_device, &info, m_allocator, &m_frames[i].commandPool));
+            }
+            {
+                VkCommandBufferAllocateInfo info{};
+                info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+                info.commandPool = m_frames[i].commandPool;
+                info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+                info.commandBufferCount = 1;
+                VK_OK(vkAllocateCommandBuffers(m_device, &info, &m_frames[i].commandBuffer));
+            }
+            {
+                VkFenceCreateInfo info{};
+                info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+                info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
+                VK_OK(vkCreateFence(m_device, &info, m_allocator, &m_frames[i].fence));
+            }
+
+            // Per-frame semaphores
+            {
+                VkSemaphoreCreateInfo info = {};
+                info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+                VK_OK(vkCreateSemaphore(m_device, &info, m_allocator, &m_semaphores[i].imageAcquired));
+                VK_OK(vkCreateSemaphore(m_device, &info, m_allocator, &m_semaphores[i].renderComplete));
+            }
+        }
+    }
+}
+
+void DeviceResources::destroySurfaceResources()
+{
+    VK_OK(vkDeviceWaitIdle(m_device));
+
+    for (auto& frame : m_frames)
+    {
+        vkDestroyFence(m_device, frame.fence, m_allocator);
+        vkFreeCommandBuffers(m_device, frame.commandPool, 1, &frame.commandBuffer);
+        vkDestroyCommandPool(m_device, frame.commandPool, m_allocator);
+        vkDestroyFramebuffer(m_device, frame.framebuffer, m_allocator);
+        vkDestroyImageView(m_device, frame.backbufferView, m_allocator);
+    }
+    m_frames.clear();
+    for (auto& frame : m_semaphores)
+    {
+        vkDestroySemaphore(m_device, frame.imageAcquired, m_allocator);
+        vkDestroySemaphore(m_device, frame.renderComplete, m_allocator);
+    }
+    m_semaphores.clear();
+
+    if (m_renderPass != VK_NULL_HANDLE)
+    {
+        vkDestroyRenderPass(m_device, m_renderPass, m_allocator);
+        m_renderPass = VK_NULL_HANDLE;
+    }
+
+    // NB: swapchain isn't destroyed because this is called from
+    // createSurfaceResources() where we need old swapchain when recreating it
+}
+
+void DeviceResources::cleanUp()
+{
+    m_initialized = false;
+    glfwSetWindowUserPointer(m_window, nullptr);
+
+    destroySurfaceResources();
+
+    vkDestroyQueryPool(m_device, m_queryPool, m_allocator);
+    vkDestroySampler(m_device, m_sampler, m_allocator);
+    vkDestroyDescriptorPool(m_device, m_descriptorPool, m_allocator);
+
+    vkDestroySwapchainKHR(m_device, m_swapchain, m_allocator);
+    vkDestroySurfaceKHR(m_instance, m_surface, m_allocator);
+    vkDestroyDevice(m_device, m_allocator);
+    vkDestroyInstance(m_instance, m_allocator);
+}
+
+void DeviceResources::selectPhysicalDeviceAndQueueFamily()
+{
+    uint32_t deviceCount = 0;
+    VK_OK(vkEnumeratePhysicalDevices(m_instance, &deviceCount, nullptr));
+    if (deviceCount == 0) {
+        VK_DIE("vkEnumeratePhysicalDevices");
+    }
+
+    std::vector<VkPhysicalDevice> physicalDevices(deviceCount);
+    VK_OK(vkEnumeratePhysicalDevices(m_instance, &deviceCount, physicalDevices.data()));
+    for (const auto& physDev : physicalDevices)
+    {
+        uint32_t queueFamilyCount = 0;
+        vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueFamilyCount, nullptr);
+        std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
+        vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueFamilyCount, queueFamilies.data());
+        for (auto i = 0; i < queueFamilies.size(); ++i)
+        {
+            const auto& qFamily = queueFamilies[i];
+            // To make things a bit simpler, we want a single queue that does everything we need
+            if ((qFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) && (qFamily.queueFlags & VK_QUEUE_COMPUTE_BIT)
+                && (qFamily.queueFlags & VK_QUEUE_TRANSFER_BIT)
+                && glfwGetPhysicalDevicePresentationSupport(m_instance, physDev, i))
+            {
+                // Additionally can:
+                // - vkGetPhysicalDeviceSurfaceFormatsKHR
+                // - vkGetPhysicalDeviceSurfacePresentModesKHR
+                m_physicalDevice = physDev;
+                m_queueFamilyIndex = i;
+                return;
+            }
+        }
+    }
+    VK_DIE("selectPhysicalDeviceAndQueueFamily");
+}
+
+uint32_t DeviceResources::findMemoryTypeIndex(uint32_t memoryTypeBits, VkMemoryPropertyFlags memPropFlags)
+{
+    VkPhysicalDeviceMemoryProperties physDevMemProps;
+    vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &physDevMemProps);
+    for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i)
+    {
+        if ((memoryTypeBits & (1 << i))
+            && (physDevMemProps.memoryTypes[i].propertyFlags & memPropFlags) == memPropFlags)
+        {
+            return i;
+        }
+    }
+    VK_DIE("findMemoryTypeIndex");
+    return -1;
+}
+
+void DeviceResources::createConstBuffer(void* initialData, uint32_t size, VkBuffer* outBuffer, VkDeviceMemory* outBuffMem, VkDeviceSize* outOffset)
+{
+    const auto align = m_physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
+    *outOffset = ((size + align - 1) / align) * align;
+    createBuffer(*outOffset * numSwapchainImages(),
+        VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+        VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+        outBuffer, outBuffMem);
+}
+
+void DeviceResources::createBuffer(VkDeviceSize size, VkBufferUsageFlags buffUsage, VkMemoryPropertyFlags memProps, VkBuffer* outBuffer, VkDeviceMemory* outBuffMem)
+{
+    {
+        VkBufferCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        info.size = size;
+        info.usage = buffUsage;
+        info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+        VK_OK(vkCreateBuffer(m_device, &info, nullptr, outBuffer));
+    }
+    {
+        VkMemoryRequirements memReqs;
+        vkGetBufferMemoryRequirements(m_device, *outBuffer, &memReqs);
+
+        VkMemoryAllocateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        info.allocationSize = memReqs.size;
+        info.memoryTypeIndex = findMemoryTypeIndex(memReqs.memoryTypeBits, memProps);
+        VK_OK(vkAllocateMemory(m_device, &info, nullptr, outBuffMem));
+    }
+
+    VK_OK(vkBindBufferMemory(m_device, *outBuffer, *outBuffMem, 0));
+}
+
+void DeviceResources::resizeRenderTarget(uint32_t Width, uint32_t Height)
+{
+    createSurfaceResources();
+}
+
+void DeviceResources::update()
+{
+    if (m_swapChainRebuild)
+    {
+        int width, height;
+        glfwGetFramebufferSize(m_window, &width, &height);
+        if (width > 0 && height > 0)
+        {
+            ImGui_ImplVulkan_SetMinImageCount(m_minImageCount);
+            resizeRenderTarget(width, height);
+            m_frameIndex = 0;
+            m_swapChainRebuild = false;
+        }
+    }
+}
+
+void DeviceResources::beginRender()
+{
+    auto image_acquired_semaphore = imageAcquired();
+    auto render_complete_semaphore = renderComplete();
+    VkResult err = vkAcquireNextImageKHR(m_device, swapchain(), UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &m_frameIndex);
+    if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
+    {
+        requestSwapChainRebuild();
+        return;
+    }
+
+    auto frame = currentFrame();
+    auto cmdBuff = commandBuffer();
+    {
+        VK_OK(vkWaitForFences(m_device, 1, &frame->fence, VK_TRUE, UINT64_MAX)); // wait indefinitely
+        VK_OK(vkResetFences(m_device, 1, &frame->fence));
+    }
+    {
+        VK_OK(vkResetCommandPool(m_device, frame->commandPool, 0));
+        VkCommandBufferBeginInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+        VK_OK(vkBeginCommandBuffer(cmdBuff, &info));
+    }
+
+    // Layout transition backbuffer
+    {
+        VkImageMemoryBarrier barrier{};
+        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
+        barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+        barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+        barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        barrier.subresourceRange.levelCount = 1;
+        barrier.subresourceRange.layerCount = 1;
+        barrier.image = backBuffer();
+        vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
+    }
+}
+
+void DeviceResources::present(uint32_t SyncInterval, uint32_t Flags)
+{
+    if (m_swapChainRebuild)
+        return;
+
+    auto cmdBuff = commandBuffer();
+
+    // Layout transition backbuffer for present
+    {
+        VkImageMemoryBarrier barrier{};
+        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
+        barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+        barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+        barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        barrier.subresourceRange.levelCount = 1;
+        barrier.subresourceRange.layerCount = 1;
+        barrier.image = backBuffer();
+        vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
+    }
+
+    auto image_acquired_semaphore = imageAcquired();
+    auto render_complete_semaphore = renderComplete();
+    auto frame = currentFrame();
+
+    // Submit command buffer
+    {
+        VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+        VkSubmitInfo info = {};
+        info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        info.waitSemaphoreCount = 1;
+        info.pWaitSemaphores = &image_acquired_semaphore;
+        info.pWaitDstStageMask = &wait_stage;
+        info.commandBufferCount = 1;
+        info.pCommandBuffers = &cmdBuff;
+        info.signalSemaphoreCount = 1;
+        info.pSignalSemaphores = &render_complete_semaphore;
+
+        VK_OK(vkEndCommandBuffer(cmdBuff));
+        VK_OK(vkQueueSubmit(m_queue, 1, &info, frame->fence));
+    }
+
+    // Frame present
+    VkPresentInfoKHR info{};
+    info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+    info.waitSemaphoreCount = 1;
+    info.pWaitSemaphores = &render_complete_semaphore;
+    info.swapchainCount = 1;
+    info.pSwapchains = &m_swapchain;
+    info.pImageIndices = &m_frameIndex;
+    VkResult err = vkQueuePresentKHR(m_queue, &info);
+    if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
+    {
+        requestSwapChainRebuild();
+        return;
+    }
+    assert(err == VK_SUCCESS);
+    m_semaphoreIndex = (m_semaphoreIndex + 1) % numSwapchainImages(); // Now we can use the next set of semaphores
+
+    // SwapBuffers not needed with Vulkan
+    //glfwSwapBuffers(hwnd);
+}
+
+VkCommandBuffer DeviceResources::beginOneTimeSubmitCmd()
+{
+    VkCommandBuffer cmdBuff = commandBuffer();
+
+    VK_OK(vkResetCommandPool(m_device, commandPool(), 0));
+    VkCommandBufferBeginInfo info{};
+    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+    VK_OK(vkBeginCommandBuffer(cmdBuff, &info));
+
+    return cmdBuff;
+}
+
+void DeviceResources::endOneTimeSubmitCmd()
+{
+    VkCommandBuffer cmdBuff = commandBuffer();
+    VkSubmitInfo info{};
+    info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    info.commandBufferCount = 1;
+    info.pCommandBuffers = &cmdBuff;
+    VK_OK(vkEndCommandBuffer(cmdBuff));
+    VK_OK(vkQueueSubmit(m_queue, 1, &info, VK_NULL_HANDLE));
+    VK_OK(vkDeviceWaitIdle(m_device));
+}
+
+void DeviceResources::createTexture2D(int w, int h, VkFormat format, const void* data, uint32_t rowPitch, uint32_t imageSize, VkImage* outImage, VkDeviceMemory* outDeviceMemory)
+{
+    auto width = static_cast<uint32_t>(w);
+    auto height = static_cast<uint32_t>(h);
+
+    VkBuffer stagingBuff;
+    VkDeviceMemory stagingBuffMem;
+
+    createBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+        VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+        &stagingBuff, &stagingBuffMem);
+
+    void* mappedMem;
+    VK_OK(vkMapMemory(m_device, stagingBuffMem, 0, imageSize, 0, &mappedMem));
+    memcpy(mappedMem, data, imageSize);
+    vkUnmapMemory(m_device, stagingBuffMem);
+
+    // Create texture image object and backing memory
+    {
+        VkImageCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        info.imageType = VK_IMAGE_TYPE_2D;
+        info.extent.width = width;
+        info.extent.height = height;
+        info.extent.depth = 1;
+        info.mipLevels = 1;
+        info.arrayLayers = 1;
+        info.format = format;
+        info.tiling = VK_IMAGE_TILING_OPTIMAL;
+        info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+        info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
+        info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+        info.samples = VK_SAMPLE_COUNT_1_BIT;
+
+        VK_OK(vkCreateImage(m_device, &info, nullptr, outImage));
+    }
+    {
+        VkMemoryRequirements memReq{};
+        vkGetImageMemoryRequirements(m_device, *outImage, &memReq);
+
+        VkMemoryAllocateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        info.allocationSize = memReq.size;
+        info.memoryTypeIndex = findMemoryTypeIndex(memReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+        VK_OK(vkAllocateMemory(m_device, &info, nullptr, outDeviceMemory));
+
+        VK_OK(vkBindImageMemory(m_device, *outImage, *outDeviceMemory, 0));
+    }
+    VkCommandBuffer cmdBuff = beginOneTimeSubmitCmd();
+    {
+        VkImageMemoryBarrier transferBarrier{};
+        transferBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        transferBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+        transferBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+        transferBarrier.srcAccessMask = 0;
+        transferBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+        transferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        transferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        transferBarrier.image = *outImage;
+        transferBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        transferBarrier.subresourceRange.levelCount = 1;
+        transferBarrier.subresourceRange.layerCount = 1;
+        vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &transferBarrier);
+
+        VkBufferImageCopy buffImageCopyRegion{};
+        buffImageCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        buffImageCopyRegion.imageSubresource.layerCount = 1;
+        buffImageCopyRegion.imageExtent = { width, height, 1 };
+        vkCmdCopyBufferToImage(cmdBuff, stagingBuff, *outImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &buffImageCopyRegion);
+
+        VkImageMemoryBarrier useBarrier{};
+        useBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+        useBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+        useBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+        useBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+        useBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+        useBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        useBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+        useBarrier.image = *outImage;
+        useBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        useBarrier.subresourceRange.levelCount = 1;
+        useBarrier.subresourceRange.layerCount = 1;
+        vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &useBarrier);
+    }
+    endOneTimeSubmitCmd();
+
+    vkFreeMemory(m_device, stagingBuffMem, nullptr);
+    vkDestroyBuffer(m_device, stagingBuff, nullptr);
+}
+
+void DeviceResources::createTexture2D(int w, int h, VkFormat format, VkImage* outImage, VkDeviceMemory* outDeviceMemory)
+{
+    auto width = static_cast<uint32_t>(w);
+    auto height = static_cast<uint32_t>(h);
+
+    // Create texture image object and backing memory
+    {
+        VkImageCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        info.imageType = VK_IMAGE_TYPE_2D;
+        info.extent.width = width;
+        info.extent.height = height;
+        info.extent.depth = 1;
+        info.mipLevels = 1;
+        info.arrayLayers = 1;
+        info.format = format;
+        info.tiling = VK_IMAGE_TILING_OPTIMAL;
+        info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+        info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
+        info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+        info.samples = VK_SAMPLE_COUNT_1_BIT;
+
+        VK_OK(vkCreateImage(m_device, &info, nullptr, outImage));
+    }
+    {
+        VkMemoryRequirements memReq{};
+        vkGetImageMemoryRequirements(m_device, *outImage, &memReq);
+
+        VkMemoryAllocateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        info.allocationSize = memReq.size;
+        info.memoryTypeIndex = findMemoryTypeIndex(memReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+        VK_OK(vkAllocateMemory(m_device, &info, nullptr, outDeviceMemory));
+
+        VK_OK(vkBindImageMemory(m_device, *outImage, *outDeviceMemory, 0));
+    }
+}
+
+void DeviceResources::createSRV(VkImage inputImage, VkFormat format, VkImageView* outSrv)
+{
+    VkImageViewCreateInfo info{};
+    info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    info.image = inputImage;
+    info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    info.format = format;
+    info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    info.subresourceRange.layerCount = 1;
+    info.subresourceRange.levelCount = 1;
+    VK_OK(vkCreateImageView(m_device, &info, nullptr, outSrv));
+}

+ 242 - 0
samples/VK/src/NVScaler.cpp

@@ -0,0 +1,242 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "NVScaler.h"
+
+#include <iostream>
+#include <array>
+
+#include "VKUtilities.h"
+#include "DeviceResources.h"
+#include "Utilities.h"
+
+
+NVScaler::NVScaler(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths, bool glsl)
+    : m_deviceResources(deviceResources)
+    , m_outputWidth(1)
+    , m_outputHeight(1)
+{
+    NISOptimizer opt(true, NISGPUArchitecture::NVIDIA_Generic);
+    m_blockWidth = opt.GetOptimalBlockWidth();
+    m_blockHeight = opt.GetOptimalBlockHeight();
+    uint32_t threadGroupSize = opt.GetOptimalThreadGroupSize();
+
+    // Shader
+    {
+        std::string shaderName = glsl ? "/nis_scaler_glsl.spv" : "/nis_scaler.spv";
+        std::string shaderPath;
+        for (auto& e : shaderPaths)
+        {
+            if (std::filesystem::exists(e + "/" + shaderName))
+            {
+                shaderPath = e + "/" + shaderName;
+                break;
+            }
+        }
+        if (shaderPath.empty())
+            throw std::runtime_error("Shader file not found" + shaderName);
+
+        auto shaderBytes = readBytes(shaderPath);
+
+        VkShaderModuleCreateInfo createInfo{};
+        createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+        createInfo.codeSize = shaderBytes.size();
+        createInfo.pCode = reinterpret_cast<uint32_t*>(shaderBytes.data());
+        VK_OK(vkCreateShaderModule(m_deviceResources.logicalDevice(), &createInfo, nullptr, &m_shaderModule));
+    }
+
+    // Descriptor set
+    {
+        std::array<VkDescriptorSetLayoutBinding, 6> bindLayout{ {
+            VK_COMMON_DESC_LAYOUT(m_deviceResources.sampler()),
+            {COEF_SCALAR_BINDING, IN_TEX_DESC_TYPE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
+            {COEF_USM_BINDING, IN_TEX_DESC_TYPE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
+        } };
+
+        VkDescriptorSetLayoutCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        info.bindingCount = (uint32_t)bindLayout.size();
+        info.pBindings = bindLayout.data();
+        VK_OK(vkCreateDescriptorSetLayout(m_deviceResources.logicalDevice(), &info, nullptr, &m_descriptorSetLayout));
+    }
+    {
+        VkDescriptorSetAllocateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        info.descriptorPool = deviceResources.descriptorPool();
+        info.descriptorSetCount = 1;
+        info.pSetLayouts = &m_descriptorSetLayout;
+        VK_OK(vkAllocateDescriptorSets(m_deviceResources.logicalDevice(), &info, &m_descriptorSet));
+    }
+
+    // Constant buffer
+    {
+        m_deviceResources.createConstBuffer(&m_config, sizeof(NISConfig), &m_buffer, &m_constantBufferDeviceMemory, &m_constantBufferStride);
+        VK_OK(vkMapMemory(m_deviceResources.logicalDevice(), m_constantBufferDeviceMemory, 0, m_constantBufferStride, 0, (void**)&m_constantMemory));
+
+        VkDescriptorBufferInfo descBuffInfo{};
+        descBuffInfo.buffer = m_buffer;
+        descBuffInfo.offset = 0;
+        descBuffInfo.range = sizeof(NISConfig);
+        VkWriteDescriptorSet writeDescSet{};
+        writeDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        writeDescSet.dstSet = m_descriptorSet;
+        writeDescSet.dstBinding = CB_BINDING;
+        writeDescSet.descriptorCount = 1;
+        writeDescSet.descriptorType = CB_DESC_TYPE;
+        writeDescSet.dstArrayElement = 0;
+        writeDescSet.pBufferInfo = &descBuffInfo;
+        vkUpdateDescriptorSets(m_deviceResources.logicalDevice(), 1, &writeDescSet, 0, nullptr);
+    }
+
+    // Pipeline layout
+    {
+        VkPushConstantRange pushConstRange{};
+        pushConstRange.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
+        pushConstRange.size = sizeof(m_config);
+        VkPipelineLayoutCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+        info.setLayoutCount = 1;
+        info.pSetLayouts = &m_descriptorSetLayout;
+        info.pushConstantRangeCount = 1;
+        info.pPushConstantRanges = &pushConstRange;
+
+        VK_OK(vkCreatePipelineLayout(m_deviceResources.logicalDevice(), &info, nullptr, &m_pipelineLayout));
+    }
+
+    // Compute pipeline
+    {
+        VkPipelineShaderStageCreateInfo pipeShaderStageCreateInfo{};
+        pipeShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+        pipeShaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
+        pipeShaderStageCreateInfo.module = m_shaderModule;
+        pipeShaderStageCreateInfo.pName = "main";
+
+        VkComputePipelineCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
+        info.stage = pipeShaderStageCreateInfo;
+        info.layout = m_pipelineLayout;
+        VK_OK(vkCreateComputePipelines(m_deviceResources.logicalDevice(), VK_NULL_HANDLE, 1, &info, nullptr, &m_pipeline));
+    }
+
+    const int rowPitch = kFilterSize * 2;
+    const int imageSize = rowPitch * kPhaseCount;
+    m_deviceResources.createTexture2D(kFilterSize / 4, kPhaseCount, VK_FORMAT_R16G16B16A16_SFLOAT, coef_scale_fp16, rowPitch, imageSize, &m_coefScale, &m_coefScaleDeviceMemory);
+    m_deviceResources.createTexture2D(kFilterSize / 4, kPhaseCount, VK_FORMAT_R16G16B16A16_SFLOAT, coef_usm_fp16, rowPitch, imageSize, &m_coefUsm, &m_coefUsmDeviceMemory);
+    m_deviceResources.createSRV(m_coefScale, VK_FORMAT_R16G16B16A16_SFLOAT, &m_coefScaleSrv);
+    m_deviceResources.createSRV(m_coefUsm, VK_FORMAT_R16G16B16A16_SFLOAT, &m_coefUsmSrv);
+}
+
+void NVScaler::cleanUp()
+{
+    vkDestroyImageView(m_deviceResources.logicalDevice(), m_coefUsmSrv, nullptr);
+    vkDestroyImageView(m_deviceResources.logicalDevice(), m_coefScaleSrv, nullptr);
+    vkFreeMemory(m_deviceResources.logicalDevice(), m_coefUsmDeviceMemory, nullptr);
+    vkFreeMemory(m_deviceResources.logicalDevice(), m_coefScaleDeviceMemory, nullptr);
+    vkDestroyImage(m_deviceResources.logicalDevice(), m_coefUsm, nullptr);
+    vkDestroyImage(m_deviceResources.logicalDevice(), m_coefScale, nullptr);
+    vkDestroyPipeline(m_deviceResources.logicalDevice(), m_pipeline, nullptr);
+    vkDestroyPipelineLayout(m_deviceResources.logicalDevice(), m_pipelineLayout, nullptr);
+    vkFreeMemory(m_deviceResources.logicalDevice(), m_constantBufferDeviceMemory, nullptr);
+    vkDestroyBuffer(m_deviceResources.logicalDevice(), m_buffer, nullptr);
+    vkFreeDescriptorSets(m_deviceResources.logicalDevice(), m_deviceResources.descriptorPool(), 1, &m_descriptorSet);
+    vkDestroyDescriptorSetLayout(m_deviceResources.logicalDevice(), m_descriptorSetLayout, nullptr);
+    vkDestroyShaderModule(m_deviceResources.logicalDevice(), m_shaderModule, nullptr);
+}
+
+void NVScaler::update(float sharpness, uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight)
+{
+    NVScalerUpdateConfig(m_config, sharpness,
+        0, 0, inputWidth, inputHeight, inputWidth, inputHeight,
+        0, 0, outputWidth, outputHeight, outputWidth, outputHeight,
+        NISHDRMode::None);
+    m_outputWidth = outputWidth;
+    m_outputHeight = outputHeight;
+}
+
+void NVScaler::dispatch(VkImageView inputSrv, VkImageView outputUav)
+{
+    // Update constant buffer
+    const auto offset = m_constantBufferStride * m_deviceResources.swapchainIndex();
+    memcpy(m_constantMemory + offset, &m_config, sizeof(m_config));
+    VkDescriptorBufferInfo descBuffInfo{};
+    descBuffInfo.buffer = m_buffer;
+    descBuffInfo.offset = offset;
+    descBuffInfo.range = sizeof(NISConfig);
+
+    VkWriteDescriptorSet inWriteDescSet{};
+    VkWriteDescriptorSet outWriteDescSet{};
+    VkWriteDescriptorSet coefScalarWriteDescSet{};
+    VkWriteDescriptorSet coefUsmWriteDescSet{};
+    VkDescriptorImageInfo info_inWriteDescSet{};
+    info_inWriteDescSet.imageView = inputSrv;
+    info_inWriteDescSet.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    inWriteDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    inWriteDescSet.dstSet = m_descriptorSet;
+    inWriteDescSet.dstBinding = IN_TEX_BINDING;
+    inWriteDescSet.descriptorCount = 1;
+    inWriteDescSet.descriptorType = IN_TEX_DESC_TYPE;
+    inWriteDescSet.pImageInfo = &info_inWriteDescSet;
+    VkDescriptorImageInfo infooutWriteDescSet{};
+    infooutWriteDescSet.imageView = outputUav;
+    infooutWriteDescSet.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+    outWriteDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    outWriteDescSet.dstSet = m_descriptorSet;
+    outWriteDescSet.dstBinding = OUT_TEX_BINDING;
+    outWriteDescSet.descriptorCount = 1;
+    outWriteDescSet.descriptorType = OUT_TEX_DESC_TYPE;
+    outWriteDescSet.pImageInfo = &infooutWriteDescSet;
+    VkDescriptorImageInfo infocoefScalarWriteDescSet{};
+    infocoefScalarWriteDescSet.imageView = m_coefScaleSrv;
+    infocoefScalarWriteDescSet.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    coefScalarWriteDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    coefScalarWriteDescSet.dstSet = m_descriptorSet;
+    coefScalarWriteDescSet.dstBinding = COEF_SCALAR_BINDING;
+    coefScalarWriteDescSet.descriptorCount = 1;
+    coefScalarWriteDescSet.descriptorType = IN_TEX_DESC_TYPE;
+    coefScalarWriteDescSet.pImageInfo = &infocoefScalarWriteDescSet;
+    VkDescriptorImageInfo infocoefUsmWriteDescSet{};
+    infocoefUsmWriteDescSet.imageView = m_coefUsmSrv;
+    infocoefUsmWriteDescSet.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    coefUsmWriteDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    coefUsmWriteDescSet.dstSet = m_descriptorSet;
+    coefUsmWriteDescSet.dstBinding = COEF_USM_BINDING;
+    coefUsmWriteDescSet.descriptorCount = 1;
+    coefUsmWriteDescSet.descriptorType = IN_TEX_DESC_TYPE;
+    coefUsmWriteDescSet.pImageInfo = &infocoefUsmWriteDescSet;
+
+    const VkWriteDescriptorSet writeDescSets[] = {
+        inWriteDescSet,
+        outWriteDescSet,
+        coefScalarWriteDescSet,
+        coefUsmWriteDescSet
+    };
+    constexpr auto sizeWriteDescSets = static_cast<uint32_t>(std::size(writeDescSets));
+    vkUpdateDescriptorSets(m_deviceResources.logicalDevice(), sizeWriteDescSets, writeDescSets, 0, nullptr);
+
+    auto cmdBuffer = m_deviceResources.commandBuffer();
+
+    vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
+    vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, 1, &m_descriptorSet, 1, (uint32_t*)&descBuffInfo.offset);
+
+    uint32_t gridX = uint32_t(std::ceil(m_outputWidth / float(m_blockWidth)));
+    uint32_t gridY = uint32_t(std::ceil(m_outputHeight / float(m_blockHeight)));
+    vkCmdDispatch(cmdBuffer, gridX, gridY, 1);
+}

+ 201 - 0
samples/VK/src/NVSharpen.cpp

@@ -0,0 +1,201 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include "NVSharpen.h"
+
+#include <iostream>
+#include <array>
+
+#include "VKUtilities.h"
+#include "DeviceResources.h"
+#include "Utilities.h"
+
+
+NVSharpen::NVSharpen(DeviceResources& deviceResources, const std::vector<std::string>& shaderPaths, bool glsl)
+    : m_deviceResources(deviceResources)
+    , m_outputWidth(1)
+    , m_outputHeight(1)
+{
+    NISOptimizer opt(false, NISGPUArchitecture::NVIDIA_Generic);
+    m_blockWidth = opt.GetOptimalBlockWidth();
+    m_blockHeight = opt.GetOptimalBlockHeight();
+    uint32_t threadGroupSize = opt.GetOptimalThreadGroupSize();
+
+    // Shader
+    {
+        std::string shaderName = glsl ? "/nis_sharpen_glsl.spv" : "/nis_sharpen.spv";
+        std::string shaderPath;
+        for (auto& e : shaderPaths)
+        {
+            if (std::filesystem::exists(e + "/" + shaderName))
+            {
+                shaderPath = e + "/" + shaderName;
+                break;
+            }
+        }
+        if (shaderPath.empty())
+            throw std::runtime_error("Shader file not found" + shaderName);
+
+        auto shaderBytes = readBytes(shaderPath);
+        VkShaderModuleCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+        info.codeSize = shaderBytes.size();
+        info.pCode = reinterpret_cast<uint32_t*>(shaderBytes.data());
+        VK_OK(vkCreateShaderModule(m_deviceResources.logicalDevice(), &info, nullptr, &m_shaderModule));
+    }
+
+    // Descriptor set
+    {
+        std::array<VkDescriptorSetLayoutBinding, 4> bindLayout{ {
+            VK_COMMON_DESC_LAYOUT(m_deviceResources.sampler()),
+        } };
+
+        VkDescriptorSetLayoutCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        info.bindingCount = (uint32_t)bindLayout.size();
+        info.pBindings = bindLayout.data();
+        VK_OK(vkCreateDescriptorSetLayout(m_deviceResources.logicalDevice(), &info, nullptr, &m_descriptorSetLayout));
+    }
+    {
+        VkDescriptorSetAllocateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        info.descriptorPool = deviceResources.descriptorPool();
+        info.descriptorSetCount = 1;
+        info.pSetLayouts = &m_descriptorSetLayout;
+        VK_OK(vkAllocateDescriptorSets(m_deviceResources.logicalDevice(), &info, &m_descriptorSet));
+    }
+
+    // Constant buffer
+    {
+        m_deviceResources.createConstBuffer(&m_config, sizeof(NISConfig), &m_buffer, &m_constantBufferDeviceMemory, &m_constantBufferStride);
+        VK_OK(vkMapMemory(m_deviceResources.logicalDevice(), m_constantBufferDeviceMemory, 0, m_constantBufferStride, 0, (void**)&m_constantMemory));
+
+        VkDescriptorBufferInfo descBuffInfo{};
+        descBuffInfo.buffer = m_buffer;
+        descBuffInfo.offset = 0;
+        descBuffInfo.range = sizeof(NISConfig);
+        VkWriteDescriptorSet writeDescSet{};
+        writeDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        writeDescSet.dstSet = m_descriptorSet;
+        writeDescSet.dstBinding = CB_BINDING;
+        writeDescSet.descriptorCount = 1;
+        writeDescSet.descriptorType = CB_DESC_TYPE;
+        writeDescSet.dstArrayElement = 0;
+        writeDescSet.pBufferInfo = &descBuffInfo;
+        vkUpdateDescriptorSets(m_deviceResources.logicalDevice(), 1, &writeDescSet, 0, nullptr);
+    }
+
+    // Pipeline layout
+    {
+        VkPushConstantRange pushConstRange{};
+        pushConstRange.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
+        pushConstRange.size = sizeof(m_config);
+        VkPipelineLayoutCreateInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+        info.setLayoutCount = 1;
+        info.pSetLayouts = &m_descriptorSetLayout;
+        info.pushConstantRangeCount = 1;
+        info.pPushConstantRanges = &pushConstRange;
+
+        VK_OK(vkCreatePipelineLayout(m_deviceResources.logicalDevice(), &info, nullptr, &m_pipelineLayout));
+    }
+
+    // Compute pipeline
+    {
+        VkPipelineShaderStageCreateInfo pipeShaderStageCreateInfo{};
+        pipeShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+        pipeShaderStageCreateInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
+        pipeShaderStageCreateInfo.module = m_shaderModule;
+        pipeShaderStageCreateInfo.pName = "main";
+
+        VkComputePipelineCreateInfo csPipeCreateInfo{};
+        csPipeCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
+        csPipeCreateInfo.stage = pipeShaderStageCreateInfo;
+        csPipeCreateInfo.layout = m_pipelineLayout;
+        VK_OK(vkCreateComputePipelines(m_deviceResources.logicalDevice(), VK_NULL_HANDLE, 1, &csPipeCreateInfo, nullptr, &m_pipeline));
+    }
+}
+
+void NVSharpen::cleanUp()
+{
+    vkDestroyPipeline(m_deviceResources.logicalDevice(), m_pipeline, nullptr);
+    vkDestroyPipelineLayout(m_deviceResources.logicalDevice(), m_pipelineLayout, nullptr);
+    vkFreeMemory(m_deviceResources.logicalDevice(), m_constantBufferDeviceMemory, nullptr);
+    vkDestroyBuffer(m_deviceResources.logicalDevice(), m_buffer, nullptr);
+    vkFreeDescriptorSets(m_deviceResources.logicalDevice(), m_deviceResources.descriptorPool(), 1, &m_descriptorSet);
+    vkDestroyDescriptorSetLayout(m_deviceResources.logicalDevice(), m_descriptorSetLayout, nullptr);
+    vkDestroyShaderModule(m_deviceResources.logicalDevice(), m_shaderModule, nullptr);
+}
+
+void NVSharpen::update(float sharpness, uint32_t inputWidth, uint32_t inputHeight)
+{
+    NVSharpenUpdateConfig(m_config, sharpness,
+        0, 0, inputWidth, inputHeight, inputWidth, inputHeight,
+        0, 0, NISHDRMode::None);
+    m_outputWidth = inputWidth;
+    m_outputHeight = inputHeight;
+}
+
+void NVSharpen::dispatch(VkImageView inputSrv, VkImageView outputUav)
+{
+    const auto offset = m_constantBufferStride * m_deviceResources.swapchainIndex();
+    memcpy(m_constantMemory + offset, &m_config, sizeof(m_config));
+    VkDescriptorBufferInfo descBuffInfo{};
+    descBuffInfo.buffer = m_buffer;
+    descBuffInfo.offset = offset;
+    descBuffInfo.range = sizeof(NISConfig);
+
+    VkWriteDescriptorSet inWriteDescSet{};
+    VkWriteDescriptorSet outWriteDescSet{};
+    VkDescriptorImageInfo inDescInfo{};
+    inDescInfo.imageView = inputSrv;
+    inDescInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    inWriteDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    inWriteDescSet.dstSet = m_descriptorSet;
+    inWriteDescSet.dstBinding = IN_TEX_BINDING;
+    inWriteDescSet.descriptorCount = 1;
+    inWriteDescSet.descriptorType = IN_TEX_DESC_TYPE;
+    inWriteDescSet.pImageInfo = &inDescInfo;
+    VkDescriptorImageInfo outDescInfo{};
+    outDescInfo.imageView = outputUav;
+    outDescInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+    outWriteDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    outWriteDescSet.dstSet = m_descriptorSet;
+    outWriteDescSet.dstBinding = OUT_TEX_BINDING;
+    outWriteDescSet.descriptorCount = 1;
+    outWriteDescSet.descriptorType = OUT_TEX_DESC_TYPE;
+    outWriteDescSet.pImageInfo = &outDescInfo;
+    const VkWriteDescriptorSet writeDescSets[] = {
+        inWriteDescSet,
+        outWriteDescSet
+    };
+    constexpr auto sizeWriteDescSets = static_cast<uint32_t>(std::size(writeDescSets));
+    vkUpdateDescriptorSets(m_deviceResources.logicalDevice(), sizeWriteDescSets, writeDescSets, 0, nullptr);
+
+    auto cmdBuffer = m_deviceResources.commandBuffer();
+
+    vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
+    vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, 1, &m_descriptorSet, 1, (uint32_t*)&descBuffInfo.offset);
+
+    uint32_t gridX = uint32_t(std::ceil(m_outputWidth / float(m_blockWidth)));
+    uint32_t gridY = uint32_t(std::ceil(m_outputHeight / float(m_blockHeight)));
+    vkCmdDispatch(cmdBuffer, gridX, gridY, 1);
+}

+ 110 - 0
samples/VK/src/Sample.cpp

@@ -0,0 +1,110 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include <filesystem>
+#include <iostream>
+
+#include "AppRenderer.h"
+#include "DeviceResources.h"
+#include "UIRenderer.h"
+
+static void glfw_error_callback(int error, const char* description)
+{
+    fprintf(stderr, "glfw error: %d %s\n", error, description);
+    assert(0);
+}
+
+int main(int argc, char* argv[])
+{
+    // Resources
+    std::string mediaFolder = "media/images/";
+
+    if (!std::filesystem::exists(mediaFolder))
+        mediaFolder = "media/images/";
+    if (!std::filesystem::exists(mediaFolder))
+        mediaFolder = "../../media/images/";
+
+    glfwSetErrorCallback(glfw_error_callback);
+    if (glfwInit() == GLFW_FALSE)
+    {
+        fprintf(stderr, "glfwInit() failed\n");
+        exit(EXIT_FAILURE);
+    }
+    glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
+    // Don't need OpenGL context
+    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+    auto app_name = "NVIDIA Image Scaling Vulkan Demo";
+    GLFWwindow* hwnd = glfwCreateWindow(256, 256, app_name, nullptr, nullptr);
+    if (!hwnd)
+    {
+        glfwTerminate();
+        exit(EXIT_FAILURE);
+    }
+
+    DeviceResources deviceResources;
+    UIData uiData;
+
+    deviceResources.create(hwnd);
+
+    // Show window and force resize similiar to ::UpdateWindow() in DX11 sample
+    glfwShowWindow(hwnd);
+    glfwFocusWindow(hwnd);
+    glfwSetWindowSize(hwnd, 1280, 1080);
+
+    // UI settings
+    uiData.Files = getFiles(mediaFolder);
+    if (uiData.Files.size() == 0)
+        throw std::runtime_error("No media files");
+    uiData.FileName = uiData.Files[0].filename().string();
+    uiData.FilePath = uiData.Files[0];
+
+    std::vector<std::string> shaderPaths{ "NIS/", "../../../NIS/", "." };
+    bool useGlsl = false;
+    AppRenderer appRenderer(deviceResources, uiData, shaderPaths, useGlsl);
+    UIRenderer uiRenderer(hwnd, deviceResources, uiData);
+    FPS m_fps;
+
+    while (!glfwWindowShouldClose(hwnd))
+    {
+        glfwPollEvents();
+
+        m_fps.update();
+        deviceResources.update();
+        uiRenderer.update(m_fps.fps());
+        if (appRenderer.update())
+        {
+            glfwSetWindowSize(hwnd, appRenderer.width(), appRenderer.height());
+        }
+        deviceResources.beginRender();
+        appRenderer.render();
+        uiRenderer.render();
+        deviceResources.present(uiData.EnableVsync /*ignored*/, 0);
+        appRenderer.present();
+    }
+
+    uiRenderer.cleanUp();
+    appRenderer.cleanUp();
+    deviceResources.cleanUp();
+    glfwDestroyWindow(hwnd);
+    glfwTerminate();
+
+    return EXIT_SUCCESS;
+}

+ 214 - 0
samples/VK/src/UIRenderer.cpp

@@ -0,0 +1,214 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files(the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include <UIRenderer.h>
+
+UIRenderer::UIRenderer(void* hwnd, DeviceResources& deviceResources, UIData& ui)
+: m_deviceResources(deviceResources)
+, m_ui(ui)
+{
+    // Setup Dear ImGui context
+    IMGUI_CHECKVERSION();
+    ImGui::CreateContext();
+    ImGuiIO& io = ImGui::GetIO(); (void)io;
+
+    ImGui::StyleColorsDark();
+    ImGui::GetStyle().WindowRounding = 6;
+    ImGui::GetStyle().FrameBorderSize = 1;
+
+    const bool installInputCallbacks = true;
+    ImGui_ImplGlfw_InitForVulkan((GLFWwindow*)hwnd, installInputCallbacks);
+    ImGui_ImplVulkan_InitInfo initInfo{};
+    initInfo.Instance = deviceResources.instance();
+    initInfo.PhysicalDevice = deviceResources.physicalDevice();
+    initInfo.Device = deviceResources.logicalDevice();
+    initInfo.Queue = deviceResources.queue();
+    initInfo.DescriptorPool = deviceResources.descriptorPool();
+    initInfo.MinImageCount = deviceResources.minImageCount();
+    initInfo.ImageCount = deviceResources.numSwapchainImages();
+    ImGui_ImplVulkan_Init(&initInfo, deviceResources.UIrenderPass());
+
+    // Upload Fonts
+    {
+        auto cmdBuff = deviceResources.beginOneTimeSubmitCmd();
+        ImGui_ImplVulkan_CreateFontsTexture(cmdBuff);
+        deviceResources.endOneTimeSubmitCmd();
+        ImGui_ImplVulkan_DestroyFontUploadObjects();
+    }
+}
+
+void UIRenderer::cleanUp()
+{
+    ImGui_ImplVulkan_Shutdown();
+    ImGui_ImplGlfw_Shutdown();
+    ImGui::DestroyContext();
+}
+
+void UIRenderer::update(double fps)
+{
+    m_elapsedTimer.start();
+    ImGui_ImplVulkan_NewFrame();
+    ImGui_ImplGlfw_NewFrame();
+
+    ImGui::NewFrame();
+    if (m_ui.ShowSettings)
+    {
+        ImGui::Begin("Settings", 0, ImGuiWindowFlags_AlwaysAutoResize);
+        if (ImGui::CollapsingHeader("Images", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            if (ImGui::BeginCombo("Filename", m_ui.FileName.c_str()))
+            {
+                for (auto& e : m_ui.Files)
+                {
+                    bool is_selected = (m_ui.FileName == e.filename().string());
+                    if (ImGui::Selectable(e.filename().string().c_str(), is_selected))
+                    {
+                        m_ui.FileName = e.filename().string();
+                        m_ui.FilePath = e;
+                    }
+                    if (is_selected)
+                    {
+                        ImGui::SetItemDefaultFocus();
+                    }
+                }
+                ImGui::EndCombo();
+            }
+        }
+        if (ImGui::CollapsingHeader("Filter", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            ImGui::RadioButton("NVScaler", &m_ui.FilterMode, 0); ImGui::SameLine();
+            ImGui::RadioButton("Bilinear", &m_ui.FilterMode, 2); ImGui::SameLine();
+            ImGui::RadioButton("NVSharpen", &m_ui.FilterMode, 1);
+            ;
+            ImGui::Separator();
+            if (m_ui.FilterMode == 0 || m_ui.FilterMode == 1)
+            {
+                m_ui.EnableNVScaler = true;
+                ImGui::SliderFloat("Sharpness (0% - 100%)", &m_ui.Sharpness, 0, 100, "%2.1f%%");
+            }
+            else
+            {
+                m_ui.EnableNVScaler = false;
+            }
+            if (m_ui.FilterMode == 0 || m_ui.FilterMode == 2)
+            {
+                ImGui::Separator();
+                std::vector<const char*> outputSizes = { "Variable", "1920x1080", "2560x1440", "3840x2160" };
+                ImGui::Combo("Height Size", (int*)&m_ui.OutputMode, outputSizes.data(), int(outputSizes.size()));
+                float fixScaleSize = 0;
+                switch (m_ui.OutputMode) {
+                case OutputSizeMode::VARIABLE:
+                    ImGui::SliderFloat("Scale (50% - 100%)", &m_ui.Scale, 50, 100, "%2.1f%%");
+                    break;
+                case OutputSizeMode::P1080:
+                    fixScaleSize = 1080.f;
+                    break;
+                case OutputSizeMode::P1440:
+                    fixScaleSize = 1440.f;
+                    break;
+                case OutputSizeMode::P2160:
+                    fixScaleSize = 2160.f;
+                    break;
+                }
+                if (fixScaleSize > 0)
+                {
+                    m_ui.Scale = std::min<float>(100.f, std::max<float>(50.f, m_ui.InputHeight / fixScaleSize * 100.f));
+                    ImGui::Text("Fix Scale : %2.1f%%", m_ui.Scale);
+                }
+            }
+            else
+            {
+                m_ui.Scale = 100;
+            }
+            ImGui::Separator();
+            if (m_ui.Scale == 100)
+            {
+                if (m_ui.EnableNVScaler)
+                {
+                    ImGui::Text("Using NVSharpen shader:");
+                    ImGui::Text("Scale 100 %% performs only sharpening");
+                }
+                else
+                {
+                    ImGui::Text("Using CopyResource");
+                }
+            }
+            else
+            {
+                if (m_ui.EnableNVScaler)
+                {
+                    ImGui::Text("Using NVScaler shader:");
+                    ImGui::Text("Performs scaling and sharpening");
+                }
+                else
+                {
+                    ImGui::Text("Using bilinear upscale shader");
+                }
+            }
+            ImGui::Separator();
+            ImGui::Text("Input Size  : %d x %d", m_ui.InputWidth, m_ui.InputHeight);
+            ImGui::Text("Output Size : %d x %d", m_ui.OutputWidth, m_ui.OutputHeight);
+        }
+        if (ImGui::CollapsingHeader("Profiling", ImGuiTreeNodeFlags_DefaultOpen))
+        {
+            ImGui::RadioButton("microseconds", &m_ui.UnitMicroseconds, 1); ImGui::SameLine();
+            ImGui::RadioButton("milliseconds", &m_ui.UnitMicroseconds, 0);
+            ImGui::Separator();
+            double unitConst = 1E6;
+            std::string unitStr = "us";
+            if (!m_ui.UnitMicroseconds)
+            {
+                unitConst = 1E3;
+                unitStr = "ms";
+            }
+            double filterTime = m_ui.FilterTime / 1E6 * unitConst;
+            double totalTime = 1. / fps * unitConst;
+            double uiTime = m_elapsedTimer.averageTime_us() / 1E6 * unitConst;
+            ImGui::Text("FPS         : %9.2f", fps);
+            ImGui::Text("Filter Time : %9.2f %s", filterTime, unitStr.c_str());
+            ImGui::Text("UI Time     : %9.2f %s", uiTime, unitStr.c_str());
+            ImGui::Text("Presnt Time : %9.2f %s", totalTime - filterTime - uiTime, unitStr.c_str());
+            ImGui::Text("Total Time  : %9.2f %s", totalTime, unitStr.c_str());
+        }
+        ImGui::End();
+    }
+    ImGui::Render();
+    m_elapsedTimer.end();
+}
+
+void UIRenderer::render()
+{
+    auto cmdBuff = m_deviceResources.commandBuffer();
+    {
+        VkRenderPassBeginInfo info{};
+        info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+        info.renderPass = m_deviceResources.UIrenderPass();
+        info.framebuffer = m_deviceResources.UIframeBuffer();
+        info.renderArea.extent.width = m_deviceResources.width();
+        info.renderArea.extent.height = m_deviceResources.height();
+        vkCmdBeginRenderPass(cmdBuff, &info, VK_SUBPASS_CONTENTS_INLINE);
+    }
+
+    // Record dear imgui primitives into command buffer
+    ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmdBuff);
+
+    vkCmdEndRenderPass(cmdBuff);
+}

+ 289 - 40
samples/common/Image.cpp

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -20,48 +20,297 @@
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Image.h"
-#include "DXUtilities.h"
+#define TINYEXR_IMPLEMENTATION
+#include <tinyexr.h>
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb_image.h>
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include <stb_image_write.h>
+#include <unordered_map>
+#include "Utilities.h"
 
-Image::Image() 
+namespace img
 {
-    DX::ThrowIfFailed(CoInitialize(nullptr));
-    DX::ThrowIfFailed(CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&m_WICFactory));
-}
 
-void Image::load(const std::filesystem::path& FilePath)
-{
-    if (FilePath.extension() == ".png")
-        LoadWIC(FilePath.wstring());
-}
+    using fp16_t = uint16_t;
 
-void Image::LoadWIC(const std::wstring& filename)
-{
-    wchar_t* wfilename = _wcsdup(filename.c_str());
-    ComPtr<IWICBitmapDecoder> decoder;
-    DX::ThrowIfFailed(m_WICFactory->CreateDecoderFromFilename(wfilename, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &decoder));
-    ComPtr<IWICBitmapFrameDecode> frame;
-    DX::ThrowIfFailed(decoder->GetFrame(0, &frame));
-    DX::ThrowIfFailed(frame->GetSize(&m_width, &m_height));
-    // get bpp
-    WICPixelFormatGUID pixelFormat;
-    DX::ThrowIfFailed(frame->GetPixelFormat(&pixelFormat));
-    ComPtr<IWICBitmapSource> pConvertedFrame;
-    if (pixelFormat != GUID_WICPixelFormat32bppRGBA)
+    inline fp16_t floatToHalf(float v)
+    {
+        tinyexr::FP32 fp32;
+        fp32.f = v;
+        return tinyexr::float_to_half_full(fp32).u;
+    }
+
+    inline float halfToFloat(fp16_t v)
     {
-        DX::ThrowIfFailed(WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, frame.Get(), &pConvertedFrame));
+        tinyexr::FP16 fp16;
+        fp16.u = v;
+        tinyexr::FP32 fp32 = tinyexr::half_to_float(fp16);
+        return fp32.f;
     }
-    else
+
+    template<typename T, typename K>
+    inline K convertTo(T v) { return K(v); }
+
+    template<>
+    inline float convertTo(uint8_t v) { return v / 255.f; }
+
+    template<>
+    inline fp16_t convertTo(uint8_t v) { return floatToHalf(v / 255.f); }
+
+    template<>
+    inline uint8_t convertTo(float v) { return uint8_t(v * 255.f); }
+
+    template<>
+    inline fp16_t convertTo(float v) { return floatToHalf(v); }
+
+    template<>
+    inline uint8_t convertTo(fp16_t v) { return uint8_t(halfToFloat(v) * 255.f); }
+
+    template<>
+    inline float convertTo(fp16_t v) { return halfToFloat(v); }
+
+    template<typename T>
+    inline T alphaMax() { return 255; }
+
+    template<>
+    inline float alphaMax() { return 1.f; }
+
+    template<>
+    inline fp16_t alphaMax() { return floatToHalf(1.f); }
+
+
+    template<typename T, typename K>
+    inline void convertToFmt(uint8_t* input, uint8_t* output, uint32_t width, uint32_t height, uint32_t inputChannels, uint32_t inputRowPitch, uint32_t outputChannels, uint32_t outputRowPitch)
+    {
+        constexpr size_t BOut = sizeof(K); // bytes per pixel
+        constexpr size_t BIn = sizeof(T);
+        for (size_t y = 0; y < height; ++y)
+        {
+            for (size_t x = 0; x < width; ++x)
+            {
+                size_t output_offset = y * outputRowPitch + x * outputChannels * BOut;
+                size_t input_offset = y * inputRowPitch + x * inputChannels * BIn;
+                ((K*)&output[output_offset])[0] = convertTo<T, K>(((T*)&input[input_offset])[0]);
+                ((K*)&output[output_offset])[1] = convertTo<T, K>(((T*)&input[input_offset])[1]);
+                ((K*)&output[output_offset])[2] = convertTo<T, K>(((T*)&input[input_offset])[2]);
+                if (outputChannels > 3)
+                    ((K*)&output[output_offset])[3] = inputChannels > 3 ? convertTo<T, K>(((T*)&input[input_offset])[3]) : alphaMax<K>();
+            }
+        }
+    }
+
+    template<typename T, typename K>
+    inline void convertToFmtPlanesABGR(uint8_t* input, uint8_t* output, uint32_t width, uint32_t height, uint32_t inputChannels, uint32_t inputRowPitch, uint32_t outputChannels, uint32_t outputRowPitch)
+    {
+        constexpr size_t BOut = sizeof(K); // bytes per pixel
+        constexpr size_t BIn = sizeof(T);
+        size_t planeSize = size_t(outputRowPitch) * height;
+        for (size_t y = 0; y < height; ++y)
+        {
+            for (size_t x = 0; x < width; ++x)
+            {
+                size_t input_offset = y * inputRowPitch + x * inputChannels * BIn;
+                size_t output_offset0 = (y * outputRowPitch) + x * BOut;
+                size_t output_offset1 = output_offset0 + planeSize;
+                size_t output_offset2 = output_offset1 + planeSize;
+                if (outputChannels == 3)
+                {
+                    *((K*)&output[output_offset0]) = convertTo<T, K>(((T*)&input[input_offset])[2]);
+                    *((K*)&output[output_offset1]) = convertTo<T, K>(((T*)&input[input_offset])[1]);
+                    *((K*)&output[output_offset2]) = convertTo<T, K>(((T*)&input[input_offset])[0]);
+                }
+                else
+                {
+                    size_t output_offset3 = output_offset2 + planeSize;
+                    *((K*)&output[output_offset0]) = inputChannels > 3 ? convertTo<T, K>(((T*)&input[input_offset])[3]) : alphaMax<K>();
+                    *((K*)&output[output_offset1]) = convertTo<T, K>(((T*)&input[input_offset])[2]);
+                    *((K*)&output[output_offset2]) = convertTo<T, K>(((T*)&input[input_offset])[1]);
+                    *((K*)&output[output_offset3]) = convertTo<T, K>(((T*)&input[input_offset])[0]);
+                }
+            }
+        }
+    }
+
+    uint32_t bytesPerPixel(Fmt fmt)
+    {
+        static std::unordered_map<Fmt, uint32_t> Bpp{ {Fmt::R8G8B8A8, 4}, {Fmt::R32G32B32A32, 16}, {Fmt::R16G16B16A16, 8} };
+        return Bpp[fmt];
+    }
+
+    void load(const std::string& fileName, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& outRowPitch, Fmt outFormat, uint32_t outRowPitchAlignment)
+    {
+        std::string extension = std::filesystem::path(fileName).extension().string();
+        for (auto& e : extension) e = std::tolower(e);
+        if (extension == ".exr")
+        {
+            loadEXR(fileName, data, width, height, outRowPitch, outFormat, outRowPitchAlignment);
+        }
+        else if (extension == ".png")
+        {
+            loadPNG(fileName, data, width, height, outRowPitch, outFormat, outRowPitchAlignment);
+        }
+    }
+
+    void loadPNG(const std::string& fileName, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& outRowPitch, Fmt outFormat, uint32_t outRowPitchAlignment)
     {
-        pConvertedFrame = frame;
+        uint32_t infileChannels;
+        uint8_t* image = stbi_load(fileName.c_str(), (int*)&width, (int*)&height, (int*)&infileChannels, STBI_rgb_alpha);
+
+        if (image == nullptr)
+            throw std::runtime_error("Failed to load PNG Image : " + fileName);
+
+        uint32_t inChannels = 4; // stb_image has already converted data to RGBA
+        uint32_t inputRowPitch = width * inChannels;
+        uint32_t outChannels = 4; // Hardcoded all output formats have 4 channel
+        outRowPitch = Align(width * bytesPerPixel(outFormat), outRowPitchAlignment);
+        uint32_t imageSize = outRowPitch * height;
+        data.resize(imageSize);
+
+        switch (outFormat)
+        {
+        case Fmt::R8G8B8A8:
+            convertToFmt<uint8_t, uint8_t>(image, data.data(), width, height, inChannels, inputRowPitch, outChannels, outRowPitch);
+            break;
+        case Fmt::R32G32B32A32:
+            convertToFmt<uint8_t, float>(image, data.data(), width, height, inChannels, inputRowPitch, outChannels, outRowPitch);
+            break;
+        case Fmt::R16G16B16A16:
+            convertToFmt<uint8_t, fp16_t>(image, data.data(), width, height, inChannels, inputRowPitch, outChannels, outRowPitch);
+            break;
+        }
+
+        stbi_image_free(image);
+    }
+
+    void loadEXR(const std::string& fileName, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& outRowPitch, Fmt outFormat, uint32_t outRowPitchAlignment)
+    {
+        uint32_t inChannels = 4; // fixed to only 4 channel EXR files
+        float* image;
+        const char* err = nullptr;
+        int ret = LoadEXR(&image, (int*)&width, (int*)&height, fileName.c_str(), &err);
+        uint32_t inputRowPitch = width * inChannels * sizeof(float);
+
+        if (ret != TINYEXR_SUCCESS) {
+            std::string serr = err;
+            FreeEXRErrorMessage(err);
+            throw std::runtime_error("Failed to load EXR Image : " + fileName + " Error: " + serr);
+        }
+
+        uint32_t outChannels = 4; // Hardcoded all output formats have 4 channel
+        outRowPitch = Align(width * bytesPerPixel(outFormat), outRowPitchAlignment);
+        uint32_t imageSize = outRowPitch * height;
+        data.resize(imageSize);
+
+        switch (outFormat)
+        {
+        case Fmt::R8G8B8A8:
+            convertToFmt<float, uint8_t>((uint8_t*)image, data.data(), width, height, inChannels, inputRowPitch, outChannels, outRowPitch);
+            break;
+        case Fmt::R32G32B32A32:
+            convertToFmt<float, float>((uint8_t*)image, data.data(), width, height, inChannels, inputRowPitch, outChannels, outRowPitch);
+            break;
+        case Fmt::R16G16B16A16:
+            convertToFmt<float, fp16_t>((uint8_t*)image, data.data(), width, height, inChannels, inputRowPitch, outChannels, outRowPitch);
+            break;
+        }
+        free(image);
+    }
+
+    void save(const std::string& fileName, uint8_t* data, uint32_t width, uint32_t height, uint32_t channels, uint32_t rowPitch, Fmt format)
+    {
+        std::string extension = std::filesystem::path(fileName).extension().string();
+        for (auto& e : extension) e = std::tolower(e);
+        if (extension == ".exr")
+        {
+            saveEXR(fileName, data, width, height, channels, rowPitch, format);
+        }
+        else if (extension == ".png")
+        {
+            savePNG(fileName, data, width, height, channels, rowPitch, format);
+        }
+    }
+
+    void savePNG(const std::string& fileName, uint8_t* data, uint32_t width, uint32_t height, uint32_t channels, uint32_t rowPitch, Fmt format)
+    {
+        constexpr uint32_t outputChannels = 4;
+        std::vector<uint8_t> image(size_t(width) * height * outputChannels);
+        uint32_t outputRowPitch = width * outputChannels * sizeof(uint8_t);
+
+        switch (format)
+        {
+        case Fmt::R8G8B8A8:
+            convertToFmt<uint8_t, uint8_t>(data, image.data(), width, height, channels, rowPitch, outputChannels, outputRowPitch);
+            break;
+        case Fmt::R32G32B32A32:
+            convertToFmt<float, uint8_t>(data, image.data(), width, height, channels, rowPitch, outputChannels, outputRowPitch);
+            break;
+
+        case Fmt::R16G16B16A16:
+            convertToFmt<fp16_t, uint8_t>(data, image.data(), width, height, channels, rowPitch, outputChannels, outputRowPitch);
+            break;
+        }
+        stbi_write_png(fileName.c_str(), width, height, outputChannels, image.data(), outputRowPitch);
+    }
+
+
+    void saveEXR(const std::string& fileName, uint8_t* data, uint32_t width, uint32_t height, uint32_t channels, uint32_t rowPitch, Fmt format)
+    {
+        EXRHeader header;
+        InitEXRHeader(&header);
+        EXRImage image;
+        InitEXRImage(&image);
+
+        constexpr uint32_t outputChannels = 4;
+        image.num_channels = outputChannels;
+        uint32_t plane_size = width * height;
+        uint32_t outputRowPitch = width * sizeof(float);
+        std::vector<float> images(size_t(outputChannels) * plane_size);
+        switch (format)
+        {
+        case Fmt::R8G8B8A8:
+            convertToFmtPlanesABGR<uint8_t, float>(data, (uint8_t*)images.data(), width, height, channels, rowPitch, outputChannels, outputRowPitch);
+            break;
+        case Fmt::R32G32B32A32:
+            convertToFmtPlanesABGR<float, float>(data, (uint8_t*)images.data(), width, height, channels, rowPitch, outputChannels, outputRowPitch);
+            break;
+        case Fmt::R16G16B16A16:
+            convertToFmtPlanesABGR<fp16_t, float>(data, (uint8_t*)images.data(), width, height, channels, rowPitch, outputChannels, outputRowPitch);
+            break;
+        }
+
+        float* image_ptr[outputChannels];
+        for (size_t i = 0; i < outputChannels; ++i)
+            image_ptr[i] = &images[i * plane_size];
+
+        image.images = (unsigned char**)image_ptr;
+        image.width = width;
+        image.height = height;
+
+        header.num_channels = outputChannels;
+        header.channels = (EXRChannelInfo*)malloc(sizeof(EXRChannelInfo) * header.num_channels);
+        // Must be (A)BGR order, since most of EXR viewers expect this channel order.
+        header.channels[0].name[0] = 'A'; header.channels[0].name[1] = '\0';
+        header.channels[1].name[0] = 'B'; header.channels[1].name[1] = '\0';
+        header.channels[2].name[0] = 'G'; header.channels[2].name[1] = '\0';
+        header.channels[3].name[0] = 'R'; header.channels[3].name[1] = '\0';
+
+        header.pixel_types = (int*)malloc(sizeof(int) * header.num_channels);
+        header.requested_pixel_types = (int*)malloc(sizeof(int) * header.num_channels);
+        for (int i = 0; i < header.num_channels; i++) {
+            header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+            header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+        }
+
+        const char* err = nullptr;
+        int ret = SaveEXRImageToFile(&image, &header, fileName.c_str(), &err);
+        if (ret != TINYEXR_SUCCESS) {
+            std::string serr = err;
+            FreeEXRErrorMessage(err);
+            throw std::runtime_error("Failed to save EXR Image : " + fileName + " Error: " + serr);
+        }
+        free(header.channels);
+        free(header.pixel_types);
+        free(header.requested_pixel_types);
     }
-    DX::ThrowIfFailed(pConvertedFrame->GetPixelFormat(&pixelFormat));
-    ComPtr<IWICComponentInfo> cinfo;
-    DX::ThrowIfFailed(m_WICFactory->CreateComponentInfo(pixelFormat, &cinfo));
-    ComPtr<IWICPixelFormatInfo> pfinfo;
-    DX::ThrowIfFailed(cinfo->QueryInterface(__uuidof(IWICPixelFormatInfo), &pfinfo));
-    DX::ThrowIfFailed(pfinfo->GetBitsPerPixel(&m_bpp));
-    m_rowPitch = (m_width * m_bpp + 7) / 8;
-    m_imageSize = m_rowPitch * m_height;
-    m_data.resize(m_imageSize);
-    DX::ThrowIfFailed(pConvertedFrame->CopyPixels(0, m_rowPitch, m_imageSize, m_data.data()));
 }

+ 23 - 29
samples/common/Image.h

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -20,34 +20,28 @@
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
+#define NOMINMAX
 
-#include <filesystem>
 #include <iostream>
 #include <string>
 #include <vector>
-#include <wincodec.h>
-#include <wrl.h>
 
-using namespace Microsoft::WRL;
-
-class Image
+namespace img
 {
-public:
-    Image();
-    void load(const std::filesystem::path& FilePath);
-    uint32_t width() { return m_width; }
-    uint32_t height() { return m_height; }
-    uint32_t bpp() { return m_bpp; }
-    uint32_t rowPitch() { return m_rowPitch; }
-    uint32_t imageSize() { return m_imageSize; }
-    uint8_t* data() { return m_data.data(); }
-protected:
-    void LoadWIC(const std::wstring& filename);
-private:    
-    uint32_t m_width, m_height;
-    uint32_t m_bpp;
-    std::vector<uint8_t> m_data;
-    uint32_t m_rowPitch;
-    uint32_t m_imageSize;
-    ComPtr<IWICImagingFactory> m_WICFactory;
-};
+    enum class Fmt : uint8_t
+    {
+        R8G8B8A8 = 0,
+        R32G32B32A32 = 1,
+        R16G16B16A16 = 2
+    };
+
+    uint32_t bytesPerPixel(Fmt fmt);
+
+    void load(const std::string& fileName, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& outRowPitch, Fmt outFormat, uint32_t outRowPitchAlignment = 1);
+    void loadPNG(const std::string& fileName, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& outRowPitch, Fmt outFormat, uint32_t outRowPitchAlignment = 1);
+    void loadEXR(const std::string& fileName, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& outRowPitch, Fmt outFormat, uint32_t outRowPitchAlignment = 1);
+
+    void save(const std::string& fileName, uint8_t* data, uint32_t width, uint32_t height, uint32_t channels, uint32_t rowPitch, Fmt format);
+    void savePNG(const std::string& fileName, uint8_t* data, uint32_t width, uint32_t height, uint32_t channels, uint32_t rowPitch, Fmt format);
+    void saveEXR(const std::string& fileName, uint8_t* data, uint32_t width, uint32_t height, uint32_t channels, uint32_t rowPitch, Fmt format);
+}

+ 14 - 10
samples/common/Utilities.h

@@ -1,17 +1,17 @@
 // The MIT License(MIT)
-// 
+//
 // Copyright(c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-// 
+//
 // Permission is hereby granted, free of charge, to any person obtaining a copy of
 // this software and associated documentation files(the "Software"), to deal in
 // the Software without restriction, including without limitation the rights to
 // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
 // the Software, and to permit persons to whom the Software is furnished to do so,
 // subject to the following conditions :
-// 
+//
 // The above copyright notice and this permission notice shall be included in all
 // copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
@@ -53,15 +53,15 @@ public:
         m_t0 = m_t1;
         m_numFrames++;
         // update only when time is up
-        if (m_totalTime > m_maxTime) 
+        if (m_totalTime > m_maxTime)
         {
             m_averageTime = m_totalTime / m_numFrames;
             m_totalTime = 0.0;
             m_numFrames = 0;
         }
     }
-    void setMaxTime(double maxTime) { 
-        m_maxTime = maxTime; 
+    void setMaxTime(double maxTime) {
+        m_maxTime = maxTime;
     }
     double averageTime_us() {
         return m_averageTime;
@@ -77,7 +77,7 @@ private:
     double m_totalTime;
     double m_averageTime;
     size_t m_numFrames;
-    std::chrono::steady_clock::time_point m_t0, m_t1;
+    std::chrono::high_resolution_clock::time_point m_t0, m_t1;
 };
 
 class ElapsedTimer {
@@ -113,7 +113,7 @@ private:
     double m_totalTime;
     double m_averageTime;
     size_t m_numIterations;
-    std::chrono::steady_clock::time_point m_t0, m_t1;
+    std::chrono::high_resolution_clock::time_point m_t0, m_t1;
 };
 
 
@@ -177,7 +177,7 @@ private:
     std::string programName;
 };
 
-
+#ifndef NIS_VK_SAMPLE
 inline std::wstring widen(const std::string& str)
 {
     int size = MultiByteToWideChar(CP_ACP, 0, str.c_str(), int(str.size()) + 1, 0, 0);
@@ -185,6 +185,7 @@ inline std::wstring widen(const std::string& str)
     MultiByteToWideChar(CP_ACP, 0, str.c_str(), int(str.size()) + 1, &temp[0], int(temp.size()));
     return std::wstring(&temp[0]);
 }
+#endif
 
 template <typename T>
 inline std::string toStr(T value)
@@ -210,4 +211,7 @@ inline std::string toStr<const char*>(const char* value)
     return value;
 }
 
+inline uint32_t Align(uint32_t x, uint32_t alignment) {
+    return (x + alignment - 1) / alignment * alignment;
+}
 

BIN
samples/third_party/DXC/bin/x64/dxc.exe


+ 459 - 0
samples/third_party/DXC/inc/d3d12shader.h

@@ -0,0 +1,459 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+//  Copyright (c) Microsoft Corporation.  All rights reserved.
+//
+//  File:       D3D12Shader.h
+//  Content:    D3D12 Shader Types and APIs
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __D3D12SHADER_H__
+#define __D3D12SHADER_H__
+
+#include "d3dcommon.h"
+
+typedef enum D3D12_SHADER_VERSION_TYPE
+{
+    D3D12_SHVER_PIXEL_SHADER    = 0,
+    D3D12_SHVER_VERTEX_SHADER   = 1,
+    D3D12_SHVER_GEOMETRY_SHADER = 2,
+    
+    // D3D11 Shaders
+    D3D12_SHVER_HULL_SHADER     = 3,
+    D3D12_SHVER_DOMAIN_SHADER   = 4,
+    D3D12_SHVER_COMPUTE_SHADER  = 5,
+
+    D3D12_SHVER_RESERVED0       = 0xFFF0,
+} D3D12_SHADER_VERSION_TYPE;
+
+#define D3D12_SHVER_GET_TYPE(_Version) \
+    (((_Version) >> 16) & 0xffff)
+#define D3D12_SHVER_GET_MAJOR(_Version) \
+    (((_Version) >> 4) & 0xf)
+#define D3D12_SHVER_GET_MINOR(_Version) \
+    (((_Version) >> 0) & 0xf)
+
+// Slot ID for library function return
+#define D3D_RETURN_PARAMETER_INDEX (-1)
+
+typedef D3D_RESOURCE_RETURN_TYPE D3D12_RESOURCE_RETURN_TYPE;
+
+typedef D3D_CBUFFER_TYPE D3D12_CBUFFER_TYPE;
+
+
+typedef struct _D3D12_SIGNATURE_PARAMETER_DESC
+{
+    LPCSTR                      SemanticName;   // Name of the semantic
+    UINT                        SemanticIndex;  // Index of the semantic
+    UINT                        Register;       // Number of member variables
+    D3D_NAME                    SystemValueType;// A predefined system value, or D3D_NAME_UNDEFINED if not applicable
+    D3D_REGISTER_COMPONENT_TYPE ComponentType;  // Scalar type (e.g. uint, float, etc.)
+    BYTE                        Mask;           // Mask to indicate which components of the register
+                                                // are used (combination of D3D10_COMPONENT_MASK values)
+    BYTE                        ReadWriteMask;  // Mask to indicate whether a given component is 
+                                                // never written (if this is an output signature) or
+                                                // always read (if this is an input signature).
+                                                // (combination of D3D_MASK_* values)
+    UINT                        Stream;         // Stream index
+    D3D_MIN_PRECISION           MinPrecision;   // Minimum desired interpolation precision
+} D3D12_SIGNATURE_PARAMETER_DESC;
+
+typedef struct _D3D12_SHADER_BUFFER_DESC
+{
+    LPCSTR                  Name;           // Name of the constant buffer
+    D3D_CBUFFER_TYPE        Type;           // Indicates type of buffer content
+    UINT                    Variables;      // Number of member variables
+    UINT                    Size;           // Size of CB (in bytes)
+    UINT                    uFlags;         // Buffer description flags
+} D3D12_SHADER_BUFFER_DESC;
+
+typedef struct _D3D12_SHADER_VARIABLE_DESC
+{
+    LPCSTR                  Name;           // Name of the variable
+    UINT                    StartOffset;    // Offset in constant buffer's backing store
+    UINT                    Size;           // Size of variable (in bytes)
+    UINT                    uFlags;         // Variable flags
+    LPVOID                  DefaultValue;   // Raw pointer to default value
+    UINT                    StartTexture;   // First texture index (or -1 if no textures used)
+    UINT                    TextureSize;    // Number of texture slots possibly used.
+    UINT                    StartSampler;   // First sampler index (or -1 if no textures used)
+    UINT                    SamplerSize;    // Number of sampler slots possibly used.
+} D3D12_SHADER_VARIABLE_DESC;
+
+typedef struct _D3D12_SHADER_TYPE_DESC
+{
+    D3D_SHADER_VARIABLE_CLASS   Class;          // Variable class (e.g. object, matrix, etc.)
+    D3D_SHADER_VARIABLE_TYPE    Type;           // Variable type (e.g. float, sampler, etc.)
+    UINT                        Rows;           // Number of rows (for matrices, 1 for other numeric, 0 if not applicable)
+    UINT                        Columns;        // Number of columns (for vectors & matrices, 1 for other numeric, 0 if not applicable)
+    UINT                        Elements;       // Number of elements (0 if not an array)
+    UINT                        Members;        // Number of members (0 if not a structure)
+    UINT                        Offset;         // Offset from the start of structure (0 if not a structure member)
+    LPCSTR                      Name;           // Name of type, can be NULL
+} D3D12_SHADER_TYPE_DESC;
+
+typedef D3D_TESSELLATOR_DOMAIN D3D12_TESSELLATOR_DOMAIN;
+
+typedef D3D_TESSELLATOR_PARTITIONING D3D12_TESSELLATOR_PARTITIONING;
+
+typedef D3D_TESSELLATOR_OUTPUT_PRIMITIVE D3D12_TESSELLATOR_OUTPUT_PRIMITIVE;
+
+typedef struct _D3D12_SHADER_DESC
+{
+    UINT                    Version;                     // Shader version
+    LPCSTR                  Creator;                     // Creator string
+    UINT                    Flags;                       // Shader compilation/parse flags
+    
+    UINT                    ConstantBuffers;             // Number of constant buffers
+    UINT                    BoundResources;              // Number of bound resources
+    UINT                    InputParameters;             // Number of parameters in the input signature
+    UINT                    OutputParameters;            // Number of parameters in the output signature
+
+    UINT                    InstructionCount;            // Number of emitted instructions
+    UINT                    TempRegisterCount;           // Number of temporary registers used 
+    UINT                    TempArrayCount;              // Number of temporary arrays used
+    UINT                    DefCount;                    // Number of constant defines 
+    UINT                    DclCount;                    // Number of declarations (input + output)
+    UINT                    TextureNormalInstructions;   // Number of non-categorized texture instructions
+    UINT                    TextureLoadInstructions;     // Number of texture load instructions
+    UINT                    TextureCompInstructions;     // Number of texture comparison instructions
+    UINT                    TextureBiasInstructions;     // Number of texture bias instructions
+    UINT                    TextureGradientInstructions; // Number of texture gradient instructions
+    UINT                    FloatInstructionCount;       // Number of floating point arithmetic instructions used
+    UINT                    IntInstructionCount;         // Number of signed integer arithmetic instructions used
+    UINT                    UintInstructionCount;        // Number of unsigned integer arithmetic instructions used
+    UINT                    StaticFlowControlCount;      // Number of static flow control instructions used
+    UINT                    DynamicFlowControlCount;     // Number of dynamic flow control instructions used
+    UINT                    MacroInstructionCount;       // Number of macro instructions used
+    UINT                    ArrayInstructionCount;       // Number of array instructions used
+    UINT                    CutInstructionCount;         // Number of cut instructions used
+    UINT                    EmitInstructionCount;        // Number of emit instructions used
+    D3D_PRIMITIVE_TOPOLOGY  GSOutputTopology;            // Geometry shader output topology
+    UINT                    GSMaxOutputVertexCount;      // Geometry shader maximum output vertex count
+    D3D_PRIMITIVE           InputPrimitive;              // GS/HS input primitive
+    UINT                    PatchConstantParameters;     // Number of parameters in the patch constant signature
+    UINT                    cGSInstanceCount;            // Number of Geometry shader instances
+    UINT                    cControlPoints;              // Number of control points in the HS->DS stage
+    D3D_TESSELLATOR_OUTPUT_PRIMITIVE HSOutputPrimitive;  // Primitive output by the tessellator
+    D3D_TESSELLATOR_PARTITIONING HSPartitioning;         // Partitioning mode of the tessellator
+    D3D_TESSELLATOR_DOMAIN  TessellatorDomain;           // Domain of the tessellator (quad, tri, isoline)
+    // instruction counts
+    UINT cBarrierInstructions;                           // Number of barrier instructions in a compute shader
+    UINT cInterlockedInstructions;                       // Number of interlocked instructions
+    UINT cTextureStoreInstructions;                      // Number of texture writes
+} D3D12_SHADER_DESC;
+
+typedef struct _D3D12_SHADER_INPUT_BIND_DESC
+{
+    LPCSTR                      Name;           // Name of the resource
+    D3D_SHADER_INPUT_TYPE       Type;           // Type of resource (e.g. texture, cbuffer, etc.)
+    UINT                        BindPoint;      // Starting bind point
+    UINT                        BindCount;      // Number of contiguous bind points (for arrays)
+
+    UINT                        uFlags;         // Input binding flags
+    D3D_RESOURCE_RETURN_TYPE    ReturnType;     // Return type (if texture)
+    D3D_SRV_DIMENSION           Dimension;      // Dimension (if texture)
+    UINT                        NumSamples;     // Number of samples (0 if not MS texture)
+    UINT                        Space;          // Register space
+    UINT uID;                                   // Range ID in the bytecode
+} D3D12_SHADER_INPUT_BIND_DESC;
+
+#define D3D_SHADER_REQUIRES_DOUBLES                                                         0x00000001
+#define D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL                                             0x00000002
+#define D3D_SHADER_REQUIRES_UAVS_AT_EVERY_STAGE                                             0x00000004
+#define D3D_SHADER_REQUIRES_64_UAVS                                                         0x00000008
+#define D3D_SHADER_REQUIRES_MINIMUM_PRECISION                                               0x00000010
+#define D3D_SHADER_REQUIRES_11_1_DOUBLE_EXTENSIONS                                          0x00000020
+#define D3D_SHADER_REQUIRES_11_1_SHADER_EXTENSIONS                                          0x00000040
+#define D3D_SHADER_REQUIRES_LEVEL_9_COMPARISON_FILTERING                                    0x00000080
+#define D3D_SHADER_REQUIRES_TILED_RESOURCES                                                 0x00000100
+#define D3D_SHADER_REQUIRES_STENCIL_REF                                                     0x00000200
+#define D3D_SHADER_REQUIRES_INNER_COVERAGE                                                  0x00000400
+#define D3D_SHADER_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS                               0x00000800
+#define D3D_SHADER_REQUIRES_ROVS                                                            0x00001000
+#define D3D_SHADER_REQUIRES_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER  0x00002000
+
+
+typedef struct _D3D12_LIBRARY_DESC
+{
+    LPCSTR    Creator;           // The name of the originator of the library.
+    UINT      Flags;             // Compilation flags.
+    UINT      FunctionCount;     // Number of functions exported from the library.
+} D3D12_LIBRARY_DESC;
+
+typedef struct _D3D12_FUNCTION_DESC
+{
+    UINT                    Version;                     // Shader version
+    LPCSTR                  Creator;                     // Creator string
+    UINT                    Flags;                       // Shader compilation/parse flags
+    
+    UINT                    ConstantBuffers;             // Number of constant buffers
+    UINT                    BoundResources;              // Number of bound resources
+
+    UINT                    InstructionCount;            // Number of emitted instructions
+    UINT                    TempRegisterCount;           // Number of temporary registers used 
+    UINT                    TempArrayCount;              // Number of temporary arrays used
+    UINT                    DefCount;                    // Number of constant defines 
+    UINT                    DclCount;                    // Number of declarations (input + output)
+    UINT                    TextureNormalInstructions;   // Number of non-categorized texture instructions
+    UINT                    TextureLoadInstructions;     // Number of texture load instructions
+    UINT                    TextureCompInstructions;     // Number of texture comparison instructions
+    UINT                    TextureBiasInstructions;     // Number of texture bias instructions
+    UINT                    TextureGradientInstructions; // Number of texture gradient instructions
+    UINT                    FloatInstructionCount;       // Number of floating point arithmetic instructions used
+    UINT                    IntInstructionCount;         // Number of signed integer arithmetic instructions used
+    UINT                    UintInstructionCount;        // Number of unsigned integer arithmetic instructions used
+    UINT                    StaticFlowControlCount;      // Number of static flow control instructions used
+    UINT                    DynamicFlowControlCount;     // Number of dynamic flow control instructions used
+    UINT                    MacroInstructionCount;       // Number of macro instructions used
+    UINT                    ArrayInstructionCount;       // Number of array instructions used
+    UINT                    MovInstructionCount;         // Number of mov instructions used
+    UINT                    MovcInstructionCount;        // Number of movc instructions used
+    UINT                    ConversionInstructionCount;  // Number of type conversion instructions used
+    UINT                    BitwiseInstructionCount;     // Number of bitwise arithmetic instructions used
+    D3D_FEATURE_LEVEL       MinFeatureLevel;             // Min target of the function byte code
+    UINT64                  RequiredFeatureFlags;        // Required feature flags
+
+    LPCSTR                  Name;                        // Function name
+    INT                     FunctionParameterCount;      // Number of logical parameters in the function signature (not including return)
+    BOOL                    HasReturn;                   // TRUE, if function returns a value, false - it is a subroutine
+    BOOL                    Has10Level9VertexShader;     // TRUE, if there is a 10L9 VS blob
+    BOOL                    Has10Level9PixelShader;      // TRUE, if there is a 10L9 PS blob
+} D3D12_FUNCTION_DESC;
+
+typedef struct _D3D12_PARAMETER_DESC
+{
+    LPCSTR                      Name;               // Parameter name.
+    LPCSTR                      SemanticName;       // Parameter semantic name (+index).
+    D3D_SHADER_VARIABLE_TYPE    Type;               // Element type.
+    D3D_SHADER_VARIABLE_CLASS   Class;              // Scalar/Vector/Matrix.
+    UINT                        Rows;               // Rows are for matrix parameters.
+    UINT                        Columns;            // Components or Columns in matrix.
+    D3D_INTERPOLATION_MODE      InterpolationMode;  // Interpolation mode.
+    D3D_PARAMETER_FLAGS         Flags;              // Parameter modifiers.
+
+    UINT                        FirstInRegister;    // The first input register for this parameter.
+    UINT                        FirstInComponent;   // The first input register component for this parameter.
+    UINT                        FirstOutRegister;   // The first output register for this parameter.
+    UINT                        FirstOutComponent;  // The first output register component for this parameter.
+} D3D12_PARAMETER_DESC;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Interfaces ////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+typedef interface ID3D12ShaderReflectionType ID3D12ShaderReflectionType;
+typedef interface ID3D12ShaderReflectionType *LPD3D12SHADERREFLECTIONTYPE;
+
+typedef interface ID3D12ShaderReflectionVariable ID3D12ShaderReflectionVariable;
+typedef interface ID3D12ShaderReflectionVariable *LPD3D12SHADERREFLECTIONVARIABLE;
+
+typedef interface ID3D12ShaderReflectionConstantBuffer ID3D12ShaderReflectionConstantBuffer;
+typedef interface ID3D12ShaderReflectionConstantBuffer *LPD3D12SHADERREFLECTIONCONSTANTBUFFER;
+
+typedef interface ID3D12ShaderReflection ID3D12ShaderReflection;
+typedef interface ID3D12ShaderReflection *LPD3D12SHADERREFLECTION;
+
+typedef interface ID3D12LibraryReflection ID3D12LibraryReflection;
+typedef interface ID3D12LibraryReflection *LPD3D12LIBRARYREFLECTION;
+
+typedef interface ID3D12FunctionReflection ID3D12FunctionReflection;
+typedef interface ID3D12FunctionReflection *LPD3D12FUNCTIONREFLECTION;
+
+typedef interface ID3D12FunctionParameterReflection ID3D12FunctionParameterReflection;
+typedef interface ID3D12FunctionParameterReflection *LPD3D12FUNCTIONPARAMETERREFLECTION;
+
+
+// {E913C351-783D-48CA-A1D1-4F306284AD56}
+interface DECLSPEC_UUID("E913C351-783D-48CA-A1D1-4F306284AD56") ID3D12ShaderReflectionType;
+DEFINE_GUID(IID_ID3D12ShaderReflectionType, 
+0xe913c351, 0x783d, 0x48ca, 0xa1, 0xd1, 0x4f, 0x30, 0x62, 0x84, 0xad, 0x56);
+
+#undef INTERFACE
+#define INTERFACE ID3D12ShaderReflectionType
+
+DECLARE_INTERFACE(ID3D12ShaderReflectionType)
+{
+    STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_TYPE_DESC *pDesc) PURE;
+    
+    STDMETHOD_(ID3D12ShaderReflectionType*, GetMemberTypeByIndex)(THIS_ _In_ UINT Index) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionType*, GetMemberTypeByName)(THIS_ _In_ LPCSTR Name) PURE;
+    STDMETHOD_(LPCSTR, GetMemberTypeName)(THIS_ _In_ UINT Index) PURE;
+
+    STDMETHOD(IsEqual)(THIS_ _In_ ID3D12ShaderReflectionType* pType) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionType*, GetSubType)(THIS) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionType*, GetBaseClass)(THIS) PURE;
+    STDMETHOD_(UINT, GetNumInterfaces)(THIS) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionType*, GetInterfaceByIndex)(THIS_ _In_ UINT uIndex) PURE;
+    STDMETHOD(IsOfType)(THIS_ _In_ ID3D12ShaderReflectionType* pType) PURE;
+    STDMETHOD(ImplementsInterface)(THIS_ _In_ ID3D12ShaderReflectionType* pBase) PURE;
+};
+
+// {8337A8A6-A216-444A-B2F4-314733A73AEA}
+interface DECLSPEC_UUID("8337A8A6-A216-444A-B2F4-314733A73AEA") ID3D12ShaderReflectionVariable;
+DEFINE_GUID(IID_ID3D12ShaderReflectionVariable, 
+0x8337a8a6, 0xa216, 0x444a, 0xb2, 0xf4, 0x31, 0x47, 0x33, 0xa7, 0x3a, 0xea);
+
+#undef INTERFACE
+#define INTERFACE ID3D12ShaderReflectionVariable
+
+DECLARE_INTERFACE(ID3D12ShaderReflectionVariable)
+{
+    STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_VARIABLE_DESC *pDesc) PURE;
+    
+    STDMETHOD_(ID3D12ShaderReflectionType*, GetType)(THIS) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetBuffer)(THIS) PURE;
+
+    STDMETHOD_(UINT, GetInterfaceSlot)(THIS_ _In_ UINT uArrayIndex) PURE;
+};
+
+// {C59598B4-48B3-4869-B9B1-B1618B14A8B7}
+interface DECLSPEC_UUID("C59598B4-48B3-4869-B9B1-B1618B14A8B7") ID3D12ShaderReflectionConstantBuffer;
+DEFINE_GUID(IID_ID3D12ShaderReflectionConstantBuffer, 
+0xc59598b4, 0x48b3, 0x4869, 0xb9, 0xb1, 0xb1, 0x61, 0x8b, 0x14, 0xa8, 0xb7);
+
+#undef INTERFACE
+#define INTERFACE ID3D12ShaderReflectionConstantBuffer
+
+DECLARE_INTERFACE(ID3D12ShaderReflectionConstantBuffer)
+{
+    STDMETHOD(GetDesc)(THIS_ D3D12_SHADER_BUFFER_DESC *pDesc) PURE;
+    
+    STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByIndex)(THIS_ _In_ UINT Index) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
+};
+
+// The ID3D12ShaderReflection IID may change from SDK version to SDK version
+// if the reflection API changes.  This prevents new code with the new API
+// from working with an old binary.  Recompiling with the new header
+// will pick up the new IID.
+
+// {5A58797D-A72C-478D-8BA2-EFC6B0EFE88E}
+interface DECLSPEC_UUID("5A58797D-A72C-478D-8BA2-EFC6B0EFE88E") ID3D12ShaderReflection;
+DEFINE_GUID(IID_ID3D12ShaderReflection, 
+0x5a58797d, 0xa72c, 0x478d, 0x8b, 0xa2, 0xef, 0xc6, 0xb0, 0xef, 0xe8, 0x8e);
+
+#undef INTERFACE
+#define INTERFACE ID3D12ShaderReflection
+
+DECLARE_INTERFACE_(ID3D12ShaderReflection, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ _In_ REFIID iid,
+                              _Out_ LPVOID *ppv) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+
+    STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_DESC *pDesc) PURE;
+    
+    STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ _In_ UINT Index) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ _In_ LPCSTR Name) PURE;
+    
+    STDMETHOD(GetResourceBindingDesc)(THIS_ _In_ UINT ResourceIndex,
+                                      _Out_ D3D12_SHADER_INPUT_BIND_DESC *pDesc) PURE;
+    
+    STDMETHOD(GetInputParameterDesc)(THIS_ _In_ UINT ParameterIndex,
+                                     _Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
+    STDMETHOD(GetOutputParameterDesc)(THIS_ _In_ UINT ParameterIndex,
+                                      _Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
+    STDMETHOD(GetPatchConstantParameterDesc)(THIS_ _In_ UINT ParameterIndex,
+                                             _Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
+
+    STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
+
+    STDMETHOD(GetResourceBindingDescByName)(THIS_ _In_ LPCSTR Name,
+                                            _Out_ D3D12_SHADER_INPUT_BIND_DESC *pDesc) PURE;
+
+    STDMETHOD_(UINT, GetMovInstructionCount)(THIS) PURE;
+    STDMETHOD_(UINT, GetMovcInstructionCount)(THIS) PURE;
+    STDMETHOD_(UINT, GetConversionInstructionCount)(THIS) PURE;
+    STDMETHOD_(UINT, GetBitwiseInstructionCount)(THIS) PURE;
+    
+    STDMETHOD_(D3D_PRIMITIVE, GetGSInputPrimitive)(THIS) PURE;
+    STDMETHOD_(BOOL, IsSampleFrequencyShader)(THIS) PURE;
+
+    STDMETHOD_(UINT, GetNumInterfaceSlots)(THIS) PURE;
+    STDMETHOD(GetMinFeatureLevel)(THIS_ _Out_ enum D3D_FEATURE_LEVEL* pLevel) PURE;
+
+    STDMETHOD_(UINT, GetThreadGroupSize)(THIS_
+                                         _Out_opt_ UINT* pSizeX,
+                                         _Out_opt_ UINT* pSizeY,
+                                         _Out_opt_ UINT* pSizeZ) PURE;
+
+    STDMETHOD_(UINT64, GetRequiresFlags)(THIS) PURE;
+};
+
+// {8E349D19-54DB-4A56-9DC9-119D87BDB804}
+interface DECLSPEC_UUID("8E349D19-54DB-4A56-9DC9-119D87BDB804") ID3D12LibraryReflection;
+DEFINE_GUID(IID_ID3D12LibraryReflection, 
+0x8e349d19, 0x54db, 0x4a56, 0x9d, 0xc9, 0x11, 0x9d, 0x87, 0xbd, 0xb8, 0x4);
+
+#undef INTERFACE
+#define INTERFACE ID3D12LibraryReflection
+
+DECLARE_INTERFACE_(ID3D12LibraryReflection, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ _In_ REFIID iid, _Out_ LPVOID * ppv) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+
+    STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_LIBRARY_DESC * pDesc) PURE;
+    
+    STDMETHOD_(ID3D12FunctionReflection *, GetFunctionByIndex)(THIS_ _In_ INT FunctionIndex) PURE;
+};
+
+// {1108795C-2772-4BA9-B2A8-D464DC7E2799}
+interface DECLSPEC_UUID("1108795C-2772-4BA9-B2A8-D464DC7E2799") ID3D12FunctionReflection;
+DEFINE_GUID(IID_ID3D12FunctionReflection, 
+0x1108795c, 0x2772, 0x4ba9, 0xb2, 0xa8, 0xd4, 0x64, 0xdc, 0x7e, 0x27, 0x99);
+
+#undef INTERFACE
+#define INTERFACE ID3D12FunctionReflection
+
+DECLARE_INTERFACE(ID3D12FunctionReflection)
+{
+    STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_FUNCTION_DESC * pDesc) PURE;
+    
+    STDMETHOD_(ID3D12ShaderReflectionConstantBuffer *, GetConstantBufferByIndex)(THIS_ _In_ UINT BufferIndex) PURE;
+    STDMETHOD_(ID3D12ShaderReflectionConstantBuffer *, GetConstantBufferByName)(THIS_ _In_ LPCSTR Name) PURE;
+    
+    STDMETHOD(GetResourceBindingDesc)(THIS_ _In_ UINT ResourceIndex,
+                                      _Out_ D3D12_SHADER_INPUT_BIND_DESC * pDesc) PURE;
+    
+    STDMETHOD_(ID3D12ShaderReflectionVariable *, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
+
+    STDMETHOD(GetResourceBindingDescByName)(THIS_ _In_ LPCSTR Name,
+                                            _Out_ D3D12_SHADER_INPUT_BIND_DESC * pDesc) PURE;
+
+    // Use D3D_RETURN_PARAMETER_INDEX to get description of the return value.
+    STDMETHOD_(ID3D12FunctionParameterReflection *, GetFunctionParameter)(THIS_ _In_ INT ParameterIndex) PURE;
+};
+
+// {EC25F42D-7006-4F2B-B33E-02CC3375733F}
+interface DECLSPEC_UUID("EC25F42D-7006-4F2B-B33E-02CC3375733F") ID3D12FunctionParameterReflection;
+DEFINE_GUID(IID_ID3D12FunctionParameterReflection, 
+0xec25f42d, 0x7006, 0x4f2b, 0xb3, 0x3e, 0x2, 0xcc, 0x33, 0x75, 0x73, 0x3f);
+
+#undef INTERFACE
+#define INTERFACE ID3D12FunctionParameterReflection
+
+DECLARE_INTERFACE(ID3D12FunctionParameterReflection)
+{
+    STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_PARAMETER_DESC * pDesc) PURE;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// APIs //////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+#ifdef __cplusplus
+}
+#endif //__cplusplus
+    
+#endif //__D3D12SHADER_H__
+

+ 693 - 0
samples/third_party/DXC/inc/dxcapi.h

@@ -0,0 +1,693 @@
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// dxcapi.h                                                                  //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Provides declarations for the DirectX Compiler API entry point.           //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef __DXC_API__
+#define __DXC_API__
+
+#ifdef _WIN32
+#ifndef DXC_API_IMPORT
+#define DXC_API_IMPORT __declspec(dllimport)
+#endif
+#else
+#ifndef DXC_API_IMPORT
+#define DXC_API_IMPORT __attribute__ ((visibility ("default")))
+#endif
+#endif
+
+#ifdef _WIN32
+#define DECLARE_CROSS_PLATFORM_UUIDOF(T)
+#define DEFINE_CROSS_PLATFORM_UUIDOF(T)
+#else
+#include <dlfcn.h>
+#include "dxc/Support/WinAdapter.h"
+#endif
+
+struct IMalloc;
+
+struct IDxcIncludeHandler;
+
+typedef HRESULT (__stdcall *DxcCreateInstanceProc)(
+    _In_ REFCLSID   rclsid,
+    _In_ REFIID     riid,
+    _Out_ LPVOID*   ppv
+);
+
+typedef HRESULT(__stdcall *DxcCreateInstance2Proc)(
+  _In_ IMalloc    *pMalloc,
+  _In_ REFCLSID   rclsid,
+  _In_ REFIID     riid,
+  _Out_ LPVOID*   ppv
+  );
+
+/// <summary>
+/// Creates a single uninitialized object of the class associated with a specified CLSID.
+/// </summary>
+/// <param name="rclsid">
+/// The CLSID associated with the data and code that will be used to create the object.
+/// </param>
+/// <param name="riid">
+/// A reference to the identifier of the interface to be used to communicate 
+/// with the object.
+/// </param>
+/// <param name="ppv">
+/// Address of pointer variable that receives the interface pointer requested
+/// in riid. Upon successful return, *ppv contains the requested interface
+/// pointer. Upon failure, *ppv contains NULL.</param>
+/// <remarks>
+/// While this function is similar to CoCreateInstance, there is no COM involvement.
+/// </remarks>
+
+extern "C"
+DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance(
+  _In_ REFCLSID   rclsid,
+  _In_ REFIID     riid,
+  _Out_ LPVOID*   ppv
+  );
+
+extern "C"
+DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance2(
+  _In_ IMalloc    *pMalloc,
+  _In_ REFCLSID   rclsid,
+  _In_ REFIID     riid,
+  _Out_ LPVOID*   ppv
+);
+
+// For convenience, equivalent definitions to CP_UTF8 and CP_UTF16.
+#define DXC_CP_UTF8 65001
+#define DXC_CP_UTF16 1200
+// Use DXC_CP_ACP for: Binary;  ANSI Text;  Autodetect UTF with BOM
+#define DXC_CP_ACP 0
+
+// This flag indicates that the shader hash was computed taking into account source information (-Zss)
+#define DXC_HASHFLAG_INCLUDES_SOURCE  1
+
+// Hash digest type for ShaderHash
+typedef struct DxcShaderHash {
+  UINT32 Flags; // DXC_HASHFLAG_*
+  BYTE HashDigest[16];
+} DxcShaderHash;
+
+#define DXC_FOURCC(ch0, ch1, ch2, ch3) (                     \
+  (UINT32)(UINT8)(ch0)        | (UINT32)(UINT8)(ch1) << 8  | \
+  (UINT32)(UINT8)(ch2) << 16  | (UINT32)(UINT8)(ch3) << 24   \
+  )
+#define DXC_PART_PDB                      DXC_FOURCC('I', 'L', 'D', 'B')
+#define DXC_PART_PDB_NAME                 DXC_FOURCC('I', 'L', 'D', 'N')
+#define DXC_PART_PRIVATE_DATA             DXC_FOURCC('P', 'R', 'I', 'V')
+#define DXC_PART_ROOT_SIGNATURE           DXC_FOURCC('R', 'T', 'S', '0')
+#define DXC_PART_DXIL                     DXC_FOURCC('D', 'X', 'I', 'L')
+#define DXC_PART_REFLECTION_DATA          DXC_FOURCC('S', 'T', 'A', 'T')
+#define DXC_PART_SHADER_HASH              DXC_FOURCC('H', 'A', 'S', 'H')
+#define DXC_PART_INPUT_SIGNATURE          DXC_FOURCC('I', 'S', 'G', '1')
+#define DXC_PART_OUTPUT_SIGNATURE         DXC_FOURCC('O', 'S', 'G', '1')
+#define DXC_PART_PATCH_CONSTANT_SIGNATURE DXC_FOURCC('P', 'S', 'G', '1')
+
+// Some option arguments are defined here for continuity with D3DCompile interface
+#define DXC_ARG_DEBUG L"-Zi"
+#define DXC_ARG_SKIP_VALIDATION L"-Vd"
+#define DXC_ARG_SKIP_OPTIMIZATIONS L"-Od"
+#define DXC_ARG_PACK_MATRIX_ROW_MAJOR L"-Zpr"
+#define DXC_ARG_PACK_MATRIX_COLUMN_MAJOR L"-Zpc"
+#define DXC_ARG_AVOID_FLOW_CONTROL L"-Gfa"
+#define DXC_ARG_PREFER_FLOW_CONTROL L"-Gfp"
+#define DXC_ARG_ENABLE_STRICTNESS L"-Ges"
+#define DXC_ARG_ENABLE_BACKWARDS_COMPATIBILITY L"-Gec"
+#define DXC_ARG_IEEE_STRICTNESS L"-Gis"
+#define DXC_ARG_OPTIMIZATION_LEVEL0 L"-O0"
+#define DXC_ARG_OPTIMIZATION_LEVEL1 L"-O1"
+#define DXC_ARG_OPTIMIZATION_LEVEL2 L"-O2"
+#define DXC_ARG_OPTIMIZATION_LEVEL3 L"-O3"
+#define DXC_ARG_WARNINGS_ARE_ERRORS L"-WX"
+#define DXC_ARG_RESOURCES_MAY_ALIAS L"-res_may_alias"
+#define DXC_ARG_ALL_RESOURCES_BOUND L"-all_resources_bound"
+#define DXC_ARG_DEBUG_NAME_FOR_SOURCE L"-Zss"
+#define DXC_ARG_DEBUG_NAME_FOR_BINARY L"-Zsb"
+
+// IDxcBlob is an alias of ID3D10Blob and ID3DBlob
+struct __declspec(uuid("8BA5FB08-5195-40e2-AC58-0D989C3A0102"))
+IDxcBlob : public IUnknown {
+public:
+  virtual LPVOID STDMETHODCALLTYPE GetBufferPointer(void) = 0;
+  virtual SIZE_T STDMETHODCALLTYPE GetBufferSize(void) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlob)
+};
+
+struct __declspec(uuid("7241d424-2646-4191-97c0-98e96e42fc68"))
+IDxcBlobEncoding : public IDxcBlob {
+public:
+  virtual HRESULT STDMETHODCALLTYPE GetEncoding(_Out_ BOOL *pKnown,
+                                                _Out_ UINT32 *pCodePage) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlobEncoding)
+};
+
+// Notes on IDxcBlobUtf16 and IDxcBlobUtf8
+// These guarantee null-terminated text and the stated encoding.
+// GetBufferSize() will return the size in bytes, including null-terminator
+// GetStringLength() will return the length in characters, excluding the null-terminator
+// Name strings will use IDxcBlobUtf16, while other string output blobs,
+// such as errors/warnings, preprocessed HLSL, or other text will be based
+// on the -encoding option.
+
+// The API will use this interface for output name strings
+struct __declspec(uuid("A3F84EAB-0FAA-497E-A39C-EE6ED60B2D84"))
+IDxcBlobUtf16 : public IDxcBlobEncoding {
+public:
+  virtual LPCWSTR STDMETHODCALLTYPE GetStringPointer(void) = 0;
+  virtual SIZE_T STDMETHODCALLTYPE GetStringLength(void) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlobUtf16)
+};
+struct __declspec(uuid("3DA636C9-BA71-4024-A301-30CBF125305B"))
+IDxcBlobUtf8 : public IDxcBlobEncoding {
+public:
+  virtual LPCSTR STDMETHODCALLTYPE GetStringPointer(void) = 0;
+  virtual SIZE_T STDMETHODCALLTYPE GetStringLength(void) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcBlobUtf8)
+};
+
+struct __declspec(uuid("7f61fc7d-950d-467f-b3e3-3c02fb49187c"))
+IDxcIncludeHandler : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE LoadSource(
+    _In_z_ LPCWSTR pFilename,                                 // Candidate filename.
+    _COM_Outptr_result_maybenull_ IDxcBlob **ppIncludeSource  // Resultant source object for included file, nullptr if not found.
+    ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcIncludeHandler)
+};
+
+// Structure for supplying bytes or text input to Dxc APIs.
+// Use Encoding = 0 for non-text bytes, ANSI text, or unknown with BOM.
+typedef struct DxcBuffer {
+  LPCVOID Ptr;
+  SIZE_T Size;
+  UINT Encoding;
+} DxcText;
+
+struct DxcDefine {
+  LPCWSTR Name;
+  _Maybenull_ LPCWSTR Value;
+};
+
+struct __declspec(uuid("73EFFE2A-70DC-45F8-9690-EFF64C02429D"))
+IDxcCompilerArgs : public IUnknown {
+  // Pass GetArguments() and GetCount() to Compile
+  virtual LPCWSTR* STDMETHODCALLTYPE GetArguments() = 0;
+  virtual UINT32 STDMETHODCALLTYPE GetCount() = 0;
+
+  // Add additional arguments or defines here, if desired.
+  virtual HRESULT STDMETHODCALLTYPE AddArguments(
+    _In_opt_count_(argCount) LPCWSTR *pArguments,       // Array of pointers to arguments to add
+    _In_ UINT32 argCount                                // Number of arguments to add
+  ) = 0;
+  virtual HRESULT STDMETHODCALLTYPE AddArgumentsUTF8(
+    _In_opt_count_(argCount)LPCSTR *pArguments,         // Array of pointers to UTF-8 arguments to add
+    _In_ UINT32 argCount                                // Number of arguments to add
+  ) = 0;
+  virtual HRESULT STDMETHODCALLTYPE AddDefines(
+      _In_count_(defineCount) const DxcDefine *pDefines, // Array of defines
+      _In_ UINT32 defineCount                            // Number of defines
+  ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompilerArgs)
+};
+
+//////////////////////////
+// Legacy Interfaces
+/////////////////////////
+
+// NOTE: IDxcUtils replaces IDxcLibrary
+struct __declspec(uuid("e5204dc7-d18c-4c3c-bdfb-851673980fe7"))
+IDxcLibrary : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE SetMalloc(_In_opt_ IMalloc *pMalloc) = 0;
+  virtual HRESULT STDMETHODCALLTYPE CreateBlobFromBlob(
+    _In_ IDxcBlob *pBlob, UINT32 offset, UINT32 length, _COM_Outptr_ IDxcBlob **ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE CreateBlobFromFile(
+    _In_z_ LPCWSTR pFileName, _In_opt_ UINT32* codePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+  virtual HRESULT STDMETHODCALLTYPE CreateBlobWithEncodingFromPinned(
+    _In_bytecount_(size) LPCVOID pText, UINT32 size, UINT32 codePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+  virtual HRESULT STDMETHODCALLTYPE CreateBlobWithEncodingOnHeapCopy(
+    _In_bytecount_(size) LPCVOID pText, UINT32 size, UINT32 codePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+  virtual HRESULT STDMETHODCALLTYPE CreateBlobWithEncodingOnMalloc(
+    _In_bytecount_(size) LPCVOID pText, IMalloc *pIMalloc, UINT32 size, UINT32 codePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+  virtual HRESULT STDMETHODCALLTYPE CreateIncludeHandler(
+    _COM_Outptr_ IDxcIncludeHandler **ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE CreateStreamFromBlobReadOnly(
+    _In_ IDxcBlob *pBlob, _COM_Outptr_ IStream **ppStream) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf8(
+    _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf16(
+    _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcLibrary)
+};
+
+// NOTE: IDxcResult replaces IDxcOperationResult
+struct __declspec(uuid("CEDB484A-D4E9-445A-B991-CA21CA157DC2"))
+IDxcOperationResult : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE GetStatus(_Out_ HRESULT *pStatus) = 0;
+
+  // GetResult returns the main result of the operation.
+  // This corresponds to:
+  // DXC_OUT_OBJECT - Compile() with shader or library target
+  // DXC_OUT_DISASSEMBLY - Disassemble()
+  // DXC_OUT_HLSL - Compile() with -P
+  // DXC_OUT_ROOT_SIGNATURE - Compile() with rootsig_* target
+  virtual HRESULT STDMETHODCALLTYPE GetResult(_COM_Outptr_result_maybenull_ IDxcBlob **ppResult) = 0;
+
+  // GetErrorBuffer Corresponds to DXC_OUT_ERRORS.
+  virtual HRESULT STDMETHODCALLTYPE GetErrorBuffer(_COM_Outptr_result_maybenull_ IDxcBlobEncoding **ppErrors) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcOperationResult)
+};
+
+// NOTE: IDxcCompiler3 replaces IDxcCompiler and IDxcCompiler2
+struct __declspec(uuid("8c210bf3-011f-4422-8d70-6f9acb8db617"))
+IDxcCompiler : public IUnknown {
+  // Compile a single entry point to the target shader model
+  virtual HRESULT STDMETHODCALLTYPE Compile(
+    _In_ IDxcBlob *pSource,                       // Source text to compile
+    _In_opt_z_ LPCWSTR pSourceName,               // Optional file name for pSource. Used in errors and include handlers.
+    _In_opt_z_ LPCWSTR pEntryPoint,               // entry point name
+    _In_z_ LPCWSTR pTargetProfile,                // shader profile to compile
+    _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments
+    _In_ UINT32 argCount,                         // Number of arguments
+    _In_count_(defineCount)
+      const DxcDefine *pDefines,                  // Array of defines
+    _In_ UINT32 defineCount,                      // Number of defines
+    _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional)
+    _COM_Outptr_ IDxcOperationResult **ppResult   // Compiler output status, buffer, and errors
+  ) = 0;
+
+  // Preprocess source text
+  virtual HRESULT STDMETHODCALLTYPE Preprocess(
+    _In_ IDxcBlob *pSource,                       // Source text to preprocess
+    _In_opt_z_ LPCWSTR pSourceName,               // Optional file name for pSource. Used in errors and include handlers.
+    _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments
+    _In_ UINT32 argCount,                         // Number of arguments
+    _In_count_(defineCount)
+      const DxcDefine *pDefines,                  // Array of defines
+    _In_ UINT32 defineCount,                      // Number of defines
+    _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional)
+    _COM_Outptr_ IDxcOperationResult **ppResult   // Preprocessor output status, buffer, and errors
+  ) = 0;
+
+  // Disassemble a program.
+  virtual HRESULT STDMETHODCALLTYPE Disassemble(
+    _In_ IDxcBlob *pSource,                         // Program to disassemble.
+    _COM_Outptr_ IDxcBlobEncoding **ppDisassembly   // Disassembly text.
+    ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompiler)
+};
+
+// NOTE: IDxcCompiler3 replaces IDxcCompiler and IDxcCompiler2
+struct __declspec(uuid("A005A9D9-B8BB-4594-B5C9-0E633BEC4D37"))
+IDxcCompiler2 : public IDxcCompiler {
+  // Compile a single entry point to the target shader model with debug information.
+  virtual HRESULT STDMETHODCALLTYPE CompileWithDebug(
+    _In_ IDxcBlob *pSource,                       // Source text to compile
+    _In_opt_z_ LPCWSTR pSourceName,               // Optional file name for pSource. Used in errors and include handlers.
+    _In_opt_z_ LPCWSTR pEntryPoint,               // Entry point name
+    _In_z_ LPCWSTR pTargetProfile,                // Shader profile to compile
+    _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments
+    _In_ UINT32 argCount,                         // Number of arguments
+    _In_count_(defineCount)
+      const DxcDefine *pDefines,                  // Array of defines
+    _In_ UINT32 defineCount,                      // Number of defines
+    _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional)
+    _COM_Outptr_ IDxcOperationResult **ppResult,  // Compiler output status, buffer, and errors
+    _Outptr_opt_result_z_ LPWSTR *ppDebugBlobName,// Suggested file name for debug blob. (Must be HeapFree()'d!)
+    _COM_Outptr_opt_ IDxcBlob **ppDebugBlob       // Debug blob
+  ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompiler2)
+};
+
+struct __declspec(uuid("F1B5BE2A-62DD-4327-A1C2-42AC1E1E78E6"))
+IDxcLinker : public IUnknown {
+public:
+  // Register a library with name to ref it later.
+  virtual HRESULT RegisterLibrary(
+    _In_opt_ LPCWSTR pLibName,          // Name of the library.
+    _In_ IDxcBlob *pLib                 // Library blob.
+  ) = 0;
+
+  // Links the shader and produces a shader blob that the Direct3D runtime can
+  // use.
+  virtual HRESULT STDMETHODCALLTYPE Link(
+    _In_opt_ LPCWSTR pEntryName,        // Entry point name
+    _In_ LPCWSTR pTargetProfile,        // shader profile to link
+    _In_count_(libCount)
+        const LPCWSTR *pLibNames,       // Array of library names to link
+    _In_ UINT32 libCount,               // Number of libraries to link
+    _In_opt_count_(argCount) const LPCWSTR *pArguments, // Array of pointers to arguments
+    _In_ UINT32 argCount,               // Number of arguments
+    _COM_Outptr_
+        IDxcOperationResult **ppResult  // Linker output status, buffer, and errors
+  ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcLinker)
+};
+
+/////////////////////////
+// Latest interfaces. Please use these
+////////////////////////
+
+// NOTE: IDxcUtils replaces IDxcLibrary
+struct __declspec(uuid("4605C4CB-2019-492A-ADA4-65F20BB7D67F"))
+IDxcUtils : public IUnknown {
+  // Create a sub-blob that holds a reference to the outer blob and points to its memory.
+  virtual HRESULT STDMETHODCALLTYPE CreateBlobFromBlob(
+    _In_ IDxcBlob *pBlob, UINT32 offset, UINT32 length, _COM_Outptr_ IDxcBlob **ppResult) = 0;
+
+  // For codePage, use 0 (or DXC_CP_ACP) for raw binary or ANSI code page
+
+  // Creates a blob referencing existing memory, with no copy.
+  // User must manage the memory lifetime separately.
+  // (was: CreateBlobWithEncodingFromPinned)
+  virtual HRESULT STDMETHODCALLTYPE CreateBlobFromPinned(
+    _In_bytecount_(size) LPCVOID pData, UINT32 size, UINT32 codePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+
+  // Create blob, taking ownership of memory allocated with supplied allocator.
+  // (was: CreateBlobWithEncodingOnMalloc)
+  virtual HRESULT STDMETHODCALLTYPE MoveToBlob(
+    _In_bytecount_(size) LPCVOID pData, IMalloc *pIMalloc, UINT32 size, UINT32 codePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+
+  ////
+  // New blobs and copied contents are allocated with the current allocator
+
+  // Copy blob contents to memory owned by the new blob.
+  // (was: CreateBlobWithEncodingOnHeapCopy)
+  virtual HRESULT STDMETHODCALLTYPE CreateBlob(
+    _In_bytecount_(size) LPCVOID pData, UINT32 size, UINT32 codePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+
+  // (was: CreateBlobFromFile)
+  virtual HRESULT STDMETHODCALLTYPE LoadFile(
+    _In_z_ LPCWSTR pFileName, _In_opt_ UINT32* pCodePage,
+    _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) = 0;
+
+  virtual HRESULT STDMETHODCALLTYPE CreateReadOnlyStreamFromBlob(
+    _In_ IDxcBlob *pBlob, _COM_Outptr_ IStream **ppStream) = 0;
+
+  // Create default file-based include handler
+  virtual HRESULT STDMETHODCALLTYPE CreateDefaultIncludeHandler(
+    _COM_Outptr_ IDxcIncludeHandler **ppResult) = 0;
+
+  // Convert or return matching encoded text blobs
+  virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf8(
+    _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobUtf8 **pBlobEncoding) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetBlobAsUtf16(
+    _In_ IDxcBlob *pBlob, _COM_Outptr_ IDxcBlobUtf16 **pBlobEncoding) = 0;
+
+  virtual HRESULT STDMETHODCALLTYPE GetDxilContainerPart(
+    _In_ const DxcBuffer *pShader,
+    _In_ UINT32 DxcPart,
+    _Outptr_result_nullonfailure_ void **ppPartData,
+    _Out_ UINT32 *pPartSizeInBytes) = 0;
+
+  // Create reflection interface from serialized Dxil container, or DXC_PART_REFLECTION_DATA.
+  // TBD: Require part header for RDAT?  (leaning towards yes)
+  virtual HRESULT STDMETHODCALLTYPE CreateReflection(
+    _In_ const DxcBuffer *pData, REFIID iid, void **ppvReflection) = 0;
+
+  virtual HRESULT STDMETHODCALLTYPE BuildArguments(
+    _In_opt_z_ LPCWSTR pSourceName,               // Optional file name for pSource. Used in errors and include handlers.
+    _In_opt_z_ LPCWSTR pEntryPoint,               // Entry point name. (-E)
+    _In_z_ LPCWSTR pTargetProfile,                // Shader profile to compile. (-T)
+    _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments
+    _In_ UINT32 argCount,                         // Number of arguments
+    _In_count_(defineCount)
+      const DxcDefine *pDefines,                  // Array of defines
+    _In_ UINT32 defineCount,                      // Number of defines
+    _COM_Outptr_ IDxcCompilerArgs **ppArgs        // Arguments you can use with Compile() method
+  ) = 0;
+
+  // Takes the shader PDB and returns the hash and the container inside it
+  virtual HRESULT STDMETHODCALLTYPE GetPDBContents(
+    _In_ IDxcBlob *pPDBBlob, _COM_Outptr_ IDxcBlob **ppHash, _COM_Outptr_ IDxcBlob **ppContainer) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcUtils)
+};
+
+// For use with IDxcResult::[Has|Get]Output dxcOutKind argument
+// Note: text outputs returned from version 2 APIs are UTF-8 or UTF-16 based on -encoding option
+typedef enum DXC_OUT_KIND {
+  DXC_OUT_NONE = 0,
+  DXC_OUT_OBJECT = 1,         // IDxcBlob - Shader or library object
+  DXC_OUT_ERRORS = 2,         // IDxcBlobUtf8 or IDxcBlobUtf16
+  DXC_OUT_PDB = 3,            // IDxcBlob
+  DXC_OUT_SHADER_HASH = 4,    // IDxcBlob - DxcShaderHash of shader or shader with source info (-Zsb/-Zss)
+  DXC_OUT_DISASSEMBLY = 5,    // IDxcBlobUtf8 or IDxcBlobUtf16 - from Disassemble
+  DXC_OUT_HLSL = 6,           // IDxcBlobUtf8 or IDxcBlobUtf16 - from Preprocessor or Rewriter
+  DXC_OUT_TEXT = 7,           // IDxcBlobUtf8 or IDxcBlobUtf16 - other text, such as -ast-dump or -Odump
+  DXC_OUT_REFLECTION = 8,     // IDxcBlob - RDAT part with reflection data
+  DXC_OUT_ROOT_SIGNATURE = 9, // IDxcBlob - Serialized root signature output
+  DXC_OUT_EXTRA_OUTPUTS  = 10,// IDxcExtraResults - Extra outputs
+
+  DXC_OUT_FORCE_DWORD = 0xFFFFFFFF
+} DXC_OUT_KIND;
+
+struct __declspec(uuid("58346CDA-DDE7-4497-9461-6F87AF5E0659"))
+IDxcResult : public IDxcOperationResult {
+  virtual BOOL STDMETHODCALLTYPE HasOutput(_In_ DXC_OUT_KIND dxcOutKind) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetOutput(_In_ DXC_OUT_KIND dxcOutKind,
+    _In_ REFIID iid, _COM_Outptr_opt_result_maybenull_ void **ppvObject,
+    _COM_Outptr_ IDxcBlobUtf16 **ppOutputName) = 0;
+
+  virtual UINT32 GetNumOutputs() = 0;
+  virtual DXC_OUT_KIND GetOutputByIndex(UINT32 Index) = 0;
+  virtual DXC_OUT_KIND PrimaryOutput() = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcResult)
+};
+
+// Special names for extra output that should get written to specific streams
+#define DXC_EXTRA_OUTPUT_NAME_STDOUT L"*stdout*"
+#define DXC_EXTRA_OUTPUT_NAME_STDERR L"*stderr*"
+
+struct __declspec(uuid("319b37a2-a5c2-494a-a5de-4801b2faf989"))
+IDxcExtraOutputs : public IUnknown {
+
+  virtual UINT32 STDMETHODCALLTYPE GetOutputCount() = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetOutput(_In_ UINT32 uIndex,
+    _In_ REFIID iid, _COM_Outptr_opt_result_maybenull_ void **ppvObject,
+    _COM_Outptr_opt_result_maybenull_ IDxcBlobUtf16 **ppOutputType,
+    _COM_Outptr_opt_result_maybenull_ IDxcBlobUtf16 **ppOutputName) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcExtraOutputs)
+};
+
+struct __declspec(uuid("228B4687-5A6A-4730-900C-9702B2203F54"))
+IDxcCompiler3 : public IUnknown {
+  // Compile a single entry point to the target shader model,
+  // Compile a library to a library target (-T lib_*),
+  // Compile a root signature (-T rootsig_*), or
+  // Preprocess HLSL source (-P)
+  virtual HRESULT STDMETHODCALLTYPE Compile(
+    _In_ const DxcBuffer *pSource,                // Source text to compile
+    _In_opt_count_(argCount) LPCWSTR *pArguments, // Array of pointers to arguments
+    _In_ UINT32 argCount,                         // Number of arguments
+    _In_opt_ IDxcIncludeHandler *pIncludeHandler, // user-provided interface to handle #include directives (optional)
+    _In_ REFIID riid, _Out_ LPVOID *ppResult      // IDxcResult: status, buffer, and errors
+  ) = 0;
+
+  // Disassemble a program.
+  virtual HRESULT STDMETHODCALLTYPE Disassemble(
+    _In_ const DxcBuffer *pObject,                // Program to disassemble: dxil container or bitcode.
+    _In_ REFIID riid, _Out_ LPVOID *ppResult      // IDxcResult: status, disassembly text, and errors
+    ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcCompiler3)
+};
+
+static const UINT32 DxcValidatorFlags_Default = 0;
+static const UINT32 DxcValidatorFlags_InPlaceEdit = 1;  // Validator is allowed to update shader blob in-place.
+static const UINT32 DxcValidatorFlags_RootSignatureOnly = 2;
+static const UINT32 DxcValidatorFlags_ModuleOnly = 4;
+static const UINT32 DxcValidatorFlags_ValidMask = 0x7;
+
+struct __declspec(uuid("A6E82BD2-1FD7-4826-9811-2857E797F49A"))
+IDxcValidator : public IUnknown {
+  // Validate a shader.
+  virtual HRESULT STDMETHODCALLTYPE Validate(
+    _In_ IDxcBlob *pShader,                       // Shader to validate.
+    _In_ UINT32 Flags,                            // Validation flags.
+    _COM_Outptr_ IDxcOperationResult **ppResult   // Validation output status, buffer, and errors
+    ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcValidator)
+};
+
+struct __declspec(uuid("334b1f50-2292-4b35-99a1-25588d8c17fe"))
+IDxcContainerBuilder : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pDxilContainerHeader) = 0;                // Loads DxilContainer to the builder
+  virtual HRESULT STDMETHODCALLTYPE AddPart(_In_ UINT32 fourCC, _In_ IDxcBlob *pSource) = 0;      // Part to add to the container
+  virtual HRESULT STDMETHODCALLTYPE RemovePart(_In_ UINT32 fourCC) = 0;                           // Remove the part with fourCC
+  virtual HRESULT STDMETHODCALLTYPE SerializeContainer(_Out_ IDxcOperationResult **ppResult) = 0; // Builds a container of the given container builder state
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcContainerBuilder)
+};
+
+struct __declspec(uuid("091f7a26-1c1f-4948-904b-e6e3a8a771d5"))
+IDxcAssembler : public IUnknown {
+  // Assemble dxil in ll or llvm bitcode to DXIL container.
+  virtual HRESULT STDMETHODCALLTYPE AssembleToContainer(
+    _In_ IDxcBlob *pShader,                       // Shader to assemble.
+    _COM_Outptr_ IDxcOperationResult **ppResult   // Assembly output status, buffer, and errors
+    ) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcAssembler)
+};
+
+struct __declspec(uuid("d2c21b26-8350-4bdc-976a-331ce6f4c54c"))
+IDxcContainerReflection : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pContainer) = 0; // Container to load.
+  virtual HRESULT STDMETHODCALLTYPE GetPartCount(_Out_ UINT32 *pResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetPartKind(UINT32 idx, _Out_ UINT32 *pResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetPartContent(UINT32 idx, _COM_Outptr_ IDxcBlob **ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE FindFirstPartKind(UINT32 kind, _Out_ UINT32 *pResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetPartReflection(UINT32 idx, REFIID iid, void **ppvObject) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcContainerReflection)
+};
+
+struct __declspec(uuid("AE2CD79F-CC22-453F-9B6B-B124E7A5204C"))
+IDxcOptimizerPass : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE GetOptionName(_COM_Outptr_ LPWSTR *ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetDescription(_COM_Outptr_ LPWSTR *ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetOptionArgCount(_Out_ UINT32 *pCount) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetOptionArgName(UINT32 argIndex, _COM_Outptr_ LPWSTR *ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetOptionArgDescription(UINT32 argIndex, _COM_Outptr_ LPWSTR *ppResult) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcOptimizerPass)
+};
+
+struct __declspec(uuid("25740E2E-9CBA-401B-9119-4FB42F39F270"))
+IDxcOptimizer : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE GetAvailablePassCount(_Out_ UINT32 *pCount) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetAvailablePass(UINT32 index, _COM_Outptr_ IDxcOptimizerPass** ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE RunOptimizer(IDxcBlob *pBlob,
+    _In_count_(optionCount) LPCWSTR *ppOptions, UINT32 optionCount,
+    _COM_Outptr_ IDxcBlob **pOutputModule,
+    _COM_Outptr_opt_ IDxcBlobEncoding **ppOutputText) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcOptimizer)
+};
+
+static const UINT32 DxcVersionInfoFlags_None = 0;
+static const UINT32 DxcVersionInfoFlags_Debug = 1; // Matches VS_FF_DEBUG
+static const UINT32 DxcVersionInfoFlags_Internal = 2; // Internal Validator (non-signing)
+
+struct __declspec(uuid("b04f5b50-2059-4f12-a8ff-a1e0cde1cc7e"))
+IDxcVersionInfo : public IUnknown {
+  virtual HRESULT STDMETHODCALLTYPE GetVersion(_Out_ UINT32 *pMajor, _Out_ UINT32 *pMinor) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetFlags(_Out_ UINT32 *pFlags) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcVersionInfo)
+};
+
+struct __declspec(uuid("fb6904c4-42f0-4b62-9c46-983af7da7c83"))
+IDxcVersionInfo2 : public IDxcVersionInfo {
+  virtual HRESULT STDMETHODCALLTYPE GetCommitInfo(_Out_ UINT32 *pCommitCount, _Out_ char **pCommitHash) = 0;
+
+  DECLARE_CROSS_PLATFORM_UUIDOF(IDxcVersionInfo2)
+};
+
+// Note: __declspec(selectany) requires 'extern'
+// On Linux __declspec(selectany) is removed and using 'extern' results in link error.
+#ifdef _MSC_VER
+#define CLSID_SCOPE __declspec(selectany) extern
+#else
+#define CLSID_SCOPE
+#endif
+
+CLSID_SCOPE const CLSID CLSID_DxcCompiler = {
+    0x73e22d93,
+    0xe6ce,
+    0x47f3,
+    {0xb5, 0xbf, 0xf0, 0x66, 0x4f, 0x39, 0xc1, 0xb0}};
+
+// {EF6A8087-B0EA-4D56-9E45-D07E1A8B7806}
+CLSID_SCOPE const GUID CLSID_DxcLinker = {
+    0xef6a8087,
+    0xb0ea,
+    0x4d56,
+    {0x9e, 0x45, 0xd0, 0x7e, 0x1a, 0x8b, 0x78, 0x6}};
+
+// {CD1F6B73-2AB0-484D-8EDC-EBE7A43CA09F}
+CLSID_SCOPE const CLSID CLSID_DxcDiaDataSource = {
+    0xcd1f6b73,
+    0x2ab0,
+    0x484d,
+    {0x8e, 0xdc, 0xeb, 0xe7, 0xa4, 0x3c, 0xa0, 0x9f}};
+
+// {3E56AE82-224D-470F-A1A1-FE3016EE9F9D}
+CLSID_SCOPE const CLSID CLSID_DxcCompilerArgs = {
+    0x3e56ae82,
+    0x224d,
+    0x470f,
+    {0xa1, 0xa1, 0xfe, 0x30, 0x16, 0xee, 0x9f, 0x9d}};
+
+// {6245D6AF-66E0-48FD-80B4-4D271796748C}
+CLSID_SCOPE const GUID CLSID_DxcLibrary = {
+    0x6245d6af,
+    0x66e0,
+    0x48fd,
+    {0x80, 0xb4, 0x4d, 0x27, 0x17, 0x96, 0x74, 0x8c}};
+
+CLSID_SCOPE const GUID CLSID_DxcUtils = CLSID_DxcLibrary;
+
+// {8CA3E215-F728-4CF3-8CDD-88AF917587A1}
+CLSID_SCOPE const GUID CLSID_DxcValidator = {
+    0x8ca3e215,
+    0xf728,
+    0x4cf3,
+    {0x8c, 0xdd, 0x88, 0xaf, 0x91, 0x75, 0x87, 0xa1}};
+
+// {D728DB68-F903-4F80-94CD-DCCF76EC7151}
+CLSID_SCOPE const GUID CLSID_DxcAssembler = {
+    0xd728db68,
+    0xf903,
+    0x4f80,
+    {0x94, 0xcd, 0xdc, 0xcf, 0x76, 0xec, 0x71, 0x51}};
+
+// {b9f54489-55b8-400c-ba3a-1675e4728b91}
+CLSID_SCOPE const GUID CLSID_DxcContainerReflection = {
+    0xb9f54489,
+    0x55b8,
+    0x400c,
+    {0xba, 0x3a, 0x16, 0x75, 0xe4, 0x72, 0x8b, 0x91}};
+
+// {AE2CD79F-CC22-453F-9B6B-B124E7A5204C}
+CLSID_SCOPE const GUID CLSID_DxcOptimizer = {
+    0xae2cd79f,
+    0xcc22,
+    0x453f,
+    {0x9b, 0x6b, 0xb1, 0x24, 0xe7, 0xa5, 0x20, 0x4c}};
+
+// {94134294-411f-4574-b4d0-8741e25240d2}
+CLSID_SCOPE const GUID CLSID_DxcContainerBuilder = {
+    0x94134294,
+    0x411f,
+    0x4574,
+    {0xb4, 0xd0, 0x87, 0x41, 0xe2, 0x52, 0x40, 0xd2}};
+#endif

+ 71 - 0
samples/third_party/DXC/license.txt

@@ -0,0 +1,71 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+Autoconf            llvm/autoconf
+                    llvm/projects/ModuleMaker/autoconf
+Google Test         llvm/utils/unittest/googletest
+OpenBSD regex       llvm/lib/Support/{reg*, COPYRIGHT.regex}
+pyyaml tests        llvm/test/YAMLParser/{*.data, LICENSE.TXT}
+ARM contributions   llvm/lib/Target/ARM/LICENSE.TXT
+md5 contributions   llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
+miniz               llvm/lib/Miniz/miniz.c llvm/include/miniz/miniz.h llvm/lib/Miniz/LICENSE.txt

+ 0 - 47
samples/third_party/glfw/.appveyor.yml

@@ -1,47 +0,0 @@
-image:
-    - Visual Studio 2015
-branches:
-    only:
-        - ci
-        - master
-        - latest
-        - 3.3-stable
-skip_tags: true
-environment:
-    matrix:
-        - GENERATOR: MinGW Makefiles
-          BUILD_SHARED_LIBS: ON
-          CFLAGS: -Werror
-        - GENERATOR: MinGW Makefiles
-          BUILD_SHARED_LIBS: OFF
-          CFLAGS: -Werror
-        - GENERATOR: Visual Studio 10 2010
-          BUILD_SHARED_LIBS: ON
-          CFLAGS: /WX
-        - GENERATOR: Visual Studio 10 2010
-          BUILD_SHARED_LIBS: OFF
-          CFLAGS: /WX
-matrix:
-    fast_finish: true
-for:
--
-    matrix:
-        only:
-            - GENERATOR: MinGW Makefiles
-    build_script:
-        - set PATH=%PATH:C:\Program Files\Git\usr\bin=C:\MinGW\bin%
-        - cmake -S . -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
-        - cmake --build build
--
-    matrix:
-        only:
-            - GENERATOR: Visual Studio 10 2010
-    build_script:
-        - cmake -S . -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
-        - cmake --build build --target glfw
-notifications:
-    - provider: Email
-      to:
-        - ci@glfw.org
-      on_build_failure: true
-      on_build_success: false

+ 0 - 5
samples/third_party/glfw/.gitattributes

@@ -1,5 +0,0 @@
-*.m linguist-language=Objective-C
-.gitignore export-ignore
-.gitattributes export-ignore
-.travis.yml export-ignore
-.appveyor.yml export-ignore

+ 0 - 104
samples/third_party/glfw/.gitignore

@@ -1,104 +0,0 @@
-# The canonical out-of-tree build subdirectory
-build
-
-# Visual Studio clutter
-_ReSharper*
-*.sdf
-*.suo
-*.dir
-*.vcxproj*
-*.sln
-.vs
-CMakeSettings.json
-Win32
-x64
-Debug
-Release
-MinSizeRel
-RelWithDebInfo
-*.opensdf
-
-# Xcode clutter
-GLFW.build
-GLFW.xcodeproj
-
-# macOS clutter
-.DS_Store
-
-# Makefile generator clutter
-Makefile
-
-# Ninja generator clutter
-build.ninja
-rules.ninja
-.ninja_deps
-.ninja_log
-
-# CMake clutter
-CMakeCache.txt
-CMakeFiles
-CMakeScripts
-CMakeDoxyfile.in
-CMakeDoxygenDefaults.cmake
-cmake_install.cmake
-cmake_uninstall.cmake
-
-# Generated files
-docs/Doxyfile
-docs/html
-docs/warnings.txt
-docs/doxygen_sqlite3.db
-src/glfw_config.h
-src/glfw3.pc
-src/glfw3Config.cmake
-src/glfw3ConfigVersion.cmake
-src/wayland-pointer-constraints-unstable-v1-client-protocol.h
-src/wayland-pointer-constraints-unstable-v1-protocol.c
-src/wayland-relative-pointer-unstable-v1-client-protocol.h
-src/wayland-relative-pointer-unstable-v1-protocol.c
-
-# Compiled binaries
-src/libglfw.so
-src/libglfw.so.3
-src/libglfw.so.3.3
-src/libglfw.dylib
-src/libglfw.dylib
-src/libglfw.3.dylib
-src/libglfw.3.3.dylib
-src/libglfw3.a
-src/glfw3.lib
-src/glfw3.dll
-src/glfw3dll.lib
-src/libglfw3dll.a
-examples/*.app
-examples/*.exe
-examples/boing
-examples/gears
-examples/heightmap
-examples/offscreen
-examples/particles
-examples/splitview
-examples/sharing
-examples/simple
-examples/wave
-tests/*.app
-tests/*.exe
-tests/clipboard
-tests/cursor
-tests/empty
-tests/events
-tests/gamma
-tests/glfwinfo
-tests/icon
-tests/iconify
-tests/joysticks
-tests/monitors
-tests/msaa
-tests/reopen
-tests/tearing
-tests/threads
-tests/timeout
-tests/title
-tests/triangle-vulkan
-tests/windows
-

+ 0 - 10
samples/third_party/glfw/.mailmap

@@ -1,10 +0,0 @@
-Camilla Löwy <elmindreda@glfw.org> <elmindreda@users.sourceforge.net>
-Camilla Löwy <elmindreda@glfw.org> <elmindreda@elmindreda.org>
-Camilla Löwy <elmindreda@glfw.org>
-
-Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
-
-Marcus Geelnard <m@bitsnbites.eu> <marcus256@users.sourceforge.net>
-Marcus Geelnard <m@bitsnbites.eu> <marcus@geelnards-pc.(none)>
-Marcus Geelnard <m@bitsnbites.eu>
-

+ 0 - 34
samples/third_party/glfw/docs/CMakeLists.txt

@@ -1,34 +0,0 @@
-
-# NOTE: The order of this list determines the order of items in the Guides
-#       (i.e. Pages) list in the generated documentation
-set(GLFW_DOXYGEN_SOURCES
-    "include/GLFW/glfw3.h"
-    "include/GLFW/glfw3native.h"
-    "docs/main.dox"
-    "docs/news.dox"
-    "docs/quick.dox"
-    "docs/moving.dox"
-    "docs/compile.dox"
-    "docs/build.dox"
-    "docs/intro.dox"
-    "docs/context.dox"
-    "docs/monitor.dox"
-    "docs/window.dox"
-    "docs/input.dox"
-    "docs/vulkan.dox"
-    "docs/compat.dox"
-    "docs/internal.dox")
-
-# Format the source list into a Doxyfile INPUT value that Doxygen can parse
-foreach(path IN LISTS GLFW_DOXYGEN_SOURCES)
-    set(GLFW_DOXYGEN_INPUT "${GLFW_DOXYGEN_INPUT} \\\n\"${GLFW_SOURCE_DIR}/${path}\"")
-endforeach()
-
-configure_file(Doxyfile.in Doxyfile @ONLY)
-
-add_custom_target(docs ALL "${DOXYGEN_EXECUTABLE}"
-                  WORKING_DIRECTORY "${GLFW_BINARY_DIR}/docs"
-                  COMMENT "Generating HTML documentation" VERBATIM)
-
-set_target_properties(docs PROPERTIES FOLDER "GLFW3")
-

+ 0 - 10
samples/third_party/glfw/docs/CODEOWNERS

@@ -1,10 +0,0 @@
-
-*               @elmindreda
-
-src/wl_*        @linkmauve
-
-docs/*.css      @glfw/webdev
-docs/*.scss     @glfw/webdev
-docs/*.html     @glfw/webdev
-docs/*.xml      @glfw/webdev
-

+ 0 - 391
samples/third_party/glfw/docs/CONTRIBUTING.md

@@ -1,391 +0,0 @@
-# Contribution Guide
-
-## Contents
-
-- [Asking a question](#asking-a-question)
-- [Reporting a bug](#reporting-a-bug)
-    - [Reporting a compile or link bug](#reporting-a-compile-or-link-bug)
-    - [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-bug)
-    - [Reporting a context creation bug](#reporting-a-context-creation-bug)
-    - [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug)
-    - [Reporting a window, input or event bug](#reporting-a-window-input-or-event-bug)
-    - [Reporting some other library bug](#reporting-some-other-library-bug)
-    - [Reporting a documentation bug](#reporting-a-documentation-bug)
-    - [Reporting a website bug](#reporting-a-website-bug)
-- [Requesting a feature](#requesting-a-feature)
-- [Contributing a bug fix](#contributing-a-bug-fix)
-- [Contributing a feature](#contributing-a-feature)
-
-
-## Asking a question
-
-Questions about how to use GLFW should be asked either in the [support
-section](https://discourse.glfw.org/c/support) of the forum, under the [Stack
-Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game
-Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on
-Stack Exchange or in the IRC channel `#glfw` on
-[Libera.Chat](https://libera.chat/).
-
-Questions about the design or implementation of GLFW or about future plans
-should be asked in the [dev section](https://discourse.glfw.org/c/dev) of the
-forum or in the IRC channel.  Please don't open a GitHub issue to discuss design
-questions without first checking with a maintainer.
-
-
-## Reporting a bug
-
-If GLFW is behaving unexpectedly at run-time, start by setting an [error
-callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling).
-GLFW will often tell you the cause of an error via this callback.  If it
-doesn't, that might be a separate bug.
-
-If GLFW is crashing or triggering asserts, make sure that all your object
-handles and other pointers are valid.
-
-For bugs where it makes sense, a short, self contained example is absolutely
-invaluable.  Just put it inline in the body text.  Note that if the bug is
-reproducible with one of the test programs that come with GLFW, just mention
-that instead.
-
-__Don't worry about adding too much information__.  Unimportant information can
-be abbreviated or removed later, but missing information can stall bug fixing,
-especially when your schedule doesn't align with that of the maintainer.
-
-__Please provide text as text, not as images__.  This includes code, error
-messages and any other text.  Text in images cannot be found by other users
-searching for the same problem and may have to be re-typed by maintainers when
-debugging.
-
-You don't need to manually indent your code or other text to quote it with
-GitHub Markdown; just surround it with triple backticks:
-
-    ```
-    Some quoted text.
-    ```
-
-You can also add syntax highlighting by appending the common file extension:
-
-    ```c
-    int five(void)
-    {
-        return 5;
-    }
-    ```
-
-There are issue labels for both platforms and GPU manufacturers, so there is no
-need to mention these in the subject line.  If you do, it will be removed when
-the issue is labeled.
-
-If your bug is already reported, please add any new information you have, or if
-it already has everything, give it a :+1:.
-
-
-### Reporting a compile or link bug
-
-__Note:__ GLFW needs many system APIs to do its job, which on some platforms
-means linking to many system libraries.  If you are using GLFW as a static
-library, that means your application needs to link to these in addition to GLFW.
-
-__Note:__ Check the [Compiling
-GLFW](https://www.glfw.org/docs/latest/compile.html) guide and or [Building
-applications](https://www.glfw.org/docs/latest/build.html) guide for before
-opening an issue of this kind.  Most issues are caused by a missing package or
-linker flag.
-
-Always include the __operating system name and version__ (e.g. `Windows
-7 64-bit` or `Ubuntu 15.10`) and the __compiler name and version__ (e.g. `Visual
-C++ 2015 Update 2`).  If you are using an official release of GLFW,
-include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
-__GLFW commit ID__ (e.g.  `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
-
-Please also include the __complete build log__ from your compiler and linker,
-even if it's long.  It can always be shortened later, if necessary.
-
-
-#### Quick template
-
-```
-OS and version:
-Compiler version:
-Release or commit:
-Build log:
-```
-
-
-### Reporting a segfault or other crash bug
-
-Always include the __operating system name and version__ (e.g. `Windows
-7 64-bit` or `Ubuntu 15.10`).  If you are using an official release of GLFW,
-include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
-__GLFW commit ID__ (e.g.  `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
-
-Please also include any __error messages__ provided to your application via the
-[error
-callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
-the __full call stack__ of the crash, or if the crash does not occur in debug
-mode, mention that instead.
-
-
-#### Quick template
-
-```
-OS and version:
-Release or commit:
-Error messages:
-Call stack:
-```
-
-
-### Reporting a context creation bug
-
-__Note:__ Windows ships with graphics drivers that do not support OpenGL.  If
-GLFW says that your machine lacks support for OpenGL, it very likely does.
-Install drivers from the computer manufacturer or graphics card manufacturer
-([Nvidia](https://www.geforce.com/drivers),
-[AMD](https://www.amd.com/en/support),
-[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to
-fix this.
-
-__Note:__ AMD only supports OpenGL ES on Windows via EGL.  See the
-[GLFW\_CONTEXT\_CREATION\_API](https://www.glfw.org/docs/latest/window_guide.html#window_hints_ctx)
-hint for how to select EGL.
-
-Please verify that context creation also fails with the `glfwinfo` tool before
-reporting it as a bug.  This tool is included in the GLFW source tree as
-`tests/glfwinfo.c` and is built along with the library.  It has switches for all
-GLFW context and framebuffer hints.  Run `glfwinfo -h` for a complete list.
-
-Always include the __operating system name and version__ (e.g. `Windows
-7 64-bit` or `Ubuntu 15.10`).  If you are using an official release of GLFW,
-include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
-__GLFW commit ID__ (e.g.  `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
-
-If you are running your program in a virtual machine, please mention this and
-include the __VM name and version__ (e.g. `VirtualBox 5.1`).
-
-Please also include the __GLFW version string__ (`3.2.0 X11 EGL clock_gettime
-/dev/js`), as described
-[here](https://www.glfw.org/docs/latest/intro.html#intro_version_string), the
-__GPU model and driver version__ (e.g. `GeForce GTX660 with 352.79`), and the
-__output of `glfwinfo`__ (with switches matching any hints you set in your
-code) when reporting this kind of bug.  If this tool doesn't run on the machine,
-mention that instead.
-
-
-#### Quick template
-
-```
-OS and version:
-GPU and driver:
-Release or commit:
-Version string:
-glfwinfo output:
-```
-
-
-### Reporting a monitor or video mode bug
-
-__Note:__ On headless systems on some platforms, no monitors are reported.  This
-causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are
-prepared for.
-
-__Note:__ Some third-party tools report more video modes than are approved of
-by the OS.  For safety and compatibility, GLFW only reports video modes the OS
-wants programs to use.  This is not a bug.
-
-The `monitors` tool is included in the GLFW source tree as `tests/monitors.c`
-and is built along with the library.  It lists all information GLFW provides
-about monitors it detects.
-
-Always include the __operating system name and version__ (e.g. `Windows
-7 64-bit` or `Ubuntu 15.10`).  If you are using an official release of GLFW,
-include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
-__GLFW commit ID__ (e.g.  `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
-
-If you are running your program in a virtual machine, please mention this and
-include the __VM name and version__ (e.g. `VirtualBox 5.1`).
-
-Please also include any __error messages__ provided to your application via the
-[error
-callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
-the __output of `monitors`__ when reporting this kind of bug.  If this tool
-doesn't run on the machine, mention this instead.
-
-
-#### Quick template
-
-```
-OS and version:
-Release or commit:
-Error messages:
-monitors output:
-```
-
-
-### Reporting a window, input or event bug
-
-__Note:__ The exact ordering of related window events will sometimes differ.
-
-__Note:__ Window moving and resizing (by the user) will block the main thread on
-some platforms.  This is not a bug.  Set a [refresh
-callback](https://www.glfw.org/docs/latest/window.html#window_refresh) if you
-want to keep the window contents updated during a move or size operation.
-
-The `events` tool is included in the GLFW source tree as `tests/events.c` and is
-built along with the library.  It prints all information provided to every
-callback supported by GLFW as events occur.  Each event is listed with the time
-and a unique number to make discussions about event logs easier.  The tool has
-command-line options for creating multiple windows and full screen windows.
-
-Always include the __operating system name and version__ (e.g. `Windows
-7 64-bit` or `Ubuntu 15.10`).  If you are using an official release of GLFW,
-include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
-__GLFW commit ID__ (e.g.  `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
-
-If you are running your program in a virtual machine, please mention this and
-include the __VM name and version__ (e.g. `VirtualBox 5.1`).
-
-Please also include any __error messages__ provided to your application via the
-[error
-callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
-if relevant, the __output of `events`__ when reporting this kind of bug.  If
-this tool doesn't run on the machine, mention this instead.
-
-__X11:__ If possible, please include what desktop environment (e.g. GNOME,
-Unity, KDE) and/or window manager (e.g. Openbox, dwm, Window Maker) you are
-running.  If the bug is related to keyboard input, please include any input
-method (e.g. ibus, SCIM) you are using.
-
-
-#### Quick template
-
-```
-OS and version:
-Release or commit:
-Error messages:
-events output:
-```
-
-
-### Reporting some other library bug
-
-Always include the __operating system name and version__ (e.g. `Windows
-7 64-bit` or `Ubuntu 15.10`).  If you are using an official release of GLFW,
-include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
-__GLFW commit ID__ (e.g.  `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
-
-Please also include any __error messages__ provided to your application via the
-[error
-callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling), if
-relevant.
-
-
-#### Quick template
-
-```
-OS and version:
-Release or commit:
-Error messages:
-```
-
-
-### Reporting a documentation bug
-
-If you found a bug in the documentation, including this file, then it's fine to
-just link to that web page or mention that source file.  You don't need to match
-the source to the output or vice versa.
-
-
-### Reporting a website bug
-
-If the bug is in the documentation (anything under `/docs/`) then please see the
-section above.  Bugs in the rest of the site are reported to the [website
-source repository](https://github.com/glfw/website/issues).
-
-
-## Requesting a feature
-
-Please explain why you need the feature and how you intend to use it.  If you
-have a specific API design in mind, please add that as well.  If you have or are
-planning to write code for the feature, see the section below.
-
-If there already is a request for the feature you need, add your specific use
-case unless it is already mentioned.  If it is, give it a :+1:.
-
-
-## Contributing a bug fix
-
-__Note:__ You must have all necessary [intellectual
-property rights](https://en.wikipedia.org/wiki/Intellectual_property) to any
-code you contribute.  If you did not write the code yourself, you must explain
-where it came from and under what license you received it.  Even code using the
-same license as GLFW may not be copied without attribution.
-
-__There is no preferred patch size__.  A one character fix is just as welcome as
-a thousand line one, if that is the appropriate size for the fix.
-
-In addition to the code, a complete bug fix includes:
-
-- Change log entry in `README.md`, describing the incorrect behavior
-- Credits entries for all authors of the bug fix
-
-Bug fixes will not be rejected because they don't include all the above parts,
-but please keep in mind that maintainer time is finite and that there are many
-other bugs and features to work on.
-
-If the patch fixes a bug introduced after the last release, it should not get
-a change log entry.
-
-If you haven't already, read the excellent article [How to Write a Git Commit
-Message](https://chris.beams.io/posts/git-commit/).
-
-
-## Contributing a feature
-
-__Note:__ You must have all necessary rights to any code you contribute.  If you
-did not write the code yourself, you must explain where it came from and under
-what license.  Even code using the same license as GLFW may not be copied
-without attribution.
-
-__Note:__ If you haven't already implemented the feature, check first if there
-already is an open issue for it and if it's already being developed in an
-[experimental branch](https://github.com/glfw/glfw/branches/all).
-
-__There is no preferred patch size__.  A one character change is just as welcome
-as one adding a thousand line one, if that is the appropriate size for the
-feature.
-
-In addition to the code, a complete feature includes:
-
-- Change log entry in `README.md`, listing all new symbols
-- News page entry, briefly describing the feature
-- Guide documentation, with minimal examples, in the relevant guide
-- Reference documentation, with all applicable tags
-- Cross-references and mentions in appropriate places
-- Credits entries for all authors of the feature
-
-If the feature requires platform-specific code, at minimum stubs must be added
-for the new platform function to all supported and experimental platforms.
-
-If it adds a new callback, support for it must be added to `tests/event.c`.
-
-If it adds a new monitor property, support for it must be added to
-`tests/monitor.c`.
-
-If it adds a new OpenGL, OpenGL ES or Vulkan option or extension, support
-for it must be added to `tests/glfwinfo.c` and the behavior of the library when
-the extension is missing documented in `docs/compat.dox`.
-
-If you haven't already, read the excellent article [How to Write a Git Commit
-Message](https://chris.beams.io/posts/git-commit/).
-
-Features will not be rejected because they don't include all the above parts,
-but please keep in mind that maintainer time is finite and that there are many
-other features and bugs to work on.
-
-Please also keep in mind that any part of the public API that has been included
-in a release cannot be changed until the next _major_ version.  Features can be
-added and existing parts can sometimes be overloaded (in the general sense of
-doing more things, not in the C++ sense), but code written to the API of one
-minor release should both compile and run on subsequent minor releases.
-

ファイルの差分が大きいため隠しています
+ 0 - 1828
samples/third_party/glfw/docs/Doxyfile.in


+ 0 - 71
samples/third_party/glfw/docs/DoxygenLayout.xml

@@ -1,71 +0,0 @@
-<doxygenlayout version="1.0">
-  <!-- Generated by doxygen 1.8.14 -->
-  <!-- Navigation index tabs for HTML output -->
-  <navindex>
-    <tab type="mainpage" visible="yes" title="Introduction"/>
-    <tab type="user" url="quick_guide.html" title="Tutorial"/>
-    <tab type="pages" visible="yes" title="Guides" intro=""/>
-    <tab type="modules" visible="yes" title="Reference" intro=""/>
-    <tab type="filelist" visible="yes" title="Files"/>
-  </navindex>
-
-  <!-- Layout definition for a file page -->
-  <file>
-    <detaileddescription title="Description"/>
-    <includes visible="$SHOW_INCLUDE_FILES"/>
-    <sourcelink visible="yes"/>
-    <memberdecl>
-      <constantgroups visible="yes" title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <memberdef>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdef>
-    <authorsection/>
-  </file>
-
-  <!-- Layout definition for a group page -->
-  <group>
-    <detaileddescription title="Description"/>
-    <memberdecl>
-      <nestedgroups visible="yes" title=""/>
-      <dirs visible="yes" title=""/>
-      <files visible="yes" title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <enumvalues title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdecl>
-    <memberdef>
-      <pagedocs/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <enumvalues title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdef>
-    <authorsection visible="yes"/>
-  </group>
-
-  <!-- Layout definition for a directory page -->
-  <directory>
-    <briefdescription visible="yes"/>
-    <memberdecl>
-      <dirs visible="yes"/>
-      <files visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-  </directory>
-</doxygenlayout>

+ 0 - 14
samples/third_party/glfw/docs/SUPPORT.md

@@ -1,14 +0,0 @@
-# Support resources
-
-See the [latest documentation](https://www.glfw.org/docs/latest/) for tutorials,
-guides and the API reference.
-
-If you have questions about using GLFW, we have a
-[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
-[Libera.Chat](https://libera.chat/).
-
-Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
-Please check the [contribution
-guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
-information on what to include when reporting a bug.
-

+ 0 - 348
samples/third_party/glfw/docs/build.dox

@@ -1,348 +0,0 @@
-/*!
-
-@page build_guide Building applications
-
-@tableofcontents
-
-This is about compiling and linking applications that use GLFW.  For information on
-how to write such applications, start with the
-[introductory tutorial](@ref quick_guide).  For information on how to compile
-the GLFW library itself, see @ref compile_guide.
-
-This is not a tutorial on compilation or linking.  It assumes basic
-understanding of how to compile and link a C program as well as how to use the
-specific compiler of your chosen development environment.  The compilation
-and linking process should be explained in your C programming material and in
-the documentation for your development environment.
-
-
-@section build_include Including the GLFW header file
-
-You should include the GLFW header in the source files where you use OpenGL or
-GLFW.
-
-@code
-#include <GLFW/glfw3.h>
-@endcode
-
-This header defines all the constants and declares all the types and function
-prototypes of the GLFW API.  By default it also includes the OpenGL header from
-your development environment.  See [option macros](@ref build_macros) below for
-how to select OpenGL ES headers and more.
-
-The GLFW header also defines any platform-specific macros needed by your OpenGL
-header, so that it can be included without needing any window system headers.
-
-It does this only when needed, so if window system headers are included, the
-GLFW header does not try to redefine those symbols.  The reverse is not true,
-i.e. `windows.h` cannot cope if any Win32 symbols have already been defined.
-
-In other words:
-
- - Use the GLFW header to include OpenGL or OpenGL ES headers portably
- - Do not include window system headers unless you will use those APIs directly
- - If you do need such headers, include them before the GLFW header
-
-If you are using an OpenGL extension loading library such as
-[glad](https://github.com/Dav1dde/glad), the extension loader header should
-be included before the GLFW one.  GLFW attempts to detect any OpenGL or OpenGL
-ES header or extension loader header included before it and will then disable
-the inclusion of the default OpenGL header.  Most extension loaders also define
-macros that disable similar headers below it.
-
-@code
-#include <glad/gl.h>
-#include <GLFW/glfw3.h>
-@endcode
-
-Both of these mechanisms depend on the extension loader header defining a known
-macro.  If yours doesn't or you don't know which one your users will pick, the
-@ref GLFW_INCLUDE_NONE macro will explicitly to prevent the GLFW header from
-including the OpenGL header.  This will also allow you to include the two
-headers in any order.
-
-@code
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-#include <glad/gl.h>
-@endcode
-
-
-@subsection build_macros GLFW header option macros
-
-These macros may be defined before the inclusion of the GLFW header and affect
-its behavior.
-
-@anchor GLFW_DLL
-__GLFW_DLL__ is required on Windows when using the GLFW DLL, to tell the
-compiler that the GLFW functions are defined in a DLL.
-
-The following macros control which OpenGL or OpenGL ES API header is included.
-Only one of these may be defined at a time.
-
-@note GLFW does not provide any of the API headers mentioned below.  They are
-provided by your development environment or your OpenGL, OpenGL ES or Vulkan
-SDK, and most of them can be downloaded from the
-[Khronos Registry](https://www.khronos.org/registry/).
-
-@anchor GLFW_INCLUDE_GLCOREARB
-__GLFW_INCLUDE_GLCOREARB__ makes the GLFW header include the modern
-`GL/glcorearb.h` header (`OpenGL/gl3.h` on macOS) instead of the regular OpenGL
-header.
-
-@anchor GLFW_INCLUDE_ES1
-__GLFW_INCLUDE_ES1__ makes the GLFW header include the OpenGL ES 1.x `GLES/gl.h`
-header instead of the regular OpenGL header.
-
-@anchor GLFW_INCLUDE_ES2
-__GLFW_INCLUDE_ES2__ makes the GLFW header include the OpenGL ES 2.0
-`GLES2/gl2.h` header instead of the regular OpenGL header.
-
-@anchor GLFW_INCLUDE_ES3
-__GLFW_INCLUDE_ES3__ makes the GLFW header include the OpenGL ES 3.0
-`GLES3/gl3.h` header instead of the regular OpenGL header.
-
-@anchor GLFW_INCLUDE_ES31
-__GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.1
-`GLES3/gl31.h` header instead of the regular OpenGL header.
-
-@anchor GLFW_INCLUDE_ES32
-__GLFW_INCLUDE_ES32__ makes the GLFW header include the OpenGL ES 3.2
-`GLES3/gl32.h` header instead of the regular OpenGL header.
-
-@anchor GLFW_INCLUDE_NONE
-__GLFW_INCLUDE_NONE__ makes the GLFW header not include any OpenGL or OpenGL ES
-API header.  This is useful in combination with an extension loading library.
-
-If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h`
-header (`OpenGL/gl.h` on macOS) is included, unless GLFW detects the inclusion
-guards of any OpenGL, OpenGL ES or extension loader header it knows about.
-
-The following macros control the inclusion of additional API headers.  Any
-number of these may be defined simultaneously, and/or together with one of the
-above macros.
-
-@anchor GLFW_INCLUDE_VULKAN
-__GLFW_INCLUDE_VULKAN__ makes the GLFW header include the Vulkan
-`vulkan/vulkan.h` header in addition to any selected OpenGL or OpenGL ES header.
-
-@anchor GLFW_INCLUDE_GLEXT
-__GLFW_INCLUDE_GLEXT__ makes the GLFW header include the appropriate extension
-header for the OpenGL or OpenGL ES header selected above after and in addition
-to that header.
-
-@anchor GLFW_INCLUDE_GLU
-__GLFW_INCLUDE_GLU__ makes the header include the GLU header in addition to the
-header selected above.  This should only be used with the standard OpenGL header
-and only for compatibility with legacy code.  GLU has been deprecated and should
-not be used in new code.
-
-@note None of these macros may be defined during the compilation of GLFW itself.
-If your build includes GLFW and you define any these in your build files, make
-sure they are not applied to the GLFW sources.
-
-
-@section build_link Link with the right libraries
-
-GLFW is essentially a wrapper of various platform-specific APIs and therefore
-needs to link against many different system libraries.  If you are using GLFW as
-a shared library / dynamic library / DLL then it takes care of these links.
-However, if you are using GLFW as a static library then your executable will
-need to link against these libraries.
-
-On Windows and macOS, the list of system libraries is static and can be
-hard-coded into your build environment.  See the section for your development
-environment below.  On Linux and other Unix-like operating systems, the list
-varies but can be retrieved in various ways as described below.
-
-A good general introduction to linking is
-[Beginner's Guide to Linkers](https://www.lurklurk.org/linkers/linkers.html) by
-David Drysdale.
-
-
-@subsection build_link_win32 With MinGW or Visual C++ on Windows
-
-The static version of the GLFW library is named `glfw3`.  When using this
-version, it is also necessary to link with some libraries that GLFW uses.
-
-When using MinGW to link an application with the static version of GLFW, you
-must also explicitly link with `gdi32`. Other toolchains including MinGW-w64
-include it in the set of default libraries along with other dependencies like
-`user32` and `kernel32`.
-
-The link library for the GLFW DLL is named `glfw3dll`.  When compiling an
-application that uses the DLL version of GLFW, you need to define the @ref
-GLFW_DLL macro _before_ any inclusion of the GLFW header.  This can be done
-either with a compiler switch or by defining it in your source code.
-
-
-@subsection build_link_cmake_source With CMake and GLFW source
-
-This section is about using CMake to compile and link GLFW along with your
-application.  If you want to use an installed binary instead, see @ref
-build_link_cmake_package.
-
-With a few changes to your `CMakeLists.txt` you can have the GLFW source tree
-built along with your application.
-
-When including GLFW as part of your build, you probably don't want to build the
-GLFW tests, examples and documentation.  To disable these, set the corresponding
-cache variables before adding the GLFW source tree.
-
-@code
-set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
-set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
-set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
-@endcode
-
-Add the root directory of the GLFW source tree to your project.  This will add
-the `glfw` target to your project.
-
-@code{.cmake}
-add_subdirectory(path/to/glfw)
-@endcode
-
-Once GLFW has been added, link your application against the `glfw` target.
-This adds the GLFW library and its link-time dependencies as it is currently
-configured, the include directory for the GLFW header and, when applicable, the
-@ref GLFW_DLL macro.
-
-@code{.cmake}
-target_link_libraries(myapp glfw)
-@endcode
-
-Note that the `glfw` target does not depend on OpenGL, as GLFW loads any OpenGL,
-OpenGL ES or Vulkan libraries it needs at runtime.  If your application calls
-OpenGL directly, instead of using a modern
-[extension loader library](@ref context_glext_auto), use the OpenGL CMake
-package.
-
-@code{.cmake}
-find_package(OpenGL REQUIRED)
-@endcode
-
-If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
-library and include directory paths.  Link against this like any other library.
-
-@code{.cmake}
-target_link_libraries(myapp OpenGL::GL)
-@endcode
-
-For a minimal example of a program and GLFW sources built with CMake, see the
-[GLFW CMake Starter](https://github.com/juliettef/GLFW-CMake-starter) on GitHub.
-
-
-@subsection build_link_cmake_package With CMake and installed GLFW binaries
-
-This section is about using CMake to link GLFW after it has been built and
-installed.  If you want to build it along with your application instead, see
-@ref build_link_cmake_source.
-
-With a few changes to your `CMakeLists.txt` you can locate the package and
-target files generated when GLFW is installed.
-
-@code{.cmake}
-find_package(glfw3 3.3 REQUIRED)
-@endcode
-
-Once GLFW has been added to the project, link against it with the `glfw` target.
-This adds the GLFW library and its link-time dependencies, the include directory
-for the GLFW header and, when applicable, the @ref GLFW_DLL macro.
-
-@code{.cmake}
-target_link_libraries(myapp glfw)
-@endcode
-
-Note that the `glfw` target does not depend on OpenGL, as GLFW loads any OpenGL,
-OpenGL ES or Vulkan libraries it needs at runtime.  If your application calls
-OpenGL directly, instead of using a modern
-[extension loader library](@ref context_glext_auto), use the OpenGL CMake
-package.
-
-@code{.cmake}
-find_package(OpenGL REQUIRED)
-@endcode
-
-If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
-library and include directory paths.  Link against this like any other library.
-
-@code{.cmake}
-target_link_libraries(myapp OpenGL::GL)
-@endcode
-
-
-@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
-
-GLFW supports [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/),
-and the `glfw3.pc` pkg-config file is generated when the GLFW library is built
-and is installed along with it.  A pkg-config file describes all necessary
-compile-time and link-time flags and dependencies needed to use a library.  When
-they are updated or if they differ between systems, you will get the correct
-ones automatically.
-
-A typical compile and link command-line when using the static version of the
-GLFW library may look like this:
-
-@code{.sh}
-cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --static --libs glfw3)
-@endcode
-
-If you are using the shared version of the GLFW library, omit the `--static`
-flag.
-
-@code{.sh}
-cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --libs glfw3)
-@endcode
-
-You can also use the `glfw3.pc` file without installing it first, by using the
-`PKG_CONFIG_PATH` environment variable.
-
-@code{.sh}
-env PKG_CONFIG_PATH=path/to/glfw/src cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --libs glfw3)
-@endcode
-
-The dependencies do not include OpenGL, as GLFW loads any OpenGL, OpenGL ES or
-Vulkan libraries it needs at runtime.  If your application calls OpenGL
-directly, instead of using a modern
-[extension loader library](@ref context_glext_auto), you should add the `gl`
-pkg-config package.
-
-@code{.sh}
-cc $(pkg-config --cflags glfw3 gl) -o myprog myprog.c $(pkg-config --libs glfw3 gl)
-@endcode
-
-
-@subsection build_link_xcode With Xcode on macOS
-
-If you are using the dynamic library version of GLFW, add it to the project
-dependencies.
-
-If you are using the static library version of GLFW, add it and the Cocoa,
-OpenGL and IOKit frameworks to the project as dependencies.  They can all be
-found in `/System/Library/Frameworks`.
-
-
-@subsection build_link_osx With command-line on macOS
-
-It is recommended that you use [pkg-config](@ref build_link_pkgconfig) when
-building from the command line on macOS.  That way you will get any new
-dependencies added automatically.  If you still wish to build manually, you need
-to add the required frameworks and libraries to your command-line yourself using
-the `-l` and `-framework` switches.
-
-If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
-
-@code{.sh}
-cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit
-@endcode
-
-If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`
-for `-lglfw`.
-
-Note that you do not add the `.framework` extension to a framework when linking
-against it from the command-line.
-
-@note Your machine may have `libGL.*.dylib` style OpenGL library, but that is
-for the X Window System and will not work with the macOS native version of GLFW.
-
-*/

+ 0 - 285
samples/third_party/glfw/docs/compat.dox

@@ -1,285 +0,0 @@
-/*!
-
-@page compat_guide Standards conformance
-
-@tableofcontents
-
-This guide describes the various API extensions used by this version of GLFW.
-It lists what are essentially implementation details, but which are nonetheless
-vital knowledge for developers intending to deploy their applications on a wide
-range of machines.
-
-The information in this guide is not a part of GLFW API, but merely
-preconditions for some parts of the library to function on a given machine.  Any
-part of this information may change in future versions of GLFW and that will not
-be considered a breaking API change.
-
-
-@section compat_x11 X11 extensions, protocols and IPC standards
-
-As GLFW uses Xlib directly, without any intervening toolkit
-library, it has sole responsibility for interacting well with the many and
-varied window managers in use on Unix-like systems.  In order for applications
-and window managers to work well together, a number of standards and
-conventions have been developed that regulate behavior outside the scope of the
-X11 API; most importantly the
-[Inter-Client Communication Conventions Manual](https://www.tronche.com/gui/x/icccm/)
-(ICCCM) and
-[Extended Window Manager Hints](https://standards.freedesktop.org/wm-spec/wm-spec-latest.html)
-(EWMH) standards.
-
-GLFW uses the `_MOTIF_WM_HINTS` window property to support borderless windows.
-If the running window manager does not support this property, the
-`GLFW_DECORATED` hint will have no effect.
-
-GLFW uses the ICCCM `WM_DELETE_WINDOW` protocol to intercept the user
-attempting to close the GLFW window.  If the running window manager does not
-support this protocol, the close callback will never be called.
-
-GLFW uses the EWMH `_NET_WM_PING` protocol, allowing the window manager notify
-the user when the application has stopped responding, i.e. when it has ceased to
-process events.  If the running window manager does not support this protocol,
-the user will not be notified if the application locks up.
-
-GLFW uses the EWMH `_NET_WM_STATE_FULLSCREEN` window state to tell the window
-manager to make the GLFW window full screen.  If the running window manager does
-not support this state, full screen windows may not work properly.  GLFW has
-a fallback code path in case this state is unavailable, but every window manager
-behaves slightly differently in this regard.
-
-GLFW uses the EWMH `_NET_WM_BYPASS_COMPOSITOR` window property to tell a
-compositing window manager to un-redirect full screen GLFW windows.  If the
-running window manager uses compositing but does not support this property then
-additional copying may be performed for each buffer swap of full screen windows.
-
-GLFW uses the
-[clipboard manager protocol](https://www.freedesktop.org/wiki/ClipboardManager/)
-to push a clipboard string (i.e. selection) owned by a GLFW window about to be
-destroyed to the clipboard manager.  If there is no running clipboard manager,
-the clipboard string will be unavailable once the window has been destroyed.
-
-GLFW uses the
-[X drag-and-drop protocol](https://www.freedesktop.org/wiki/Specifications/XDND/)
-to provide file drop events.  If the application originating the drag does not
-support this protocol, drag and drop will not work.
-
-GLFW uses the XRandR 1.3 extension to provide multi-monitor support.  If the
-running X server does not support this version of this extension, multi-monitor
-support will not function and only a single, desktop-spanning monitor will be
-reported.
-
-GLFW uses the XRandR 1.3 and Xf86vidmode extensions to provide gamma ramp
-support.  If the running X server does not support either or both of these
-extensions, gamma ramp support will not function.
-
-GLFW uses the Xkb extension and detectable auto-repeat to provide keyboard
-input.  If the running X server does not support this extension, a non-Xkb
-fallback path is used.
-
-GLFW uses the XInput2 extension to provide raw, non-accelerated mouse motion
-when the cursor is disabled.  If the running X server does not support this
-extension, regular accelerated mouse motion will be used.
-
-GLFW uses both the XRender extension and the compositing manager to support
-transparent window framebuffers.  If the running X server does not support this
-extension or there is no running compositing manager, the
-`GLFW_TRANSPARENT_FRAMEBUFFER` framebuffer hint will have no effect.
-
-
-@section compat_wayland Wayland protocols and IPC standards
-
-As GLFW uses libwayland directly, without any intervening toolkit library, it
-has sole responsibility for interacting well with every compositor in use on
-Unix-like systems.  Most of the features are provided by the core protocol,
-while cursor support is provided by the libwayland-cursor helper library, EGL
-integration by libwayland-egl, and keyboard handling by
-[libxkbcommon](https://xkbcommon.org/).  In addition, GLFW uses some protocols
-from wayland-protocols to provide additional features if the compositor
-supports them.
-
-GLFW uses xkbcommon 0.5.0 to provide compose key support.  When it has been
-built against an older xkbcommon, the compose key will be disabled even if it
-has been configured in the compositor.
-
-GLFW uses the [xdg-shell
-protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
-to provide better window management.  This protocol is part of
-wayland-protocols 1.12, and mandatory at build time.  If the running compositor
-does not support this protocol, the older [wl_shell
-interface](https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml#n972)
-will be used instead.  This will result in a worse integration with the
-desktop, especially on tiling compositors.
-
-GLFW uses the [relative pointer
-protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml)
-alongside the [pointer constraints
-protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml)
-to implement disabled cursor.  These two protocols are part of
-wayland-protocols 1.1, and mandatory at build time.  If the running compositor
-does not support both of these protocols, disabling the cursor will have no
-effect.
-
-GLFW uses the [idle inhibit
-protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml)
-to prohibit the screensaver from starting.  This protocol is part of
-wayland-protocols 1.6, and mandatory at build time.  If the running compositor
-does not support this protocol, the screensaver may start even for full screen
-windows.
-
-GLFW uses the [xdg-decoration
-protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
-to request decorations to be drawn around its windows.  This protocol is part
-of wayland-protocols 1.15, and mandatory at build time.  If the running
-compositor does not support this protocol, a very simple frame will be drawn by
-GLFW itself, using the [viewporter
-protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/viewporter/viewporter.xml)
-alongside
-[subsurfaces](https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml#n2598).
-This protocol is part of wayland-protocols 1.4, and mandatory at build time.
-If the running compositor does not support this protocol either, no decorations
-will be drawn around windows.
-
-
-@section compat_glx GLX extensions
-
-The GLX API is the default API used to create OpenGL contexts on Unix-like
-systems using the X Window System.
-
-GLFW uses the GLX 1.3 `GLXFBConfig` functions to enumerate and select framebuffer pixel
-formats.  If GLX 1.3 is not supported, @ref glfwInit will fail.
-
-GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and
-`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization
-(or _vsync_), in that order of preference.  Where none of these extension are
-available, calling @ref glfwSwapInterval will have no effect.
-
-GLFW uses the `GLX_ARB_multisample` extension to create contexts with
-multisampling anti-aliasing.  Where this extension is unavailable, the
-`GLFW_SAMPLES` hint will have no effect.
-
-GLFW uses the `GLX_ARB_create_context` extension when available, even when
-creating OpenGL contexts of version 2.1 and below.  Where this extension is
-unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
-hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint
-will have no effect, and setting the `GLFW_OPENGL_PROFILE` or
-`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref
-glfwCreateWindow to fail.
-
-GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for
-context profiles.  Where this extension is unavailable, setting the
-`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE`, or setting
-`GLFW_CLIENT_API` to anything but `GLFW_OPENGL_API` or `GLFW_NO_API` will cause
-@ref glfwCreateWindow to fail.
-
-GLFW uses the `GLX_ARB_context_flush_control` extension to provide control over
-whether a context is flushed when it is released (made non-current).  Where this
-extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no
-effect and the context will always be flushed when released.
-
-GLFW uses the `GLX_ARB_framebuffer_sRGB` and `GLX_EXT_framebuffer_sRGB`
-extensions to provide support for sRGB framebuffers.  Where both of these
-extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
-
-
-@section compat_wgl WGL extensions
-
-The WGL API is used to create OpenGL contexts on Microsoft Windows and other
-implementations of the Win32 API, such as Wine.
-
-GLFW uses either the `WGL_EXT_extension_string` or the
-`WGL_ARB_extension_string` extension to check for the presence of all other WGL
-extensions listed below.  If both are available, the EXT one is preferred.  If
-neither is available, no other extensions are used and many GLFW features
-related to context creation will have no effect or cause errors when used.
-
-GLFW uses the `WGL_EXT_swap_control` extension to provide vertical retrace
-synchronization (or _vsync_).  Where this extension is unavailable, calling @ref
-glfwSwapInterval will have no effect.
-
-GLFW uses the `WGL_ARB_pixel_format` and `WGL_ARB_multisample` extensions to
-create contexts with multisampling anti-aliasing.  Where these extensions are
-unavailable, the `GLFW_SAMPLES` hint will have no effect.
-
-GLFW uses the `WGL_ARB_create_context` extension when available, even when
-creating OpenGL contexts of version 2.1 and below.  Where this extension is
-unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
-hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint
-will have no effect, and setting the `GLFW_OPENGL_PROFILE` or
-`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref
-glfwCreateWindow to fail.
-
-GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for
-context profiles.  Where this extension is unavailable, setting the
-`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE` will cause
-@ref glfwCreateWindow to fail.
-
-GLFW uses the `WGL_ARB_context_flush_control` extension to provide control over
-whether a context is flushed when it is released (made non-current).  Where this
-extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no
-effect and the context will always be flushed when released.
-
-GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB`
-extensions to provide support for sRGB framebuffers.  Where both of these
-extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
-
-
-@section compat_osx OpenGL on macOS
-
-Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then
-only forward-compatible, core profile contexts are supported.  Support for
-OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible,
-core profile contexts.  There is also still no mechanism for requesting debug
-contexts or no-error contexts.  Versions of Mac OS X earlier than 10.7 support
-at most OpenGL version 2.1.
-
-Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and
-`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if
-given version 3.0 or 3.1.  The `GLFW_OPENGL_FORWARD_COMPAT` hint must be set to
-`GLFW_TRUE` and the `GLFW_OPENGL_PROFILE` hint must be set to
-`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts.  The
-`GLFW_OPENGL_DEBUG_CONTEXT` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
-
-Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and
-`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
-setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to
-a non-default value will cause @ref glfwCreateWindow to fail and the
-`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored.
-
-
-@section compat_vulkan Vulkan loader and API
-
-By default, GLFW uses the standard system-wide Vulkan loader to access the
-Vulkan API on all platforms except macOS.  This is installed by both graphics
-drivers and Vulkan SDKs.  If either the loader or at least one minimally
-functional ICD is missing, @ref glfwVulkanSupported will return `GLFW_FALSE` and
-all other Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE
-error.
-
-
-@section compat_wsi Vulkan WSI extensions
-
-The Vulkan WSI extensions are used to create Vulkan surfaces for GLFW windows on
-all supported platforms.
-
-GLFW uses the `VK_KHR_surface` and `VK_KHR_win32_surface` extensions to create
-surfaces on Microsoft Windows.  If any of these extensions are not available,
-@ref glfwGetRequiredInstanceExtensions will return an empty list and window
-surface creation will fail.
-
-GLFW uses the `VK_KHR_surface` and either the `VK_MVK_macos_surface` or
-`VK_EXT_metal_surface` extensions to create surfaces on macOS.  If any of these
-extensions are not available, @ref glfwGetRequiredInstanceExtensions will
-return an empty list and window surface creation will fail.
-
-GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
-`VK_KHR_xcb_surface` extensions to create surfaces on X11.  If `VK_KHR_surface`
-or both `VK_KHR_xlib_surface` and `VK_KHR_xcb_surface` are not available, @ref
-glfwGetRequiredInstanceExtensions will return an empty list and window surface
-creation will fail.
-
-GLFW uses the `VK_KHR_surface` and `VK_KHR_wayland_surface` extensions to create
-surfaces on Wayland.  If any of these extensions are not available, @ref
-glfwGetRequiredInstanceExtensions will return an empty list and window surface
-creation will fail.
-
-*/

+ 0 - 365
samples/third_party/glfw/docs/compile.dox

@@ -1,365 +0,0 @@
-/*!
-
-@page compile_guide Compiling GLFW
-
-@tableofcontents
-
-This is about compiling the GLFW library itself.  For information on how to
-build applications that use GLFW, see @ref build_guide.
-
-
-@section compile_cmake Using CMake
-
-@note GLFW behaves like most other libraries that use CMake so this guide mostly
-describes the basic configure/generate/compile sequence.  If you are already
-familiar with this from other projects, you may want to focus on the @ref
-compile_deps and @ref compile_options sections for GLFW-specific information.
-
-GLFW uses [CMake](https://cmake.org/) to generate project files or makefiles
-for your chosen development environment.  To compile GLFW, first generate these
-files with CMake and then use them to compile the GLFW library. 
-
-If you are on Windows and macOS you can
-[download CMake](https://cmake.org/download/) from their site.
-
-If you are on a Unix-like system such as Linux, FreeBSD or Cygwin or have
-a package system like Fink, MacPorts or Homebrew, you can install its CMake
-package.
-
-CMake is a complex tool and this guide will only show a few of the possible ways
-to set up and compile GLFW.  The CMake project has their own much more detailed
-[CMake user guide](https://cmake.org/cmake/help/latest/guide/user-interaction/)
-that includes everything in this guide not specific to GLFW.  It may be a useful
-companion to this one.
-
-
-@subsection compile_deps Installing dependencies
-
-The C/C++ development environments in Visual Studio, Xcode and MinGW come with
-all necessary dependencies for compiling GLFW, but on Unix-like systems like
-Linux and FreeBSD you will need a few extra packages.
-
-
-@subsubsection compile_deps_x11 Dependencies for X11 on Unix-like systems
-
-To compile GLFW for X11, you need to have the X11 development packages
-installed.  They are not needed to build or run programs that use GLFW.
-
-On Debian and derivates like Ubuntu and Linux Mint the `xorg-dev` meta-package
-pulls in the development packages for all of X11.
-
-@code{.sh}
-sudo apt install xorg-dev
-@endcode
-
-On Fedora and derivatives like Red Hat the X11 extension packages
-`libXcursor-devel`, `libXi-devel`, `libXinerama-devel` and `libXrandr-devel`
-required by GLFW pull in all its other dependencies.
-
-@code{.sh}
-sudo dnf install libXcursor-devel libXi-devel libXinerama-devel libXrandr-devel
-@endcode
-
-On FreeBSD the X11 headers are installed along the end-user X11 packages, so if
-you have an X server running you should have the headers as well.  If not,
-install the `xorgproto` package.
-
-@code{.sh}
-pkg install xorgproto
-@endcode
-
-On Cygwin the `xorgproto` package in the Devel section of the GUI installer will
-install the headers and other development related files for all of X11.
-
-Once you have the required depdendencies, move on to @ref compile_generate.
-
-
-@subsubsection compile_deps_wayland Dependencies for Wayland on Unix-like systems
-
-To compile GLFW for Wayland, you need to have the Wayland and xkbcommon
-development packages installed.  They are not needed to build or run programs
-that use GLFW.
-
-On Debian and derivates like Ubuntu and Linux Mint you will need the `libwayland-dev`,
-`libxkbcommon-dev`, `wayland-protocols` and `extra-cmake-modules` packages.
-
-@code{.sh}
-sudo apt install libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules
-@endcode
-
-On Fedora and derivatives like Red Hat you will need the `wayland-devel`,
-`libxkbcommon-devel`, `wayland-protocols-devel` and `extra-cmake-modules` packages.
-
-@code{.sh}
-sudo dnf install wayland-devel libxkbcommon-devel wayland-protocols-devel extra-cmake-modules
-@endcode
-
-On FreeBSD you will need the `wayland`, `libxkbcommon`, `wayland-protocols` and
-`kf5-extra-cmake-modules` packages.
-
-@code{.sh}
-pkg install wayland libxkbcommon wayland-protocols kf5-extra-cmake-modules
-@endcode
-
-Once you have the required depdendencies, move on to @ref compile_generate.
-
-
-@subsection compile_generate Generating build files with CMake
-
-Once you have all necessary dependencies it is time to generate the project
-files or makefiles for your development environment.  CMake needs two paths for
-this:
-
- - the path to the root directory of the GLFW source tree (not its `src`
-   subdirectory)
- - the path to the directory where the generated build files and compiled
-   binaries will be placed
-
-If these are the same, it is called an in-tree build, otherwise it is called an
-out-of-tree build.
-
-Out-of-tree builds are recommended as they avoid cluttering up the source tree.
-They also allow you to have several build directories for different
-configurations all using the same source tree.
-
-A common pattern when building a single configuration is to have a build
-directory named `build` in the root of the source tree.
-
-
-@subsubsection compile_generate_gui Generating files with the CMake GUI
-
-Start the CMake GUI and set the paths to the source and build directories
-described above.  Then press _Configure_ and _Generate_.
-
-If you wish change any CMake variables in the list, press _Configure_ and then
-_Generate_ to have the new values take effect.  The variable list will be
-populated after the first configure step.
-
-By default GLFW will use X11 on Linux and other Unix-like systems other
-than macOS.  To use Wayland instead, set the `GLFW_USE_WAYLAND` option in the
-GLFW section of the variable list, then apply the new value as described above.
-
-Once you have generated the project files or makefiles for your chosen
-development environment, move on to @ref compile_compile.
-
-
-@subsubsection compile_generate_cli Generating files with the CMake command-line tool
-
-To make a build directory, pass the source and build directories to the `cmake`
-command.  These can be relative or absolute paths.  The build directory is
-created if it doesn't already exist.
-
-@code{.sh}
-cmake -S path/to/glfw -B path/to/build
-@endcode
-
-It is common to name the build directory `build` and place it in the root of the
-source tree when only planning to build a single configuration.
-
-@code{.sh}
-cd path/to/glfw
-cmake -S . -B build
-@endcode
-
-Without other flags these will generate Visual Studio project files on Windows
-and makefiles on other platforms.  You can choose other targets using the `-G`
-flag.
-
-@code{.sh}
-cmake -S path/to/glfw -B path/to/build -G Xcode
-@endcode
-
-By default GLFW will use X11 on Linux and other Unix-like systems other
-than macOS.  To use Wayland instead, set the `GLFW_USE_WAYLAND` CMake option.
-
-@code{.sh}
-cmake -S path/to/glfw -B path/to/build -D GLFW_USE_WAYLAND=1
-@endcode
-
-Once you have generated the project files or makefiles for your chosen
-development environment, move on to @ref compile_compile.
-
-
-@subsection compile_compile Compiling the library
-
-You should now have all required dependencies and the project files or makefiles
-necessary to compile GLFW.  Go ahead and compile the actual GLFW library with
-these files as you would with any other project.
-
-With Visual Studio open `GLFW.sln` and use the Build menu.  With Xcode open
-`GLFW.xcodeproj` and use the Project menu.
-
-With Linux, macOS and other forms of Unix, run `make`.
-
-@code{.sh}
-cd path/to/build
-make
-@endcode
-
-With MinGW, it is `mingw32-make`.
-
-@code{.sh}
-cd path/to/build
-mingw32-make
-@endcode
-
-Any CMake build directory can also be built with the `cmake` command and the
-`--build` flag.
-
-@code{.sh}
-cmake --build path/to/build
-@endcode
-
-This will run the platform specific build tool the directory was generated for.
-
-Once the GLFW library is compiled you are ready to build your application,
-linking it to the GLFW library.  See @ref build_guide for more information.
-
-
-@section compile_options CMake options
-
-The CMake files for GLFW provide a number of options, although not all are
-available on all supported platforms.  Some of these are de facto standards
-among projects using CMake and so have no `GLFW_` prefix.
-
-If you are using the GUI version of CMake, these are listed and can be changed
-from there.  If you are using the command-line version of CMake you can use the
-`ccmake` ncurses GUI to set options.  Some package systems like Ubuntu and other
-distributions based on Debian GNU/Linux have this tool in a separate
-`cmake-curses-gui` package.
-
-Finally, if you don't want to use any GUI, you can set options from the `cmake`
-command-line with the `-D` flag.
-
-@code{.sh}
-cmake -S path/to/glfw -B path/to/build -D BUILD_SHARED_LIBS=ON
-@endcode
-
-
-@subsection compile_options_shared Shared CMake options
-
-@anchor BUILD_SHARED_LIBS
-__BUILD_SHARED_LIBS__ determines whether GLFW is built as a static
-library or as a DLL / shared library / dynamic library.  This is disabled by
-default, producing a static GLFW library.
-
-@anchor GLFW_BUILD_EXAMPLES
-__GLFW_BUILD_EXAMPLES__ determines whether the GLFW examples are built
-along with the library.
-
-@anchor GLFW_BUILD_TESTS
-__GLFW_BUILD_TESTS__ determines whether the GLFW test programs are
-built along with the library.
-
-@anchor GLFW_BUILD_DOCS
-__GLFW_BUILD_DOCS__ determines whether the GLFW documentation is built along
-with the library.  This is enabled by default if
-[Doxygen](https://www.doxygen.nl/) is found by CMake during configuration.
-
-@anchor GLFW_VULKAN_STATIC
-__GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked
-directly with the application.  This is disabled by default.
-
-
-@subsection compile_options_win32 Windows specific CMake options
-
-@anchor USE_MSVC_RUNTIME_LIBRARY_DLL
-__USE_MSVC_RUNTIME_LIBRARY_DLL__ determines whether to use the DLL version or the
-static library version of the Visual C++ runtime library.  When enabled, the
-DLL version of the Visual C++ library is used.  This is enabled by default.
-
-On CMake 3.15 and later you can set the standard CMake
-[CMAKE_MSVC_RUNTIME_LIBRARY](https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html)
-variable instead of this GLFW-specific option.
-
-@anchor GLFW_USE_HYBRID_HPG
-__GLFW_USE_HYBRID_HPG__ determines whether to export the `NvOptimusEnablement` and
-`AmdPowerXpressRequestHighPerformance` symbols, which force the use of the
-high-performance GPU on Nvidia Optimus and AMD PowerXpress systems.  These symbols
-need to be exported by the EXE to be detected by the driver, so the override
-will not work if GLFW is built as a DLL.  This is disabled by default, letting
-the operating system and driver decide.
-
-
-@subsection compile_options_wayland Wayland specific CMake options
-
-@anchor GLFW_USE_WAYLAND
-__GLFW_USE_WAYLAND__ determines whether to compile the library for Wayland.
-This option is only available on Linux and other Unix-like systems other than
-macOS.  This is disabled by default.
-
-
-@section compile_mingw_cross Cross-compilation with CMake and MinGW
-
-Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages.  For
-example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages
-for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives
-like Ubuntu have the `mingw-w64` package for both.
-
-GLFW has CMake toolchain files in the `CMake` subdirectory that set up
-cross-compilation of Windows binaries.  To use these files you set the
-`CMAKE_TOOLCHAIN_FILE` CMake variable with the `-D` flag add an option when
-configuring and generating the build files.
-
-@code{.sh}
-cmake -S path/to/glfw -B path/to/build -D CMAKE_TOOLCHAIN_FILE=path/to/file
-@endcode
-
-The exact toolchain file to use depends on the prefix used by the MinGW or
-MinGW-w64 binaries on your system.  You can usually see this in the /usr
-directory.  For example, both the Ubuntu and Cygwin MinGW-w64 packages have
-`/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct invocation
-would be:
-
-@code{.sh}
-cmake -S path/to/glfw -B path/to/build -D CMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake
-@endcode
-
-The path to the toolchain file is relative to the path to the GLFW source tree
-passed to the `-S` flag, not to the current directory.
-
-For more details see the
-[CMake toolchain guide](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html).
-
-
-@section compile_manual Compiling GLFW manually
-
-If you wish to compile GLFW without its CMake build environment then you will
-have to do at least some of the platform detection yourself.  GLFW needs
-a configuration macro to be defined in order to know what window system it is
-being compiled for and also has optional, platform-specific ones for various
-features.
-
-When building with CMake, the `glfw_config.h` configuration header is generated
-based on the current platform and CMake options.  The GLFW CMake environment
-defines @b GLFW_USE_CONFIG_H, which causes this header to be included by
-`internal.h`.  Without this macro, GLFW will expect the necessary configuration
-macros to be defined on the command-line.
-
-The window creation API is used to create windows, handle input, monitors, gamma
-ramps and clipboard.  The options are:
-
- - @b _GLFW_COCOA to use the Cocoa frameworks
- - @b _GLFW_WIN32 to use the Win32 API
- - @b _GLFW_X11 to use the X Window System
- - @b _GLFW_WAYLAND to use the Wayland API (experimental and incomplete)
- - @b _GLFW_OSMESA to use the OSMesa API (headless and non-interactive)
-
-If you are building GLFW as a shared library / dynamic library / DLL then you
-must also define @b _GLFW_BUILD_DLL.  Otherwise, you must not define it.
-
-If you are linking the Vulkan loader directly with your application then you
-must also define @b _GLFW_VULKAN_STATIC.  Otherwise, GLFW will attempt to use the
-external version.
-
-If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
-or GLESv2 library, you can override the default names by defining those you need
-of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b
-_GLFW_OSMESA_LIBRARY, @b _GLFW_OPENGL_LIBRARY, @b _GLFW_GLESV1_LIBRARY and @b
-_GLFW_GLESV2_LIBRARY.  Otherwise, GLFW will use the built-in default names.
-
-@note None of the @ref build_macros may be defined during the compilation of
-GLFW.  If you define any of these in your build files, make sure they are not
-applied to the GLFW sources.
-
-*/

+ 0 - 346
samples/third_party/glfw/docs/context.dox

@@ -1,346 +0,0 @@
-/*!
-
-@page context_guide Context guide
-
-@tableofcontents
-
-This guide introduces the OpenGL and OpenGL ES context related functions of
-GLFW.  For details on a specific function in this category, see the @ref
-context.  There are also guides for the other areas of the GLFW API.
-
- - @ref intro_guide
- - @ref window_guide
- - @ref vulkan_guide
- - @ref monitor_guide
- - @ref input_guide
-
-
-@section context_object Context objects
-
-A window object encapsulates both a top-level window and an OpenGL or OpenGL ES
-context.  It is created with @ref glfwCreateWindow and destroyed with @ref
-glfwDestroyWindow or @ref glfwTerminate.  See @ref window_creation for more
-information.
-
-As the window and context are inseparably linked, the window object also serves
-as the context handle.
-
-To test the creation of various kinds of contexts and see their properties, run
-the `glfwinfo` test program.
-
-@note Vulkan does not have a context and the Vulkan instance is created via the
-Vulkan API itself.  If you will be using Vulkan to render to a window, disable
-context creation by setting the [GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint)
-hint to `GLFW_NO_API`.  For more information, see the @ref vulkan_guide.
-
-
-@subsection context_hints Context creation hints
-
-There are a number of hints, specified using @ref glfwWindowHint, related to
-what kind of context is created.  See
-[context related hints](@ref window_hints_ctx) in the window guide.
-
-
-@subsection context_sharing Context object sharing
-
-When creating a window and its OpenGL or OpenGL ES context with @ref
-glfwCreateWindow, you can specify another window whose context the new one
-should share its objects (textures, vertex and element buffers, etc.) with.
-
-@code
-GLFWwindow* second_window = glfwCreateWindow(640, 480, "Second Window", NULL, first_window);
-@endcode
-
-Object sharing is implemented by the operating system and graphics driver.  On
-platforms where it is possible to choose which types of objects are shared, GLFW
-requests that all types are shared.
-
-See the relevant chapter of the [OpenGL](https://www.opengl.org/registry/) or
-[OpenGL ES](https://www.khronos.org/opengles/) reference documents for more
-information.  The name and number of this chapter unfortunately varies between
-versions and APIs, but has at times been named _Shared Objects and Multiple
-Contexts_.
-
-GLFW comes with a barebones object sharing example program called `sharing`.
-
-
-@subsection context_offscreen Offscreen contexts
-
-GLFW doesn't support creating contexts without an associated window.  However,
-contexts with hidden windows can be created with the
-[GLFW_VISIBLE](@ref GLFW_VISIBLE_hint) window hint.
-
-@code
-glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
-
-GLFWwindow* offscreen_context = glfwCreateWindow(640, 480, "", NULL, NULL);
-@endcode
-
-The window never needs to be shown and its context can be used as a plain
-offscreen context.  Depending on the window manager, the size of a hidden
-window's framebuffer may not be usable or modifiable, so framebuffer
-objects are recommended for rendering with such contexts.
-
-You should still [process events](@ref events) as long as you have at least one
-window, even if none of them are visible.
-
-@macos The first time a window is created the menu bar is created.  This is not
-desirable for example when writing a command-line only application.  Menu bar
-creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
-
-
-@subsection context_less Windows without contexts
-
-You can disable context creation by setting the
-[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`.  Windows
-without contexts must not be passed to @ref glfwMakeContextCurrent or @ref
-glfwSwapBuffers.
-
-
-@section context_current Current context
-
-Before you can make OpenGL or OpenGL ES calls, you need to have a current
-context of the correct type.  A context can only be current for a single thread
-at a time, and a thread can only have a single context current at a time.
-
-When moving a context between threads, you must make it non-current on the old
-thread before making it current on the new one.
-
-The context of a window is made current with @ref glfwMakeContextCurrent.
-
-@code
-glfwMakeContextCurrent(window);
-@endcode
-
-The window of the current context is returned by @ref glfwGetCurrentContext.
-
-@code
-GLFWwindow* window = glfwGetCurrentContext();
-@endcode
-
-The following GLFW functions require a context to be current.  Calling any these
-functions without a current context will generate a @ref GLFW_NO_CURRENT_CONTEXT
-error.
-
- - @ref glfwSwapInterval
- - @ref glfwExtensionSupported
- - @ref glfwGetProcAddress
-
-
-@section context_swap Buffer swapping
-
-See @ref buffer_swap in the window guide.
-
-
-@section context_glext OpenGL and OpenGL ES extensions
-
-One of the benefits of OpenGL and OpenGL ES is their extensibility.
-Hardware vendors may include extensions in their implementations that extend the
-API before that functionality is included in a new version of the OpenGL or
-OpenGL ES specification, and some extensions are never included and remain
-as extensions until they become obsolete.
-
-An extension is defined by:
-
-- An extension name (e.g. `GL_ARB_gl_spirv`)
-- New OpenGL tokens (e.g. `GL_SPIR_V_BINARY_ARB`)
-- New OpenGL functions (e.g. `glSpecializeShaderARB`)
-
-Note the `ARB` affix, which stands for Architecture Review Board and is used
-for official extensions.  The extension above was created by the ARB, but there
-are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD.  Any
-group may also use the generic `EXT` affix.  Lists of extensions, together with
-their specifications, can be found at the
-[OpenGL Registry](https://www.opengl.org/registry/) and
-[OpenGL ES Registry](https://www.khronos.org/registry/gles/).
-
-
-@subsection context_glext_auto Loading extension with a loader library
-
-An extension loader library is the easiest and best way to access both OpenGL and
-OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs.
-They will take care of all the details of declaring and loading everything you
-need.  One such library is [glad](https://github.com/Dav1dde/glad) and there are
-several others.
-
-The following example will use glad but all extension loader libraries work
-similarly.
-
-First you need to generate the source files using the glad Python script.  This
-example generates a loader for any version of OpenGL, which is the default for
-both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific
-API versions and extension sets can be generated.  The generated files are
-written to the `output` directory.
-
-@code{.sh}
-python main.py --generator c --no-loader --out-path output
-@endcode
-
-The `--no-loader` option is added because GLFW already provides a function for
-loading OpenGL and OpenGL ES function pointers, one that automatically uses the
-selected context creation API, and glad can call this instead of having to
-implement its own.  There are several other command-line options as well.  See
-the glad documentation for details.
-
-Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and
-`output/include/KHR/khrplatform.h` files to your build.  Then you need to
-include the glad header file, which will replace the OpenGL header of your
-development environment.  By including the glad header before the GLFW header,
-it suppresses the development environment's OpenGL or OpenGL ES header.
-
-@code
-#include <glad/glad.h>
-#include <GLFW/glfw3.h>
-@endcode
-
-Finally you need to initialize glad once you have a suitable current context.
-
-@code
-window = glfwCreateWindow(640, 480, "My Window", NULL, NULL);
-if (!window)
-{
-    ...
-}
-
-glfwMakeContextCurrent(window);
-
-gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
-@endcode
-
-Once glad has been loaded, you have access to all OpenGL core and extension
-functions supported by both the context you created and the glad loader you
-generated and you are ready to start rendering.
-
-You can specify a minimum required OpenGL or OpenGL ES version with
-[context hints](@ref window_hints_ctx).  If your needs are more complex, you can
-check the actual OpenGL or OpenGL ES version with
-[context attributes](@ref window_attribs_ctx), or you can check whether
-a specific version is supported by the current context with the
-`GLAD_GL_VERSION_x_x` booleans.
-
-@code
-if (GLAD_GL_VERSION_3_2)
-{
-    // Call OpenGL 3.2+ specific code
-}
-@endcode
-
-To check whether a specific extension is supported, use the `GLAD_GL_xxx`
-booleans.
-
-@code
-if (GLAD_GL_ARB_gl_spirv)
-{
-    // Use GL_ARB_gl_spirv
-}
-@endcode
-
-
-@subsection context_glext_manual Loading extensions manually
-
-__Do not use this technique__ unless it is absolutely necessary.  An
-[extension loader library](@ref context_glext_auto) will save you a ton of
-tedious, repetitive, error prone work.
-
-To use a certain extension, you must first check whether the context supports
-that extension and then, if it introduces new functions, retrieve the pointers
-to those functions.  GLFW provides @ref glfwExtensionSupported and @ref
-glfwGetProcAddress for manual loading of extensions and new API functions.
-
-This section will demonstrate manual loading of OpenGL extensions.  The loading
-of OpenGL ES extensions is identical except for the name of the extension header.
-
-
-@subsubsection context_glext_header The glext.h header
-
-The `glext.h` extension header is a continually updated file that defines the
-interfaces for all OpenGL extensions.  The latest version of this can always be
-found at the [OpenGL Registry](https://www.opengl.org/registry/).  There are also
-extension headers for the various versions of OpenGL ES at the
-[OpenGL ES Registry](https://www.khronos.org/registry/gles/).  It it strongly
-recommended that you use your own copy of the extension header, as the one
-included in your development environment may be several years out of date and
-may not include the extensions you wish to use.
-
-The header defines function pointer types for all functions of all extensions it
-supports.  These have names like `PFNGLSPECIALIZESHADERARBPROC` (for
-`glSpecializeShaderARB`), i.e. the name is made uppercase and `PFN` (pointer
-to function) and `PROC` (procedure) are added to the ends.
-
-To include the extension header, define @ref GLFW_INCLUDE_GLEXT before including
-the GLFW header.
-
-@code
-#define GLFW_INCLUDE_GLEXT
-#include <GLFW/glfw3.h>
-@endcode
-
-
-@subsubsection context_glext_string Checking for extensions
-
-A given machine may not actually support the extension (it may have older
-drivers or a graphics card that lacks the necessary hardware features), so it
-is necessary to check at run-time whether the context supports the extension.
-This is done with @ref glfwExtensionSupported.
-
-@code
-if (glfwExtensionSupported("GL_ARB_gl_spirv"))
-{
-    // The extension is supported by the current context
-}
-@endcode
-
-The argument is a null terminated ASCII string with the extension name.  If the
-extension is supported, @ref glfwExtensionSupported returns `GLFW_TRUE`,
-otherwise it returns `GLFW_FALSE`.
-
-
-@subsubsection context_glext_proc Fetching function pointers
-
-Many extensions, though not all, require the use of new OpenGL functions.
-These functions often do not have entry points in the client API libraries of
-your operating system, making it necessary to fetch them at run time.  You can
-retrieve pointers to these functions with @ref glfwGetProcAddress.
-
-@code
-PFNGLSPECIALIZESHADERARBPROC pfnSpecializeShaderARB = glfwGetProcAddress("glSpecializeShaderARB");
-@endcode
-
-In general, you should avoid giving the function pointer variables the (exact)
-same name as the function, as this may confuse your linker.  Instead, you can
-use a different prefix, like above, or some other naming scheme.
-
-Now that all the pieces have been introduced, here is what they might look like
-when used together.
-
-@code
-#define GLFW_INCLUDE_GLEXT
-#include <GLFW/glfw3.h>
-
-#define glSpecializeShaderARB pfnSpecializeShaderARB
-PFNGLSPECIALIZESHADERARBPROC pfnSpecializeShaderARB;
-
-// Flag indicating whether the extension is supported
-int has_ARB_gl_spirv = 0;
-
-void load_extensions(void)
-{
-    if (glfwExtensionSupported("GL_ARB_gl_spirv"))
-    {
-        pfnSpecializeShaderARB = (PFNGLSPECIALIZESHADERARBPROC)
-            glfwGetProcAddress("glSpecializeShaderARB");
-        has_ARB_gl_spirv = 1;
-    }
-}
-
-void some_function(void)
-{
-    if (has_ARB_gl_spirv)
-    {
-        // Now the extension function can be called as usual
-        glSpecializeShaderARB(...);
-    }
-}
-@endcode
-
-*/

ファイルの差分が大きいため隠しています
+ 0 - 1
samples/third_party/glfw/docs/extra.css


ファイルの差分が大きいため隠しています
+ 0 - 1
samples/third_party/glfw/docs/extra.css.map


+ 0 - 430
samples/third_party/glfw/docs/extra.scss

@@ -1,430 +0,0 @@
-// NOTE: Please use this file to perform modifications on default style sheets.
-//
-// You need to install the official Sass CLI tool:
-// npm install -g sass
-//
-// Run this command to regenerate extra.css after you're finished with changes:
-// sass --style=compressed extra.scss extra.css
-//
-// Alternatively you can use online services to regenerate extra.css.
-
-
-// Default text color for page contents
-$default-text-color: hsl(0,0%,30%);
-
-// Page header, footer, table rows, inline codes and definition lists
-$header-footer-background-color: hsl(0,0%,95%);
-
-// Page header, footer links and navigation bar background
-$header-footer-link-color: hsl(0,0%,40%);
-
-// Doxygen navigation bar links
-$navbar-link-color: $header-footer-background-color;
-
-// Page content background color
-$content-background-color: hsl(0,0%,100%);
-
-// Bold, italic, h1, h2, ... and table of contents
-$heading-color: hsl(0,0%,10%);
-
-// Function, enum and macro definition separator
-$def-separator-color: $header-footer-background-color;
-
-// Base color hue
-$base-hue: 24;
-
-// Default color used for links
-$default-link-color: hsl($base-hue,100%,50%);
-
-// Doxygen navigation bar active tab
-$tab-text-color: hsl(0,0%,100%);
-$tab-background-color1: $default-link-color;
-$tab-background-color2: lighten(adjust-hue($tab-background-color1, 10), 10%);
-
-// Table borders
-$default-border-color: $default-link-color;
-
-// Table header
-$table-text-color: $tab-text-color;
-$table-background-color1: $tab-background-color1;
-$table-background-color2: $tab-background-color2;
-
-// Table of contents, data structure index and prototypes
-$toc-background-color1: hsl(0,0%,90%);
-$toc-background-color2: lighten($toc-background-color1, 5%);
-
-// Function prototype parameters color
-$prototype-param-color: darken($default-link-color, 25%);
-
-// Message box color: note, pre, post and invariant
-$box-note-color: hsl(103,80%,85%);
-
-// Message box color: warning and attention
-$box-warning-color: hsl(34,80%,85%);
-
-// Message box color: deprecated and bug
-$box-bug-color: hsl(333,80%,85%);
-
-// Message box color: todo and test
-$box-todo-color: hsl(200,80%,85%);
-
-// Message box helper function
-@mixin message-box($base-color){
-	background:linear-gradient(to bottom,lighten($base-color, 5%) 0%,$base-color 100%);
-	box-shadow:inset 0 0 32px darken($base-color, 5%);
-	color:darken($base-color, 67%);
-	border:2px solid desaturate(darken($base-color, 10%), 20%);
-}
-
-.sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover {
-	background:none;
-	text-shadow:none;
-}
-
-.sm-dox a span.sub-arrow {
-	border-color:$navbar-link-color transparent transparent transparent;
-}
-
-.sm-dox a span.sub-arrow:active,.sm-dox a span.sub-arrow:focus,.sm-dox a span.sub-arrow:hover,.sm-dox a:hover span.sub-arrow {
-	border-color:$default-link-color transparent transparent transparent;
-}
-
-.sm-dox ul a span.sub-arrow:active,.sm-dox ul a span.sub-arrow:focus,.sm-dox ul a span.sub-arrow:hover,.sm-dox ul a:hover span.sub-arrow {
-	border-color:transparent transparent transparent $default-link-color;
-}
-
-.sm-dox ul a:hover {
-	background:$header-footer-link-color;
-	text-shadow:none;
-}
-
-.sm-dox ul.sm-nowrap a {
-	color:$default-text-color;
-	text-shadow:none;
-}
-
-#main-nav,#main-menu,#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code,.markdownTable code {
-	background:none;
-}
-
-#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,table.markdownTable td,table.markdownTable th,hr,.memSeparator {
-	border:none;
-}
-
-#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.reflist dt a.el,.levels span,.directory .levels span {
-	text-shadow:none;
-}
-
-.memdoc,dl.reflist dd {
-	box-shadow:none;
-}
-
-div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code,table.markdownTable code {
-	padding:0;
-}
-
-#nav-path,.directory .levels,span.lineno {
-	display:none;
-}
-
-html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code,.markdownTableRowEven {
-	background:$header-footer-background-color;
-}
-
-body {
-	color:$default-text-color;
-}
-
-h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em {
-	color:$heading-color;
-	border-bottom:none;
-}
-
-h1 {
-	padding-top:0.5em;
-	font-size:180%;
-}
-
-h2 {
-	padding-top:0.5em;
-	margin-bottom:0;
-	font-size:140%;
-}
-
-h3 {
-	padding-top:0.5em;
-	margin-bottom:0;
-	font-size:110%;
-}
-
-.glfwheader {
-	font-size:16px;
-	min-height:64px;
-	max-width:920px;
-	padding:0 32px;
-	margin:0 auto;
-
-	display: flex;
-	flex-direction: row;
-	flex-wrap: wrap;
-	justify-content: flex-start;
-	align-items: center;
-	align-content: stretch;
-}
-
-#glfwhome {
-	line-height:64px;
-	padding-right:48px;
-	color:$header-footer-link-color;
-	font-size:2.5em;
-	background:url("https://www.glfw.org/css/arrow.png") no-repeat right;
-}
-
-.glfwnavbar {
-	list-style-type:none;
-	margin:0 0 0 auto;
-	float:right;
-}
-
-#glfwhome,.glfwnavbar li {
-	float:left;
-}
-
-.glfwnavbar a,.glfwnavbar a:visited {
-	line-height:64px;
-	margin-left:2em;
-	display:block;
-	color:$header-footer-link-color;
-}
-
-.glfwnavbar {
-	padding-left: 0;
-}
-
-#glfwhome,.glfwnavbar a,.glfwnavbar a:visited {
-	transition:.35s ease;
-}
-
-#titlearea,.footer {
-	color:$header-footer-link-color;
-}
-
-address.footer {
-	text-align:center;
-	padding:2em;
-	margin-top:3em;
-}
-
-#top {
-	background:$header-footer-link-color;
-}
-
-#main-nav {
-	max-width:960px;
-	margin:0 auto;
-	font-size:13px;
-}
-
-#main-menu {
-	max-width:920px;
-	margin:0 auto;
-	font-size:13px;
-}
-
-.memtitle {
-	display:none;
-}
-
-.memproto,.memname {
-	font-weight:bold;
-	text-shadow:none;
-}
-
-#main-menu {
-	min-height:36px;
-	display: flex;
-	flex-direction: row;
-	flex-wrap: wrap;
-	justify-content: flex-start;
-	align-items: center;
-	align-content: stretch;
-}
-
-#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li {
-	color:$navbar-link-color;
-}
-
-#main-menu li ul.sm-nowrap li a {
-	color:$default-text-color;
-}
-
-#main-menu li ul.sm-nowrap li a:hover {
-	color:$default-link-color;
-}
-
-#main-menu > li:last-child {
-	margin: 0 0 0 auto;
-}
-
-.contents {
-	min-height:590px;
-}
-
-div.contents,div.header {
-	max-width:920px;
-	margin:0 auto;
-	padding:0 32px;
-	background:$content-background-color none;
-}
-
-table.doxtable th,table.markdownTable th,dl.reflist dt {
-	background:linear-gradient(to bottom,$table-background-color2 0%,$table-background-color1 100%);
-	box-shadow:inset 0 0 32px $table-background-color1;
-	text-shadow:0 -1px 1px darken($table-background-color1, 15%);
-	text-align:left;
-	color:$table-text-color;
-}
-
-dl.reflist dt a.el {
-	color:$default-link-color;
-	padding:.2em;
-	border-radius:4px;
-	background-color:lighten($default-link-color, 40%);
-}
-
-div.toc {
-	float:none;
-	width:auto;
-}
-
-div.toc h3 {
-	font-size:1.17em;
-}
-
-div.toc ul {
-	padding-left:1.5em;
-}
-
-div.toc li {
-	font-size:1em;
-	padding-left:0;
-	list-style-type:disc;
-}
-
-div.toc,.memproto,div.qindex,div.ah {
-	background:linear-gradient(to bottom,$toc-background-color2 0%,$toc-background-color1 100%);
-	box-shadow:inset 0 0 32px $toc-background-color1;
-	text-shadow:0 1px 1px lighten($toc-background-color2, 10%);
-	color:$heading-color;
-	border:2px solid $toc-background-color1;
-	border-radius:4px;
-}
-
-.paramname {
-	color:$prototype-param-color;
-}
-
-dl.reflist dt {
-	border:2px solid $default-border-color;
-	border-top-left-radius:4px;
-	border-top-right-radius:4px;
-	border-bottom:none;
-}
-
-dl.reflist dd {
-	border:2px solid $default-border-color;
-	border-bottom-right-radius:4px;
-	border-bottom-left-radius:4px;
-	border-top:none;
-}
-
-table.doxtable,table.markdownTable {
-	border-collapse:inherit;
-	border-spacing:0;
-	border:2px solid $default-border-color;
-	border-radius:4px;
-}
-
-a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,#main-menu a:hover,span.lineno a:hover {
-	color:$default-link-color;
-	text-decoration:none;
-}
-
-div.directory {
-	border-collapse:inherit;
-	border-spacing:0;
-	border:2px solid $default-border-color;
-	border-radius:4px;
-}
-
-hr,.memSeparator {
-	height:2px;
-	background:linear-gradient(to right,$def-separator-color 0%,darken($def-separator-color, 10%) 50%,$def-separator-color 100%);
-}
-
-dl.note,dl.pre,dl.post,dl.invariant {
-	@include message-box($box-note-color);
-}
-
-dl.warning,dl.attention {
-	@include message-box($box-warning-color);
-}
-
-dl.deprecated,dl.bug {
-	@include message-box($box-bug-color);
-}
-
-dl.todo,dl.test {
-	@include message-box($box-todo-color);
-}
-
-dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test {
-	border-radius:4px;
-	padding:1em;
-	text-shadow:0 1px 1px hsl(0,0%,100%);
-	margin:1em 0;
-}
-
-.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited {
-	color:inherit;
-}
-
-div.line {
-	line-height:inherit;
-}
-
-div.fragment,pre.fragment {
-	background:hsl(0,0%,95%);
-	border-radius:4px;
-	border:none;
-	padding:1em;
-	overflow:auto;
-	border-left:4px solid hsl(0,0%,80%);
-	margin:1em 0;
-}
-
-.lineno a,.lineno a:visited,.line,pre.fragment {
-	color:$default-text-color;
-}
-
-span.preprocessor,span.comment {
-	color:hsl(193,100%,30%);
-}
-
-a.code,a.code:visited {
-	color:hsl(18,100%,45%);
-}
-
-span.keyword,span.keywordtype,span.keywordflow {
-	color:darken($default-text-color, 5%);
-	font-weight:bold;
-}
-
-span.stringliteral {
-	color:hsl(261,100%,30%);
-}
-
-code {
-	padding:.1em;
-	border-radius:4px;
-}

+ 0 - 7
samples/third_party/glfw/docs/footer.html

@@ -1,7 +0,0 @@
-<address class="footer">
-<p>
-Last update on $date for $projectname $projectnumber
-</p>
-</address>
-</body>
-</html>

+ 0 - 34
samples/third_party/glfw/docs/header.html

@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen $doxygenversion"/>
-<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
-<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
-<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="$relpath^jquery.js"></script>
-<script type="text/javascript" src="$relpath^dynsections.js"></script>
-$treeview
-$search
-$mathjax
-<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
-$extrastylesheet
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-
-<!--BEGIN TITLEAREA-->
-<div id="titlearea">
-	<div class="glfwheader">
-		<a href="https://www.glfw.org/" id="glfwhome">GLFW</a>
-		<ul class="glfwnavbar">
-			<li><a href="https://www.glfw.org/documentation.html">Documentation</a></li>
-			<li><a href="https://www.glfw.org/download.html">Download</a></li>
-			<li><a href="https://www.glfw.org/community.html">Community</a></li>
-		</ul>
-	</div>
-</div>
-<!--END TITLEAREA-->
-<!-- end header part -->

+ 0 - 950
samples/third_party/glfw/docs/input.dox

@@ -1,950 +0,0 @@
-/*!
-
-@page input_guide Input guide
-
-@tableofcontents
-
-This guide introduces the input related functions of GLFW.  For details on
-a specific function in this category, see the @ref input.  There are also guides
-for the other areas of GLFW.
-
- - @ref intro_guide
- - @ref window_guide
- - @ref context_guide
- - @ref vulkan_guide
- - @ref monitor_guide
-
-GLFW provides many kinds of input.  While some can only be polled, like time, or
-only received via callbacks, like scrolling, many provide both callbacks and
-polling.  Callbacks are more work to use than polling but is less CPU intensive
-and guarantees that you do not miss state changes.
-
-All input callbacks receive a window handle.  By using the
-[window user pointer](@ref window_userptr), you can access non-global structures
-or objects from your callbacks.
-
-To get a better feel for how the various events callbacks behave, run the
-`events` test program.  It register every callback supported by GLFW and prints
-out all arguments provided for every event, along with time and sequence
-information.
-
-
-@section events Event processing
-
-GLFW needs to poll the window system for events both to provide input to the
-application and to prove to the window system that the application hasn't locked
-up.  Event processing is normally done each frame after
-[buffer swapping](@ref buffer_swap).  Even when you have no windows, event
-polling needs to be done in order to receive monitor and joystick connection
-events.
-
-There are three functions for processing pending events.  @ref glfwPollEvents,
-processes only those events that have already been received and then returns
-immediately.
-
-@code
-glfwPollEvents();
-@endcode
-
-This is the best choice when rendering continuously, like most games do.
-
-If you only need to update the contents of the window when you receive new
-input, @ref glfwWaitEvents is a better choice.
-
-@code
-glfwWaitEvents();
-@endcode
-
-It puts the thread to sleep until at least one event has been received and then
-processes all received events.  This saves a great deal of CPU cycles and is
-useful for, for example, editing tools.
-
-If you want to wait for events but have UI elements or other tasks that need
-periodic updates, @ref glfwWaitEventsTimeout lets you specify a timeout.
-
-@code
-glfwWaitEventsTimeout(0.7);
-@endcode
-
-It puts the thread to sleep until at least one event has been received, or until
-the specified number of seconds have elapsed.  It then processes any received
-events.
-
-If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from
-another thread by posting an empty event to the event queue with @ref
-glfwPostEmptyEvent.
-
-@code
-glfwPostEmptyEvent();
-@endcode
-
-Do not assume that callbacks will _only_ be called in response to the above
-functions.  While it is necessary to process events in one or more of the ways
-above, window systems that require GLFW to register callbacks of its own can
-pass events to GLFW in response to many window system function calls.  GLFW will
-pass those events on to the application callbacks before returning.
-
-For example, on Windows the system function that @ref glfwSetWindowSize is
-implemented with will send window size events directly to the event callback
-that every window has and that GLFW implements for its windows.  If you have set
-a [window size callback](@ref window_size) GLFW will call it in turn with the
-new size before everything returns back out of the @ref glfwSetWindowSize call.
-
-
-@section input_keyboard Keyboard input
-
-GLFW divides keyboard input into two categories; key events and character
-events.  Key events relate to actual physical keyboard keys, whereas character
-events relate to the Unicode code points generated by pressing some of them.
-
-Keys and characters do not map 1:1.  A single key press may produce several
-characters, and a single character may require several keys to produce.  This
-may not be the case on your machine, but your users are likely not all using the
-same keyboard layout, input method or even operating system as you.
-
-
-@subsection input_key Key input
-
-If you wish to be notified when a physical key is pressed or released or when it
-repeats, set a key callback.
-
-@code
-glfwSetKeyCallback(window, key_callback);
-@endcode
-
-The callback function receives the [keyboard key](@ref keys), platform-specific
-scancode, key action and [modifier bits](@ref mods).
-
-@code
-void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
-{
-    if (key == GLFW_KEY_E && action == GLFW_PRESS)
-        activate_airship();
-}
-@endcode
-
-The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`.  The key
-will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example
-_E-mail_ and _Play_ keys.
-
-The scancode is unique for every key, regardless of whether it has a key token.
-Scancodes are platform-specific but consistent over time, so keys will have
-different scancodes depending on the platform but they are safe to save to disk.
-You can query the scancode for any [named key](@ref keys) on the current
-platform with @ref glfwGetKeyScancode.
-
-@code
-const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
-set_key_mapping(scancode, swap_weapons);
-@endcode
-
-The last reported state for every [named key](@ref keys) is also saved in
-per-window state arrays that can be polled with @ref glfwGetKey.
-
-@code
-int state = glfwGetKey(window, GLFW_KEY_E);
-if (state == GLFW_PRESS)
-{
-    activate_airship();
-}
-@endcode
-
-The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
-
-This function only returns cached key event state.  It does not poll the
-system for the current physical state of the key.
-
-@anchor GLFW_STICKY_KEYS
-Whenever you poll state, you risk missing the state change you are looking for.
-If a pressed key is released again before you poll its state, you will have
-missed the key press.  The recommended solution for this is to use a
-key callback, but there is also the `GLFW_STICKY_KEYS` input mode.
-
-@code
-glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE);
-@endcode
-
-When sticky keys mode is enabled, the pollable state of a key will remain
-`GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey.  Once
-it has been polled, if a key release event had been processed in the meantime,
-the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`.
-
-@anchor GLFW_LOCK_KEY_MODS
-If you wish to know what the state of the Caps Lock and Num Lock keys was when
-input events were generated, set the `GLFW_LOCK_KEY_MODS` input mode.
-
-@code
-glfwSetInputMode(window, GLFW_LOCK_KEY_MODS, GLFW_TRUE);
-@endcode
-
-When this input mode is enabled, any callback that receives
-[modifier bits](@ref mods) will have the @ref GLFW_MOD_CAPS_LOCK bit set if Caps
-Lock was on when the event occurred and the @ref GLFW_MOD_NUM_LOCK bit set if
-Num Lock was on.
-
-The `GLFW_KEY_LAST` constant holds the highest value of any
-[named key](@ref keys).
-
-
-@subsection input_char Text input
-
-GLFW supports text input in the form of a stream of
-[Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the
-operating system text input system.  Unlike key input, text input obeys keyboard
-layouts and modifier keys and supports composing characters using
-[dead keys](https://en.wikipedia.org/wiki/Dead_key).  Once received, you can
-encode the code points into UTF-8 or any other encoding you prefer.
-
-Because an `unsigned int` is 32 bits long on all platforms supported by GLFW,
-you can treat the code point argument as native endian UTF-32.
-
-If you wish to offer regular text input, set a character callback.
-
-@code
-glfwSetCharCallback(window, character_callback);
-@endcode
-
-The callback function receives Unicode code points for key events that would
-have led to regular text input and generally behaves as a standard text field on
-that platform.
-
-@code
-void character_callback(GLFWwindow* window, unsigned int codepoint)
-{
-}
-@endcode
-
-
-@subsection input_key_name Key names
-
-If you wish to refer to keys by name, you can query the keyboard layout
-dependent name of printable keys with @ref glfwGetKeyName.
-
-@code
-const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0);
-show_tutorial_hint("Press %s to move forward", key_name);
-@endcode
-
-This function can handle both [keys and scancodes](@ref input_key).  If the
-specified key is `GLFW_KEY_UNKNOWN` then the scancode is used, otherwise it is
-ignored.  This matches the behavior of the key callback, meaning the callback
-arguments can always be passed unmodified to this function.
-
-
-@section input_mouse Mouse input
-
-Mouse input comes in many forms, including mouse motion, button presses and
-scrolling offsets.  The cursor appearance can also be changed, either to
-a custom image or a standard cursor shape from the system theme.
-
-
-@subsection cursor_pos Cursor position
-
-If you wish to be notified when the cursor moves over the window, set a cursor
-position callback.
-
-@code
-glfwSetCursorPosCallback(window, cursor_position_callback);
-@endcode
-
-The callback functions receives the cursor position, measured in screen
-coordinates but relative to the top-left corner of the window content area.  On
-platforms that provide it, the full sub-pixel cursor position is passed on.
-
-@code
-static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
-{
-}
-@endcode
-
-The cursor position is also saved per-window and can be polled with @ref
-glfwGetCursorPos.
-
-@code
-double xpos, ypos;
-glfwGetCursorPos(window, &xpos, &ypos);
-@endcode
-
-
-@subsection cursor_mode Cursor mode
-
-@anchor GLFW_CURSOR
-The `GLFW_CURSOR` input mode provides several cursor modes for special forms of
-mouse motion input.  By default, the cursor mode is `GLFW_CURSOR_NORMAL`,
-meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor)
-is used and cursor motion is not limited.
-
-If you wish to implement mouse motion based camera controls or other input
-schemes that require unlimited mouse movement, set the cursor mode to
-`GLFW_CURSOR_DISABLED`.
-
-@code
-glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
-@endcode
-
-This will hide the cursor and lock it to the specified window.  GLFW will then
-take care of all the details of cursor re-centering and offset calculation and
-providing the application with a virtual cursor position.  This virtual position
-is provided normally via both the cursor position callback and through polling.
-
-@note You should not implement your own version of this functionality using
-other features of GLFW.  It is not supported and will not work as robustly as
-`GLFW_CURSOR_DISABLED`.
-
-If you only wish the cursor to become hidden when it is over a window but still
-want it to behave normally, set the cursor mode to `GLFW_CURSOR_HIDDEN`.
-
-@code
-glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
-@endcode
-
-This mode puts no limit on the motion of the cursor.
-
-To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL`
-cursor mode.
-
-@code
-glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
-@endcode
-
-
-@anchor GLFW_RAW_MOUSE_MOTION
-@subsection raw_mouse_motion Raw mouse motion
-
-When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can
-be enabled if available.
-
-Raw mouse motion is closer to the actual motion of the mouse across a surface.
-It is not affected by the scaling and acceleration applied to the motion of the
-desktop cursor.  That processing is suitable for a cursor while raw motion is
-better for controlling for example a 3D camera.  Because of this, raw mouse
-motion is only provided when the cursor is disabled.
-
-Call @ref glfwRawMouseMotionSupported to check if the current machine provides
-raw motion and set the `GLFW_RAW_MOUSE_MOTION` input mode to enable it.  It is
-disabled by default.
-
-@code
-if (glfwRawMouseMotionSupported())
-    glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
-@endcode
-
-If supported, raw mouse motion can be enabled or disabled per-window and at any
-time but it will only be provided when the cursor is disabled.
-
-
-@subsection cursor_object Cursor objects
-
-GLFW supports creating both custom and system theme cursor images, encapsulated
-as @ref GLFWcursor objects.  They are created with @ref glfwCreateCursor or @ref
-glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref
-glfwTerminate, if any remain.
-
-
-@subsubsection cursor_custom Custom cursor creation
-
-A custom cursor is created with @ref glfwCreateCursor, which returns a handle to
-the created cursor object.  For example, this creates a 16x16 white square
-cursor with the hot-spot in the upper-left corner:
-
-@code
-unsigned char pixels[16 * 16 * 4];
-memset(pixels, 0xff, sizeof(pixels));
-
-GLFWimage image;
-image.width = 16;
-image.height = 16;
-image.pixels = pixels;
-
-GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0);
-@endcode
-
-If cursor creation fails, `NULL` will be returned, so it is necessary to check
-the return value.
-
-The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits
-per channel with the red channel first.  The pixels are arranged canonically as
-sequential rows, starting from the top-left corner.
-
-
-@subsubsection cursor_standard Standard cursor creation
-
-A cursor with a [standard shape](@ref shapes) from the current system cursor
-theme can be can be created with @ref glfwCreateStandardCursor.
-
-@code
-GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
-@endcode
-
-These cursor objects behave in the exact same way as those created with @ref
-glfwCreateCursor except that the system cursor theme provides the actual image.
-
-
-@subsubsection cursor_destruction Cursor destruction
-
-When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor.
-
-@code
-glfwDestroyCursor(cursor);
-@endcode
-
-Cursor destruction always succeeds.  If the cursor is current for any window,
-that window will revert to the default cursor.  This does not affect the cursor
-mode.  All remaining cursors are destroyed when @ref glfwTerminate is called.
-
-
-@subsubsection cursor_set Cursor setting
-
-A cursor can be set as current for a window with @ref glfwSetCursor.
-
-@code
-glfwSetCursor(window, cursor);
-@endcode
-
-Once set, the cursor image will be used as long as the system cursor is over the
-content area of the window and the [cursor mode](@ref cursor_mode) is set
-to `GLFW_CURSOR_NORMAL`.
-
-A single cursor may be set for any number of windows.
-
-To revert to the default cursor, set the cursor of that window to `NULL`.
-
-@code
-glfwSetCursor(window, NULL);
-@endcode
-
-When a cursor is destroyed, any window that has it set will revert to the
-default cursor.  This does not affect the cursor mode.
-
-
-@subsection cursor_enter Cursor enter/leave events
-
-If you wish to be notified when the cursor enters or leaves the content area of
-a window, set a cursor enter/leave callback.
-
-@code
-glfwSetCursorEnterCallback(window, cursor_enter_callback);
-@endcode
-
-The callback function receives the new classification of the cursor.
-
-@code
-void cursor_enter_callback(GLFWwindow* window, int entered)
-{
-    if (entered)
-    {
-        // The cursor entered the content area of the window
-    }
-    else
-    {
-        // The cursor left the content area of the window
-    }
-}
-@endcode
-
-You can query whether the cursor is currently inside the content area of the
-window with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute.
-
-@code
-if (glfwGetWindowAttrib(window, GLFW_HOVERED))
-{
-    highlight_interface();
-}
-@endcode
-
-
-@subsection input_mouse_button Mouse button input
-
-If you wish to be notified when a mouse button is pressed or released, set
-a mouse button callback.
-
-@code
-glfwSetMouseButtonCallback(window, mouse_button_callback);
-@endcode
-
-The callback function receives the [mouse button](@ref buttons), button action
-and [modifier bits](@ref mods).
-
-@code
-void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
-{
-    if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
-        popup_menu();
-}
-@endcode
-
-The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
-
-Mouse button states for [named buttons](@ref buttons) are also saved in
-per-window state arrays that can be polled with @ref glfwGetMouseButton.
-
-@code
-int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
-if (state == GLFW_PRESS)
-{
-    upgrade_cow();
-}
-@endcode
-
-The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
-
-This function only returns cached mouse button event state.  It does not poll
-the system for the current state of the mouse button.
-
-@anchor GLFW_STICKY_MOUSE_BUTTONS
-Whenever you poll state, you risk missing the state change you are looking for.
-If a pressed mouse button is released again before you poll its state, you will have
-missed the button press.  The recommended solution for this is to use a
-mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS`
-input mode.
-
-@code
-glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, GLFW_TRUE);
-@endcode
-
-When sticky mouse buttons mode is enabled, the pollable state of a mouse button
-will remain `GLFW_PRESS` until the state of that button is polled with @ref
-glfwGetMouseButton.  Once it has been polled, if a mouse button release event
-had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
-otherwise it will remain `GLFW_PRESS`.
-
-The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
-[named button](@ref buttons).
-
-
-@subsection scrolling Scroll input
-
-If you wish to be notified when the user scrolls, whether with a mouse wheel or
-touchpad gesture, set a scroll callback.
-
-@code
-glfwSetScrollCallback(window, scroll_callback);
-@endcode
-
-The callback function receives two-dimensional scroll offsets.
-
-@code
-void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
-{
-}
-@endcode
-
-A normal mouse wheel, being vertical, provides offsets along the Y-axis.
-
-
-@section joystick Joystick input
-
-The joystick functions expose connected joysticks and controllers, with both
-referred to as joysticks.  It supports up to sixteen joysticks, ranging from
-`GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to and including `GLFW_JOYSTICK_16` or
-`GLFW_JOYSTICK_LAST`.  You can test whether a [joystick](@ref joysticks) is
-present with @ref glfwJoystickPresent.
-
-@code
-int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
-@endcode
-
-Each joystick has zero or more axes, zero or more buttons, zero or more hats,
-a human-readable name, a user pointer and an SDL compatible GUID.
-
-When GLFW is initialized, detected joysticks are added to the beginning of
-the array.  Once a joystick is detected, it keeps its assigned ID until it is
-disconnected or the library is terminated, so as joysticks are connected and
-disconnected, there may appear gaps in the IDs.
-
-Joystick axis, button and hat state is updated when polled and does not require
-a window to be created or events to be processed.  However, if you want joystick
-connection and disconnection events reliably delivered to the
-[joystick callback](@ref joystick_event) then you must
-[process events](@ref events).
-
-To see all the properties of all connected joysticks in real-time, run the
-`joysticks` test program.
-
-
-@subsection joystick_axis Joystick axis states
-
-The positions of all axes of a joystick are returned by @ref
-glfwGetJoystickAxes.  See the reference documentation for the lifetime of the
-returned array.
-
-@code
-int count;
-const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count);
-@endcode
-
-Each element in the returned array is a value between -1.0 and 1.0.
-
-
-@subsection joystick_button Joystick button states
-
-The states of all buttons of a joystick are returned by @ref
-glfwGetJoystickButtons.  See the reference documentation for the lifetime of the
-returned array.
-
-@code
-int count;
-const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count);
-@endcode
-
-Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`.
-
-For backward compatibility with earlier versions that did not have @ref
-glfwGetJoystickHats, the button array by default also includes all hats.  See
-the reference documentation for @ref glfwGetJoystickButtons for details.
-
-
-@subsection joystick_hat Joystick hat states
-
-The states of all hats are returned by @ref glfwGetJoystickHats.  See the
-reference documentation for the lifetime of the returned array.
-
-@code
-int count;
-const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count);
-@endcode
-
-Each element in the returned array is one of the following:
-
-Name                  | Value
-----                  | -----
-`GLFW_HAT_CENTERED`   | 0
-`GLFW_HAT_UP`         | 1
-`GLFW_HAT_RIGHT`      | 2
-`GLFW_HAT_DOWN`       | 4
-`GLFW_HAT_LEFT`       | 8
-`GLFW_HAT_RIGHT_UP`   | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP`
-`GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN`
-`GLFW_HAT_LEFT_UP`    | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP`
-`GLFW_HAT_LEFT_DOWN`  | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN`
-
-The diagonal directions are bitwise combinations of the primary (up, right, down
-and left) directions and you can test for these individually by ANDing it with
-the corresponding direction.
-
-@code
-if (hats[2] & GLFW_HAT_RIGHT)
-{
-    // State of hat 2 could be right-up, right or right-down
-}
-@endcode
-
-For backward compatibility with earlier versions that did not have @ref
-glfwGetJoystickHats, all hats are by default also included in the button array.
-See the reference documentation for @ref glfwGetJoystickButtons for details.
-
-
-@subsection joystick_name Joystick name
-
-The human-readable, UTF-8 encoded name of a joystick is returned by @ref
-glfwGetJoystickName.  See the reference documentation for the lifetime of the
-returned string.
-
-@code
-const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
-@endcode
-
-Joystick names are not guaranteed to be unique.  Two joysticks of the same model
-and make may have the same name.  Only the [joystick ID](@ref joysticks) is
-guaranteed to be unique, and only until that joystick is disconnected.
-
-
-@subsection joystick_userptr Joystick user pointer
-
-Each joystick has a user pointer that can be set with @ref
-glfwSetJoystickUserPointer and queried with @ref glfwGetJoystickUserPointer.
-This can be used for any purpose you need and will not be modified by GLFW.  The
-value will be kept until the joystick is disconnected or until the library is
-terminated.
-
-The initial value of the pointer is `NULL`.
-
-
-@subsection joystick_event Joystick configuration changes
-
-If you wish to be notified when a joystick is connected or disconnected, set
-a joystick callback.
-
-@code
-glfwSetJoystickCallback(joystick_callback);
-@endcode
-
-The callback function receives the ID of the joystick that has been connected
-and disconnected and the event that occurred.
-
-@code
-void joystick_callback(int jid, int event)
-{
-    if (event == GLFW_CONNECTED)
-    {
-        // The joystick was connected
-    }
-    else if (event == GLFW_DISCONNECTED)
-    {
-        // The joystick was disconnected
-    }
-}
-@endcode
-
-For joystick connection and disconnection events to be delivered on all
-platforms, you need to call one of the [event processing](@ref events)
-functions.  Joystick disconnection may also be detected and the callback
-called by joystick functions.  The function will then return whatever it
-returns for a disconnected joystick.
-
-Only @ref glfwGetJoystickName and @ref glfwGetJoystickUserPointer will return
-useful values for a disconnected joystick and only before the monitor callback
-returns.
-
-
-@subsection gamepad Gamepad input
-
-The joystick functions provide unlabeled axes, buttons and hats, with no
-indication of where they are located on the device.  Their order may also vary
-between platforms even with the same device.
-
-To solve this problem the SDL community crowdsourced the
-[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) project,
-a database of mappings from many different devices to an Xbox-like gamepad.
-
-GLFW supports this mapping format and contains a copy of the mappings
-available at the time of release.  See @ref gamepad_mapping for how to update
-this at runtime.  Mappings will be assigned to joysticks automatically any time
-a joystick is connected or the mappings are updated.
-
-You can check whether a joystick is both present and has a gamepad mapping with
-@ref glfwJoystickIsGamepad.
-
-@code
-if (glfwJoystickIsGamepad(GLFW_JOYSTICK_2))
-{
-    // Use as gamepad
-}
-@endcode
-
-If you are only interested in gamepad input you can use this function instead of
-@ref glfwJoystickPresent.
-
-You can query the human-readable name provided by the gamepad mapping with @ref
-glfwGetGamepadName.  This may or may not be the same as the
-[joystick name](@ref joystick_name).
-
-@code
-const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7);
-@endcode
-
-To retrieve the gamepad state of a joystick, call @ref glfwGetGamepadState.
-
-@code
-GLFWgamepadstate state;
-
-if (glfwGetGamepadState(GLFW_JOYSTICK_3, &state))
-{
-    if (state.buttons[GLFW_GAMEPAD_BUTTON_A])
-    {
-        input_jump();
-    }
-
-    input_speed(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER]);
-}
-@endcode
-
-The @ref GLFWgamepadstate struct has two arrays; one for button states and one
-for axis states.  The values for each button and axis are the same as for the
-@ref glfwGetJoystickButtons and @ref glfwGetJoystickAxes functions, i.e.
-`GLFW_PRESS` or `GLFW_RELEASE` for buttons and -1.0 to 1.0 inclusive for axes.
-
-The sizes of the arrays and the positions within each array are fixed.
-
-The [button indices](@ref gamepad_buttons) are `GLFW_GAMEPAD_BUTTON_A`,
-`GLFW_GAMEPAD_BUTTON_B`, `GLFW_GAMEPAD_BUTTON_X`, `GLFW_GAMEPAD_BUTTON_Y`,
-`GLFW_GAMEPAD_BUTTON_LEFT_BUMPER`, `GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER`,
-`GLFW_GAMEPAD_BUTTON_BACK`, `GLFW_GAMEPAD_BUTTON_START`,
-`GLFW_GAMEPAD_BUTTON_GUIDE`, `GLFW_GAMEPAD_BUTTON_LEFT_THUMB`,
-`GLFW_GAMEPAD_BUTTON_RIGHT_THUMB`, `GLFW_GAMEPAD_BUTTON_DPAD_UP`,
-`GLFW_GAMEPAD_BUTTON_DPAD_RIGHT`, `GLFW_GAMEPAD_BUTTON_DPAD_DOWN` and
-`GLFW_GAMEPAD_BUTTON_DPAD_LEFT`.
-
-For those who prefer, there are also the `GLFW_GAMEPAD_BUTTON_CROSS`,
-`GLFW_GAMEPAD_BUTTON_CIRCLE`, `GLFW_GAMEPAD_BUTTON_SQUARE` and
-`GLFW_GAMEPAD_BUTTON_TRIANGLE` aliases for the A, B, X and Y button indices.
-
-The [axis indices](@ref gamepad_axes) are `GLFW_GAMEPAD_AXIS_LEFT_X`,
-`GLFW_GAMEPAD_AXIS_LEFT_Y`, `GLFW_GAMEPAD_AXIS_RIGHT_X`,
-`GLFW_GAMEPAD_AXIS_RIGHT_Y`, `GLFW_GAMEPAD_AXIS_LEFT_TRIGGER` and
-`GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER`.
-
-The `GLFW_GAMEPAD_BUTTON_LAST` and `GLFW_GAMEPAD_AXIS_LAST` constants equal
-the largest available index for each array.
-
-
-@subsection gamepad_mapping Gamepad mappings
-
-GLFW contains a copy of the mappings available in
-[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) at the
-time of release.  Newer ones can be added at runtime with @ref
-glfwUpdateGamepadMappings.
-
-@code
-const char* mappings = load_file_contents("game/data/gamecontrollerdb.txt");
-
-glfwUpdateGamepadMappings(mappings);
-@endcode
-
-This function supports everything from single lines up to and including the
-unmodified contents of the whole `gamecontrollerdb.txt` file.
-
-If you are compiling GLFW from source with CMake you can update the built-in mappings by
-building the _update_mappings_ target.  This runs the `GenerateMappings.cmake` CMake
-script, which downloads `gamecontrollerdb.txt` and regenerates the `mappings.h` header
-file.
-
-Below is a description of the mapping format.  Please keep in mind that __this
-description is not authoritative__.  The format is defined by the SDL and
-SDL_GameControllerDB projects and their documentation and code takes precedence.
-
-Each mapping is a single line of comma-separated values describing the GUID,
-name and layout of the gamepad.  Lines that do not begin with a hexadecimal
-digit are ignored.
-
-The first value is always the gamepad GUID, a 32 character long hexadecimal
-string that typically identifies its make, model, revision and the type of
-connection to the computer.  When this information is not available, the GUID is
-generated using the gamepad name.  GLFW uses the SDL 2.0.5+ GUID format but can
-convert from the older formats.
-
-The second value is always the human-readable name of the gamepad.
-
-All subsequent values are in the form `<field>:<value>` and describe the layout
-of the mapping.  These fields may not all be present and may occur in any order.
-
-The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`,
-`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
-`rightstick`.
-
-The axis fields are `leftx`, `lefty`, `rightx`, `righty`, `lefttrigger` and
-`righttrigger`.
-
-The value of an axis or button field can be a joystick button, a joystick axis,
-a hat bitmask or empty.  Joystick buttons are specified as `bN`, for example
-`b2` for the third button.  Joystick axes are specified as `aN`, for example
-`a7` for the eighth button.  Joystick hat bit masks are specified as `hN.N`, for
-example `h0.8` for left on the first hat.  More than one bit may be set in the
-mask.
-
-Before an axis there may be a `+` or `-` range modifier, for example `+a3` for
-the positive half of the fourth axis.  This restricts input to only the positive
-or negative halves of the joystick axis.  After an axis or half-axis there may
-be the `~` inversion modifier, for example `a2~` or `-a7~`.  This negates the
-values of the gamepad axis.
-
-The hat bit mask match the [hat states](@ref hat_state) in the joystick
-functions.
-
-There is also the special `platform` field that specifies which platform the
-mapping is valid for.  Possible values are `Windows`, `Mac OS X` and `Linux`.
-
-Below is an example of what a gamepad mapping might look like.  It is the
-one built into GLFW for Xbox controllers accessed via the XInput API on Windows.
-This example has been broken into several lines to fit on the page, but real
-gamepad mappings must be a single line.
-
-@code{.unparsed}
-78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,
-b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,
-rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,
-righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
-@endcode
-
-@note GLFW does not yet support the output range and modifiers `+` and `-` that
-were recently added to SDL.  The input modifiers `+`, `-` and `~` are supported
-and described above.
-
-
-@section time Time input
-
-GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime.
-
-@code
-double seconds = glfwGetTime();
-@endcode
-
-It returns the number of seconds since the library was initialized with @ref
-glfwInit.  The platform-specific time sources used typically have micro- or
-nanosecond resolution.
-
-You can modify the base time with @ref glfwSetTime.
-
-@code
-glfwSetTime(4.0);
-@endcode
-
-This sets the time to the specified time, in seconds, and it continues to count
-from there.
-
-You can also access the raw timer used to implement the functions above,
-with @ref glfwGetTimerValue.
-
-@code
-uint64_t value = glfwGetTimerValue();
-@endcode
-
-This value is in 1&nbsp;/&nbsp;frequency seconds.  The frequency of the raw
-timer varies depending on the operating system and hardware.  You can query the
-frequency, in Hz, with @ref glfwGetTimerFrequency.
-
-@code
-uint64_t frequency = glfwGetTimerFrequency();
-@endcode
-
-
-@section clipboard Clipboard input and output
-
-If the system clipboard contains a UTF-8 encoded string or if it can be
-converted to one, you can retrieve it with @ref glfwGetClipboardString.  See the
-reference documentation for the lifetime of the returned string.
-
-@code
-const char* text = glfwGetClipboardString(NULL);
-if (text)
-{
-    insert_text(text);
-}
-@endcode
-
-If the clipboard is empty or if its contents could not be converted, `NULL` is
-returned.
-
-The contents of the system clipboard can be set to a UTF-8 encoded string with
-@ref glfwSetClipboardString.
-
-@code
-glfwSetClipboardString(NULL, "A string with words in it");
-@endcode
-
-
-@section path_drop Path drop input
-
-If you wish to receive the paths of files and/or directories dropped on
-a window, set a file drop callback.
-
-@code
-glfwSetDropCallback(window, drop_callback);
-@endcode
-
-The callback function receives an array of paths encoded as UTF-8.
-
-@code
-void drop_callback(GLFWwindow* window, int count, const char** paths)
-{
-    int i;
-    for (i = 0;  i < count;  i++)
-        handle_dropped_file(paths[i]);
-}
-@endcode
-
-The path array and its strings are only valid until the file drop callback
-returns, as they may have been generated specifically for that event.  You need
-to make a deep copy of the array if you want to keep the paths.
-
-*/

+ 0 - 115
samples/third_party/glfw/docs/internal.dox

@@ -1,115 +0,0 @@
-/*!
-
-@page internals_guide Internal structure
-
-@tableofcontents
-
-There are several interfaces inside GLFW.  Each interface has its own area of
-responsibility and its own naming conventions.
-
-
-@section internals_public Public interface
-
-The most well-known is the public interface, described in the glfw3.h header
-file.  This is implemented in source files shared by all platforms and these
-files contain no platform-specific code.  This code usually ends up calling the
-platform and internal interfaces to do the actual work.
-
-The public interface uses the OpenGL naming conventions except with GLFW and
-glfw instead of GL and gl.  For struct members, where OpenGL sets no precedent,
-it use headless camel case.
-
-Examples: `glfwCreateWindow`, `GLFWwindow`, `GLFW_RED_BITS`
-
-
-@section internals_native Native interface
-
-The [native interface](@ref native) is a small set of publicly available
-but platform-specific functions, described in the glfw3native.h header file and
-used to gain access to the underlying window, context and (on some platforms)
-display handles used by the platform interface.
-
-The function names of the native interface are similar to those of the public
-interface, but embeds the name of the interface that the returned handle is
-from.
-
-Examples: `glfwGetX11Window`, `glfwGetWGLContext`
-
-
-@section internals_internal Internal interface
-
-The internal interface consists of utility functions used by all other
-interfaces.  It is shared code implemented in the same shared source files as
-the public and event interfaces.  The internal interface is described in the
-internal.h header file.
-
-The internal interface is in charge of GLFW's global data, which it stores in
-a `_GLFWlibrary` struct named `_glfw`.
-
-The internal interface uses the same style as the public interface, except all
-global names have a leading underscore.
-
-Examples: `_glfwIsValidContextConfig`, `_GLFWwindow`, `_glfw.monitorCount`
-
-
-@section internals_platform Platform interface
-
-The platform interface implements all platform-specific operations as a service
-to the public interface.  This includes event processing.  The platform
-interface is never directly called by application code and never directly calls
-application-provided callbacks.  It is also prohibited from modifying the
-platform-independent part of the internal structs.  Instead, it calls the event
-interface when events interesting to GLFW are received.
-
-The platform interface mirrors those parts of the public interface that needs to
-perform platform-specific operations on some or all platforms.  The are also
-named the same except that the glfw function prefix is replaced by
-_glfwPlatform.
-
-Examples: `_glfwPlatformCreateWindow`
-
-The platform interface also defines structs that contain platform-specific
-global and per-object state.  Their names mirror those of the internal
-interface, except that an interface-specific suffix is added.
-
-Examples: `_GLFWwindowX11`, `_GLFWcontextWGL`
-
-These structs are incorporated as members into the internal interface structs
-using special macros that name them after the specific interface used.  This
-prevents shared code from accidentally using these members.
-
-Examples: `window->win32.handle`, `_glfw.x11.display`
-
-
-@section internals_event Event interface
-
-The event interface is implemented in the same shared source files as the public
-interface and is responsible for delivering the events it receives to the
-application, either via callbacks, via window state changes or both.
-
-The function names of the event interface use a `_glfwInput` prefix and the
-ObjectEvent pattern.
-
-Examples: `_glfwInputWindowFocus`, `_glfwInputCursorPos`
-
-
-@section internals_static Static functions
-
-Static functions may be used by any interface and have no prefixes or suffixes.
-These use headless camel case.
-
-Examples: `isValidElementForJoystick`
-
-
-@section internals_config Configuration macros
-
-GLFW uses a number of configuration macros to select at compile time which
-interfaces and code paths to use.  They are defined in the glfw_config.h header file,
-which is generated from the `glfw_config.h.in` file by CMake.
-
-Configuration macros the same style as tokens in the public interface, except
-with a leading underscore.
-
-Examples: `_GLFW_WIN32`, `_GLFW_BUILD_DLL`
-
-*/

+ 0 - 454
samples/third_party/glfw/docs/intro.dox

@@ -1,454 +0,0 @@
-/*!
-
-@page intro_guide Introduction to the API
-
-@tableofcontents
-
-This guide introduces the basic concepts of GLFW and describes initialization,
-error handling and API guarantees and limitations.  For a broad but shallow
-tutorial, see @ref quick_guide instead.  For details on a specific function in
-this category, see the @ref init.
-
-There are also guides for the other areas of GLFW.
-
- - @ref window_guide
- - @ref context_guide
- - @ref vulkan_guide
- - @ref monitor_guide
- - @ref input_guide
-
-
-@section intro_init Initialization and termination
-
-Before most GLFW functions may be called, the library must be initialized.
-This initialization checks what features are available on the machine,
-enumerates monitors and joysticks, initializes the timer and performs any
-required platform-specific initialization.
-
-Only the following functions may be called before the library has been
-successfully initialized, and only from the main thread.
-
- - @ref glfwGetVersion
- - @ref glfwGetVersionString
- - @ref glfwGetError
- - @ref glfwSetErrorCallback
- - @ref glfwInitHint
- - @ref glfwInit
- - @ref glfwTerminate
-
-Calling any other function before successful initialization will cause a @ref
-GLFW_NOT_INITIALIZED error.
-
-
-@subsection intro_init_init Initializing GLFW
-
-The library is initialized with @ref glfwInit, which returns `GLFW_FALSE` if an
-error occurred.
-
-@code
-if (!glfwInit())
-{
-    // Handle initialization failure
-}
-@endcode
-
-If any part of initialization fails, any parts that succeeded are terminated as
-if @ref glfwTerminate had been called.  The library only needs to be initialized
-once and additional calls to an already initialized library will return
-`GLFW_TRUE` immediately.
-
-Once the library has been successfully initialized, it should be terminated
-before the application exits.  Modern systems are very good at freeing resources
-allocated by programs that exit, but GLFW sometimes has to change global system
-settings and these might not be restored without termination.
-
-
-@subsection init_hints Initialization hints
-
-Initialization hints are set before @ref glfwInit and affect how the library
-behaves until termination.  Hints are set with @ref glfwInitHint.
-
-@code
-glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE);
-@endcode
-
-The values you set hints to are never reset by GLFW, but they only take effect
-during initialization.  Once GLFW has been initialized, any values you set will
-be ignored until the library is terminated and initialized again.
-
-Some hints are platform specific.  These may be set on any platform but they
-will only affect their specific platform.  Other platforms will ignore them.
-Setting these hints requires no platform specific headers or functions.
-
-
-@subsubsection init_hints_shared Shared init hints
-
-@anchor GLFW_JOYSTICK_HAT_BUTTONS
-__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
-buttons, for compatibility with earlier versions of GLFW that did not have @ref
-glfwGetJoystickHats.  Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
-
-
-@subsubsection init_hints_osx macOS specific init hints
-
-@anchor GLFW_COCOA_CHDIR_RESOURCES_hint
-__GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to
-the application to the `Contents/Resources` subdirectory of the application's
-bundle, if present.  Set this with @ref glfwInitHint.
-
-@anchor GLFW_COCOA_MENUBAR_hint
-__GLFW_COCOA_MENUBAR__ specifies whether to create a basic menu bar, either from
-a nib or manually, when the first window is created, which is when AppKit is
-initialized.  Set this with @ref glfwInitHint.
-
-
-@subsubsection init_hints_values Supported and default values
-
-Initialization hint             | Default value | Supported values
-------------------------------- | ------------- | ----------------
-@ref GLFW_JOYSTICK_HAT_BUTTONS  | `GLFW_TRUE`   | `GLFW_TRUE` or `GLFW_FALSE`
-@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE`   | `GLFW_TRUE` or `GLFW_FALSE`
-@ref GLFW_COCOA_MENUBAR         | `GLFW_TRUE`   | `GLFW_TRUE` or `GLFW_FALSE`
-
-
-@subsection intro_init_terminate Terminating GLFW
-
-Before your application exits, you should terminate the GLFW library if it has
-been initialized.  This is done with @ref glfwTerminate.
-
-@code
-glfwTerminate();
-@endcode
-
-This will destroy any remaining window, monitor and cursor objects, restore any
-modified gamma ramps, re-enable the screensaver if it had been disabled and free
-any other resources allocated by GLFW.
-
-Once the library is terminated, it is as if it had never been initialized and
-you will need to initialize it again before being able to use GLFW.  If the
-library was not initialized or had already been terminated, it return
-immediately.
-
-
-@section error_handling Error handling
-
-Some GLFW functions have return values that indicate an error, but this is often
-not very helpful when trying to figure out what happened or why it occurred.
-Other functions have no return value reserved for errors, so error notification
-needs a separate channel.  Finally, far from all GLFW functions have return
-values.
-
-The last [error code](@ref errors) for the calling thread can be queried at any
-time with @ref glfwGetError.
-
-@code
-int code = glfwGetError(NULL);
-
-if (code != GLFW_NO_ERROR)
-    handle_error(code);
-@endcode
-
-If no error has occurred since the last call, @ref GLFW_NO_ERROR (zero) is
-returned.  The error is cleared before the function returns.
-
-The error code indicates the general category of the error.  Some error codes,
-such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like
-@ref GLFW_PLATFORM_ERROR are used for many different errors.
-
-GLFW often has more information about an error than its general category.  You
-can retrieve a UTF-8 encoded human-readable description along with the error
-code.  If no error has occurred since the last call, the description is set to
-`NULL`.
-
-@code
-const char* description;
-int code = glfwGetError(&description);
-
-if (description)
-    display_error_message(code, description);
-@endcode
-
-The retrieved description string is only valid until the next error occurs.
-This means you must make a copy of it if you want to keep it.
-
-You can also set an error callback, which will be called each time an error
-occurs.  It is set with @ref glfwSetErrorCallback.
-
-@code
-glfwSetErrorCallback(error_callback);
-@endcode
-
-The error callback receives the same error code and human-readable description
-returned by @ref glfwGetError.
-
-@code
-void error_callback(int code, const char* description)
-{
-    display_error_message(code, description);
-}
-@endcode
-
-The error callback is called after the error is stored, so calling @ref
-glfwGetError from within the error callback returns the same values as the
-callback argument.
-
-The description string passed to the callback is only valid until the error
-callback returns.  This means you must make a copy of it if you want to keep it.
-
-__Reported errors are never fatal.__  As long as GLFW was successfully
-initialized, it will remain initialized and in a safe state until terminated
-regardless of how many errors occur.  If an error occurs during initialization
-that causes @ref glfwInit to fail, any part of the library that was initialized
-will be safely terminated.
-
-Do not rely on a currently invalid call to generate a specific error, as in the
-future that same call may generate a different error or become valid.
-
-
-@section coordinate_systems Coordinate systems
-
-GLFW has two primary coordinate systems: the _virtual screen_ and the window
-_content area_ or _content area_.  Both use the same unit: _virtual screen
-coordinates_, or just _screen coordinates_, which don't necessarily correspond
-to pixels.
-
-<img src="spaces.svg" width="90%" />
-
-Both the virtual screen and the content area coordinate systems have the X-axis
-pointing to the right and the Y-axis pointing down.
-
-Window and monitor positions are specified as the position of the upper-left
-corners of their content areas relative to the virtual screen, while cursor
-positions are specified relative to a window's content area.
-
-Because the origin of the window's content area coordinate system is also the
-point from which the window position is specified, you can translate content
-area coordinates to the virtual screen by adding the window position.  The
-window frame, when present, extends out from the content area but does not
-affect the window position.
-
-Almost all positions and sizes in GLFW are measured in screen coordinates
-relative to one of the two origins above.  This includes cursor positions,
-window positions and sizes, window frame sizes, monitor positions and video mode
-resolutions.
-
-Two exceptions are the [monitor physical size](@ref monitor_size), which is
-measured in millimetres, and [framebuffer size](@ref window_fbsize), which is
-measured in pixels.
-
-Pixels and screen coordinates may map 1:1 on your machine, but they won't on
-every other machine, for example on a Mac with a Retina display.  The ratio
-between screen coordinates and pixels may also change at run-time depending on
-which monitor the window is currently considered to be on.
-
-
-@section guarantees_limitations Guarantees and limitations
-
-This section describes the conditions under which GLFW can be expected to
-function, barring bugs in the operating system or drivers.  Use of GLFW outside
-of these limits may work on some platforms, or on some machines, or some of the
-time, or on some versions of GLFW, but it may break at any time and this will
-not be considered a bug.
-
-
-@subsection lifetime Pointer lifetimes
-
-GLFW will never free any pointer you provide to it and you must never free any
-pointer it provides to you.
-
-Many GLFW functions return pointers to dynamically allocated structures, strings
-or arrays, and some callbacks are provided with strings or arrays.  These are
-always managed by GLFW and should never be freed by the application.  The
-lifetime of these pointers is documented for each GLFW function and callback.
-If you need to keep this data, you must copy it before its lifetime expires.
-
-Many GLFW functions accept pointers to structures or strings allocated by the
-application.  These are never freed by GLFW and are always the responsibility of
-the application.  If GLFW needs to keep the data in these structures or strings,
-it is copied before the function returns.
-
-Pointer lifetimes are guaranteed not to be shortened in future minor or patch
-releases.
-
-
-@subsection reentrancy Reentrancy
-
-GLFW event processing and object destruction are not reentrant.  This means that
-the following functions must not be called from any callback function:
-
- - @ref glfwDestroyWindow
- - @ref glfwDestroyCursor
- - @ref glfwPollEvents
- - @ref glfwWaitEvents
- - @ref glfwWaitEventsTimeout
- - @ref glfwTerminate
-
-These functions may be made reentrant in future minor or patch releases, but
-functions not on this list will not be made non-reentrant.
-
-
-@subsection thread_safety Thread safety
-
-Most GLFW functions must only be called from the main thread (the thread that
-calls main), but some may be called from any thread once the library has been
-initialized.  Before initialization the whole library is thread-unsafe.
-
-The reference documentation for every GLFW function states whether it is limited
-to the main thread.
-
-Initialization, termination, event processing and the creation and
-destruction of windows, cursors and OpenGL and OpenGL ES contexts are all
-restricted to the main thread due to limitations of one or several platforms.
-
-Because event processing must be performed on the main thread, all callbacks
-except for the error callback will only be called on that thread.  The error
-callback may be called on any thread, as any GLFW function may generate errors.
-
-The error code and description may be queried from any thread.
-
- - @ref glfwGetError
-
-Empty events may be posted from any thread.
-
- - @ref glfwPostEmptyEvent
-
-The window user pointer and close flag may be read and written from any thread,
-but this is not synchronized by GLFW.
-
- - @ref glfwGetWindowUserPointer
- - @ref glfwSetWindowUserPointer
- - @ref glfwWindowShouldClose
- - @ref glfwSetWindowShouldClose
-
-These functions for working with OpenGL and OpenGL ES contexts may be called
-from any thread, but the window object is not synchronized by GLFW.
-
- - @ref glfwMakeContextCurrent
- - @ref glfwGetCurrentContext
- - @ref glfwSwapBuffers
- - @ref glfwSwapInterval
- - @ref glfwExtensionSupported
- - @ref glfwGetProcAddress
-
-The raw timer functions may be called from any thread.
-
- - @ref glfwGetTimerFrequency
- - @ref glfwGetTimerValue
-
-The regular timer may be used from any thread, but reading and writing the timer
-offset is not synchronized by GLFW.
-
- - @ref glfwGetTime
- - @ref glfwSetTime
-
-Library version information may be queried from any thread.
-
- - @ref glfwGetVersion
- - @ref glfwGetVersionString
-
-All Vulkan related functions may be called from any thread.
-
- - @ref glfwVulkanSupported
- - @ref glfwGetRequiredInstanceExtensions
- - @ref glfwGetInstanceProcAddress
- - @ref glfwGetPhysicalDevicePresentationSupport
- - @ref glfwCreateWindowSurface
-
-GLFW uses synchronization objects internally only to manage the per-thread
-context and error states.  Additional synchronization is left to the
-application.
-
-Functions that may currently be called from any thread will always remain so,
-but functions that are currently limited to the main thread may be updated to
-allow calls from any thread in future releases.
-
-
-@subsection compatibility Version compatibility
-
-GLFW uses [Semantic Versioning](https://semver.org/).  This guarantees source
-and binary backward compatibility with earlier minor versions of the API.  This
-means that you can drop in a newer version of the library and existing programs
-will continue to compile and existing binaries will continue to run.
-
-Once a function or constant has been added, the signature of that function or
-value of that constant will remain unchanged until the next major version of
-GLFW.  No compatibility of any kind is guaranteed between major versions.
-
-Undocumented behavior, i.e. behavior that is not described in the documentation,
-may change at any time until it is documented.
-
-If the reference documentation and the implementation differ, the reference
-documentation will almost always take precedence and the implementation will be
-fixed in the next release.  The reference documentation will also take
-precedence over anything stated in a guide.
-
-
-@subsection event_order Event order
-
-The order of arrival of related events is not guaranteed to be consistent
-across platforms.  The exception is synthetic key and mouse button release
-events, which are always delivered after the window defocus event.
-
-
-@section intro_version Version management
-
-GLFW provides mechanisms for identifying what version of GLFW your application
-was compiled against as well as what version it is currently running against.
-If you are loading GLFW dynamically (not just linking dynamically), you can use
-this to verify that the library binary is compatible with your application.
-
-
-@subsection intro_version_compile Compile-time version
-
-The compile-time version of GLFW is provided by the GLFW header with the
-`GLFW_VERSION_MAJOR`, `GLFW_VERSION_MINOR` and `GLFW_VERSION_REVISION` macros.
-
-@code
-printf("Compiled against GLFW %i.%i.%i\n",
-       GLFW_VERSION_MAJOR,
-       GLFW_VERSION_MINOR,
-       GLFW_VERSION_REVISION);
-@endcode
-
-
-@subsection intro_version_runtime Run-time version
-
-The run-time version can be retrieved with @ref glfwGetVersion, a function that
-may be called regardless of whether GLFW is initialized.
-
-@code
-int major, minor, revision;
-glfwGetVersion(&major, &minor, &revision);
-
-printf("Running against GLFW %i.%i.%i\n", major, minor, revision);
-@endcode
-
-
-@subsection intro_version_string Version string
-
-GLFW 3 also provides a compile-time generated version string that describes the
-version, platform, compiler and any platform-specific compile-time options.
-This is primarily intended for submitting bug reports, to allow developers to
-see which code paths are enabled in a binary.
-
-The version string is returned by @ref glfwGetVersionString, a function that may
-be called regardless of whether GLFW is initialized.
-
-__Do not use the version string__ to parse the GLFW library version.  The @ref
-glfwGetVersion function already provides the version of the running library
-binary.
-
-The format of the string is as follows:
- - The version of GLFW
- - The name of the window system API
- - The name of the context creation API
- - Any additional options or APIs
-
-For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL
-back ends, the version string may look something like this:
-
-@code
-3.0.0 Win32 WGL MinGW
-@endcode
-
-*/

+ 0 - 46
samples/third_party/glfw/docs/main.dox

@@ -1,46 +0,0 @@
-/*!
-
-@mainpage notitle
-
-@section main_intro Introduction
-
-GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
-Vulkan application development.  It provides a simple, platform-independent API
-for creating windows, contexts and surfaces, reading input, handling events, etc.
-
-@ref news_33 list new features, caveats and deprecations.
-
-@ref quick_guide is a guide for users new to GLFW.  It takes you through how to
-write a small but complete program.
-
-There are guides for each section of the API:
-
- - @ref intro_guide – initialization, error handling and high-level design
- - @ref window_guide – creating and working with windows and framebuffers
- - @ref context_guide – working with OpenGL and OpenGL ES contexts
- - @ref vulkan_guide - working with Vulkan objects and extensions
- - @ref monitor_guide – enumerating and working with monitors and video modes
- - @ref input_guide – receiving events, polling and processing input
-
-Once you have written a program, see @ref compile_guide and @ref build_guide.
-
-The [reference documentation](modules.html) provides more detailed information
-about specific functions.
-
-@ref moving_guide explains what has changed and how to update existing code to
-use the new API.
-
-There is a section on @ref guarantees_limitations for pointer lifetimes,
-reentrancy, thread safety, event order and backward and forward compatibility.
-
-The [FAQ](https://www.glfw.org/faq.html) answers many common questions about the
-design, implementation and use of GLFW.
-
-Finally, @ref compat_guide explains what APIs, standards and protocols GLFW uses
-and what happens when they are not present on a given machine.
-
-This documentation was generated with Doxygen.  The sources for it are available
-in both the [source distribution](https://www.glfw.org/download.html) and
-[GitHub repository](https://github.com/glfw/glfw).
-
-*/

+ 0 - 268
samples/third_party/glfw/docs/monitor.dox

@@ -1,268 +0,0 @@
-/*!
-
-@page monitor_guide Monitor guide
-
-@tableofcontents
-
-This guide introduces the monitor related functions of GLFW.  For details on
-a specific function in this category, see the @ref monitor.  There are also
-guides for the other areas of GLFW.
-
- - @ref intro_guide
- - @ref window_guide
- - @ref context_guide
- - @ref vulkan_guide
- - @ref input_guide
-
-
-@section monitor_object Monitor objects
-
-A monitor object represents a currently connected monitor and is represented as
-a pointer to the [opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type
-@ref GLFWmonitor.  Monitor objects cannot be created or destroyed by the
-application and retain their addresses until the monitors they represent are
-disconnected or until the library is [terminated](@ref intro_init_terminate).
-
-Each monitor has a current video mode, a list of supported video modes,
-a virtual position, a human-readable name, an estimated physical size and
-a gamma ramp.  One of the monitors is the primary monitor.
-
-The virtual position of a monitor is in
-[screen coordinates](@ref coordinate_systems) and, together with the current
-video mode, describes the viewports that the connected monitors provide into the
-virtual desktop that spans them.
-
-To see how GLFW views your monitor setup and its available video modes, run the
-`monitors` test program.
-
-
-@subsection monitor_monitors Retrieving monitors
-
-The primary monitor is returned by @ref glfwGetPrimaryMonitor.  It is the user's
-preferred monitor and is usually the one with global UI elements like task bar
-or menu bar.
-
-@code
-GLFWmonitor* primary = glfwGetPrimaryMonitor();
-@endcode
-
-You can retrieve all currently connected monitors with @ref glfwGetMonitors.
-See the reference documentation for the lifetime of the returned array.
-
-@code
-int count;
-GLFWmonitor** monitors = glfwGetMonitors(&count);
-@endcode
-
-The primary monitor is always the first monitor in the returned array, but other
-monitors may be moved to a different index when a monitor is connected or
-disconnected.
-
-
-@subsection monitor_event Monitor configuration changes
-
-If you wish to be notified when a monitor is connected or disconnected, set
-a monitor callback.
-
-@code
-glfwSetMonitorCallback(monitor_callback);
-@endcode
-
-The callback function receives the handle for the monitor that has been
-connected or disconnected and the event that occurred.
-
-@code
-void monitor_callback(GLFWmonitor* monitor, int event)
-{
-    if (event == GLFW_CONNECTED)
-    {
-        // The monitor was connected
-    }
-    else if (event == GLFW_DISCONNECTED)
-    {
-        // The monitor was disconnected
-    }
-}
-@endcode
-
-If a monitor is disconnected, all windows that are full screen on it will be
-switched to windowed mode before the callback is called.  Only @ref
-glfwGetMonitorName and @ref glfwGetMonitorUserPointer will return useful values
-for a disconnected monitor and only before the monitor callback returns.
-
-
-@section monitor_properties Monitor properties
-
-Each monitor has a current video mode, a list of supported video modes,
-a virtual position, a content scale, a human-readable name, a user pointer, an
-estimated physical size and a gamma ramp.
-
-
-@subsection monitor_modes Video modes
-
-GLFW generally does a good job selecting a suitable video mode when you create
-a full screen window, change its video mode or make a windowed one full
-screen, but it is sometimes useful to know exactly which video modes are
-supported.
-
-Video modes are represented as @ref GLFWvidmode structures.  You can get an
-array of the video modes supported by a monitor with @ref glfwGetVideoModes.
-See the reference documentation for the lifetime of the returned array.
-
-@code
-int count;
-GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
-@endcode
-
-To get the current video mode of a monitor call @ref glfwGetVideoMode.  See the
-reference documentation for the lifetime of the returned pointer.
-
-@code
-const GLFWvidmode* mode = glfwGetVideoMode(monitor);
-@endcode
-
-The resolution of a video mode is specified in
-[screen coordinates](@ref coordinate_systems), not pixels.
-
-
-@subsection monitor_size Physical size
-
-The physical size of a monitor in millimetres, or an estimation of it, can be
-retrieved with @ref glfwGetMonitorPhysicalSize.  This has no relation to its
-current _resolution_, i.e. the width and height of its current
-[video mode](@ref monitor_modes).
-
-@code
-int width_mm, height_mm;
-glfwGetMonitorPhysicalSize(monitor, &width_mm, &height_mm);
-@endcode
-
-While this can be used to calculate the raw DPI of a monitor, this is often not
-useful.  Instead use the [monitor content scale](@ref monitor_scale) and
-[window content scale](@ref window_scale) to scale your content.
-
-
-@subsection monitor_scale Content scale
-
-The content scale for a monitor can be retrieved with @ref
-glfwGetMonitorContentScale.
-
-@code
-float xscale, yscale;
-glfwGetMonitorContentScale(monitor, &xscale, &yscale);
-@endcode
-
-The content scale is the ratio between the current DPI and the platform's
-default DPI.  This is especially important for text and any UI elements.  If the
-pixel dimensions of your UI scaled by this look appropriate on your machine then
-it should appear at a reasonable size on other machines regardless of their DPI
-and scaling settings.  This relies on the system DPI and scaling settings being
-somewhat correct.
-
-The content scale may depend on both the monitor resolution and pixel density
-and on user settings.  It may be very different from the raw DPI calculated from
-the physical size and current resolution.
-
-
-@subsection monitor_pos Virtual position
-
-The position of the monitor on the virtual desktop, in
-[screen coordinates](@ref coordinate_systems), can be retrieved with @ref
-glfwGetMonitorPos.
-
-@code
-int xpos, ypos;
-glfwGetMonitorPos(monitor, &xpos, &ypos);
-@endcode
-
-
-@subsection monitor_workarea Work area
-
-The area of a monitor not occupied by global task bars or menu bars is the work
-area.  This is specified in [screen coordinates](@ref coordinate_systems) and
-can be retrieved with @ref glfwGetMonitorWorkarea.
-
-@code
-int xpos, ypos, width, height;
-glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height);
-@endcode
-
-
-@subsection monitor_name Human-readable name
-
-The human-readable, UTF-8 encoded name of a monitor is returned by @ref
-glfwGetMonitorName.  See the reference documentation for the lifetime of the
-returned string.
-
-@code
-const char* name = glfwGetMonitorName(monitor);
-@endcode
-
-Monitor names are not guaranteed to be unique.  Two monitors of the same model
-and make may have the same name.  Only the monitor handle is guaranteed to be
-unique, and only until that monitor is disconnected.
-
-
-@subsection monitor_userptr User pointer
-
-Each monitor has a user pointer that can be set with @ref
-glfwSetMonitorUserPointer and queried with @ref glfwGetMonitorUserPointer.  This
-can be used for any purpose you need and will not be modified by GLFW.  The
-value will be kept until the monitor is disconnected or until the library is
-terminated.
-
-The initial value of the pointer is `NULL`.
-
-
-@subsection monitor_gamma Gamma ramp
-
-The gamma ramp of a monitor can be set with @ref glfwSetGammaRamp, which accepts
-a monitor handle and a pointer to a @ref GLFWgammaramp structure.
-
-@code
-GLFWgammaramp ramp;
-unsigned short red[256], green[256], blue[256];
-
-ramp.size = 256;
-ramp.red = red;
-ramp.green = green;
-ramp.blue = blue;
-
-for (i = 0;  i < ramp.size;  i++)
-{
-    // Fill out gamma ramp arrays as desired
-}
-
-glfwSetGammaRamp(monitor, &ramp);
-@endcode
-
-The gamma ramp data is copied before the function returns, so there is no need
-to keep it around once the ramp has been set.
-
-It is recommended that your gamma ramp have the same size as the current gamma
-ramp for that monitor.
-
-The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp.  See
-the reference documentation for the lifetime of the returned structure.
-
-@code
-const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor);
-@endcode
-
-If you wish to set a regular gamma ramp, you can have GLFW calculate it for you
-from the desired exponent with @ref glfwSetGamma, which in turn calls @ref
-glfwSetGammaRamp with the resulting ramp.
-
-@code
-glfwSetGamma(monitor, 1.0);
-@endcode
-
-To experiment with gamma correction via the @ref glfwSetGamma function, run the
-`gamma` test program.
-
-@note The software controlled gamma ramp is applied _in addition_ to the
-hardware gamma correction, which today is usually an approximation of sRGB
-gamma.  This means that setting a perfectly linear ramp, or gamma 1.0, will
-produce the default (usually sRGB-like) behavior.
-
-*/

+ 0 - 513
samples/third_party/glfw/docs/moving.dox

@@ -1,513 +0,0 @@
-/*!
-
-@page moving_guide Moving from GLFW 2 to 3
-
-@tableofcontents
-
-This is a transition guide for moving from GLFW 2 to 3.  It describes what has
-changed or been removed, but does _not_ include
-[new features](@ref news) unless they are required when moving an existing code
-base onto the new API.  For example, the new multi-monitor functions are
-required to create full screen windows with GLFW 3.
-
-
-@section moving_removed Changed and removed features
-
-@subsection moving_renamed_files Renamed library and header file
-
-The GLFW 3 header is named @ref glfw3.h and moved to the `GLFW` directory, to
-avoid collisions with the headers of other major versions.  Similarly, the GLFW
-3 library is named `glfw3,` except when it's installed as a shared library on
-Unix-like systems, where it uses the
-[soname](https://en.wikipedia.org/wiki/soname) `libglfw.so.3`.
-
-@par Old syntax
-@code
-#include <GL/glfw.h>
-@endcode
-
-@par New syntax
-@code
-#include <GLFW/glfw3.h>
-@endcode
-
-
-@subsection moving_threads Removal of threading functions
-
-The threading functions have been removed, including the per-thread sleep
-function.  They were fairly primitive, under-used, poorly integrated and took
-time away from the focus of GLFW (i.e.  context, input and window).  There are
-better threading libraries available and native threading support is available
-in both [C++11](https://en.cppreference.com/w/cpp/thread) and
-[C11](https://en.cppreference.com/w/c/thread), both of which are gaining
-traction.
-
-If you wish to use the C++11 or C11 facilities but your compiler doesn't yet
-support them, see the
-[TinyThread++](https://gitorious.org/tinythread/tinythreadpp) and
-[TinyCThread](https://github.com/tinycthread/tinycthread) projects created by
-the original author of GLFW.  These libraries implement a usable subset of the
-threading APIs in C++11 and C11, and in fact some GLFW 3 test programs use
-TinyCThread.
-
-However, GLFW 3 has better support for _use from multiple threads_ than GLFW
-2 had.  Contexts can be made current on any thread, although only a single
-thread at a time, and the documentation explicitly states which functions may be
-used from any thread and which must only be used from the main thread.
-
-@par Removed functions
-`glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`,
-`glfwGetThreadID`, `glfwCreateMutex`, `glfwDestroyMutex`, `glfwLockMutex`,
-`glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`,
-`glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`.
-
-@par Removed types
-`GLFWthreadfun`
-
-
-@subsection moving_image Removal of image and texture loading
-
-The image and texture loading functions have been removed.  They only supported
-the Targa image format, making them mostly useful for beginner level examples.
-To become of sufficiently high quality to warrant keeping them in GLFW 3, they
-would need not only to support other formats, but also modern extensions to
-OpenGL texturing.  This would either add a number of external
-dependencies (libjpeg, libpng, etc.), or force GLFW to ship with inline versions
-of these libraries.
-
-As there already are libraries doing this, it is unnecessary both to duplicate
-the work and to tie the duplicate to GLFW.  The resulting library would also be
-platform-independent, as both OpenGL and stdio are available wherever GLFW is.
-
-@par Removed functions
-`glfwReadImage`, `glfwReadMemoryImage`, `glfwFreeImage`, `glfwLoadTexture2D`,
-`glfwLoadMemoryTexture2D` and `glfwLoadTextureImage2D`.
-
-
-@subsection moving_stdcall Removal of GLFWCALL macro
-
-The `GLFWCALL` macro, which made callback functions use
-[__stdcall](https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows,
-has been removed.  GLFW is written in C, not Pascal.  Removing this macro means
-there's one less thing for application programmers to remember, i.e. the
-requirement to mark all callback functions with `GLFWCALL`.  It also simplifies
-the creation of DLLs and DLL link libraries, as there's no need to explicitly
-disable `@n` entry point suffixes.
-
-@par Old syntax
-@code
-void GLFWCALL callback_function(...);
-@endcode
-
-@par New syntax
-@code
-void callback_function(...);
-@endcode
-
-
-@subsection moving_window_handles Window handle parameters
-
-Because GLFW 3 supports multiple windows, window handle parameters have been
-added to all window-related GLFW functions and callbacks.  The handle of
-a newly created window is returned by @ref glfwCreateWindow (formerly
-`glfwOpenWindow`).  Window handles are pointers to the
-[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWwindow.
-
-@par Old syntax
-@code
-glfwSetWindowTitle("New Window Title");
-@endcode
-
-@par New syntax
-@code
-glfwSetWindowTitle(window, "New Window Title");
-@endcode
-
-
-@subsection moving_monitor Explicit monitor selection
-
-GLFW 3 provides support for multiple monitors.  To request a full screen mode window,
-instead of passing `GLFW_FULLSCREEN` you specify which monitor you wish the
-window to use.  The @ref glfwGetPrimaryMonitor function returns the monitor that
-GLFW 2 would have selected, but there are many other
-[monitor functions](@ref monitor_guide).  Monitor handles are pointers to the
-[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWmonitor.
-
-@par Old basic full screen
-@code
-glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN);
-@endcode
-
-@par New basic full screen
-@code
-window = glfwCreateWindow(640, 480, "My Window", glfwGetPrimaryMonitor(), NULL);
-@endcode
-
-@note The framebuffer bit depth parameters of `glfwOpenWindow` have been turned
-into [window hints](@ref window_hints), but as they have been given
-[sane defaults](@ref window_hints_values) you rarely need to set these hints.
-
-
-@subsection moving_autopoll Removal of automatic event polling
-
-GLFW 3 does not automatically poll for events in @ref glfwSwapBuffers, meaning
-you need to call @ref glfwPollEvents or @ref glfwWaitEvents yourself.  Unlike
-buffer swap, which acts on a single window, the event processing functions act
-on all windows at once.
-
-@par Old basic main loop
-@code
-while (...)
-{
-    // Process input
-    // Render output
-    glfwSwapBuffers();
-}
-@endcode
-
-@par New basic main loop
-@code
-while (...)
-{
-    // Process input
-    // Render output
-    glfwSwapBuffers(window);
-    glfwPollEvents();
-}
-@endcode
-
-
-@subsection moving_context Explicit context management
-
-Each GLFW 3 window has its own OpenGL context and only you, the application
-programmer, can know which context should be current on which thread at any
-given time.  Therefore, GLFW 3 leaves that decision to you.
-
-This means that you need to call @ref glfwMakeContextCurrent after creating
-a window before you can call any OpenGL functions.
-
-
-@subsection moving_hidpi Separation of window and framebuffer sizes
-
-Window positions and sizes now use screen coordinates, which may not be the same
-as pixels on machines with high-DPI monitors.  This is important as OpenGL uses
-pixels, not screen coordinates.  For example, the rectangle specified with
-`glViewport` needs to use pixels.  Therefore, framebuffer size functions have
-been added.  You can retrieve the size of the framebuffer of a window with @ref
-glfwGetFramebufferSize function.  A framebuffer size callback has also been
-added, which can be set with @ref glfwSetFramebufferSizeCallback.
-
-@par Old basic viewport setup
-@code
-glfwGetWindowSize(&width, &height);
-glViewport(0, 0, width, height);
-@endcode
-
-@par New basic viewport setup
-@code
-glfwGetFramebufferSize(window, &width, &height);
-glViewport(0, 0, width, height);
-@endcode
-
-
-@subsection moving_window_close Window closing changes
-
-The `GLFW_OPENED` window parameter has been removed.  As long as the window has
-not been destroyed, whether through @ref glfwDestroyWindow or @ref
-glfwTerminate, the window is "open".
-
-A user attempting to close a window is now just an event like any other.  Unlike
-GLFW 2, windows and contexts created with GLFW 3 will never be destroyed unless
-you choose them to be.  Each window now has a close flag that is set to
-`GLFW_TRUE` when the user attempts to close that window.  By default, nothing else
-happens and the window stays visible.  It is then up to you to either destroy
-the window, take some other action or ignore the request.
-
-You can query the close flag at any time with @ref glfwWindowShouldClose and set
-it at any time with @ref glfwSetWindowShouldClose.
-
-@par Old basic main loop
-@code
-while (glfwGetWindowParam(GLFW_OPENED))
-{
-    ...
-}
-@endcode
-
-@par New basic main loop
-@code
-while (!glfwWindowShouldClose(window))
-{
-    ...
-}
-@endcode
-
-The close callback no longer returns a value.  Instead, it is called after the
-close flag has been set so it can override its value, if it chooses to, before
-event processing completes.  You may however not call @ref glfwDestroyWindow
-from the close callback (or any other window related callback).
-
-@par Old syntax
-@code
-int GLFWCALL window_close_callback(void);
-@endcode
-
-@par New syntax
-@code
-void window_close_callback(GLFWwindow* window);
-@endcode
-
-@note GLFW never clears the close flag to `GLFW_FALSE`, meaning you can use it
-for other reasons to close the window as well, for example the user choosing
-Quit from an in-game menu.
-
-
-@subsection moving_hints Persistent window hints
-
-The `glfwOpenWindowHint` function has been renamed to @ref glfwWindowHint.
-
-Window hints are no longer reset to their default values on window creation, but
-instead retain their values until modified by @ref glfwWindowHint or @ref
-glfwDefaultWindowHints, or until the library is terminated and re-initialized.
-
-
-@subsection moving_video_modes Video mode enumeration
-
-Video mode enumeration is now per-monitor.  The @ref glfwGetVideoModes function
-now returns all available modes for a specific monitor instead of requiring you
-to guess how large an array you need.  The `glfwGetDesktopMode` function, which
-had poorly defined behavior, has been replaced by @ref glfwGetVideoMode, which
-returns the current mode of a monitor.
-
-
-@subsection moving_char_up Removal of character actions
-
-The action parameter of the [character callback](@ref GLFWcharfun) has been
-removed.  This was an artefact of the origin of GLFW, i.e. being developed in
-English by a Swede.  However, many keyboard layouts require more than one key to
-produce characters with diacritical marks. Even the Swedish keyboard layout
-requires this for uncommon cases like ü.
-
-@par Old syntax
-@code
-void GLFWCALL character_callback(int character, int action);
-@endcode
-
-@par New syntax
-@code
-void character_callback(GLFWwindow* window, int character);
-@endcode
-
-
-@subsection moving_cursorpos Cursor position changes
-
-The `glfwGetMousePos` function has been renamed to @ref glfwGetCursorPos,
-`glfwSetMousePos` to @ref glfwSetCursorPos and `glfwSetMousePosCallback` to @ref
-glfwSetCursorPosCallback.
-
-The cursor position is now `double` instead of `int`, both for the direct
-functions and for the callback.  Some platforms can provide sub-pixel cursor
-movement and this data is now passed on to the application where available.  On
-platforms where this is not provided, the decimal part is zero.
-
-GLFW 3 only allows you to position the cursor within a window using @ref
-glfwSetCursorPos (formerly `glfwSetMousePos`) when that window is active.
-Unless the window is active, the function fails silently.
-
-
-@subsection moving_wheel Wheel position replaced by scroll offsets
-
-The `glfwGetMouseWheel` function has been removed.  Scrolling is the input of
-offsets and has no absolute position.  The mouse wheel callback has been
-replaced by a [scroll callback](@ref GLFWscrollfun) that receives
-two-dimensional floating point scroll offsets.  This allows you to receive
-precise scroll data from for example modern touchpads.
-
-@par Old syntax
-@code
-void GLFWCALL mouse_wheel_callback(int position);
-@endcode
-
-@par New syntax
-@code
-void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
-@endcode
-
-@par Removed functions
-`glfwGetMouseWheel`
-
-
-@subsection moving_repeat Key repeat action
-
-The `GLFW_KEY_REPEAT` enable has been removed and key repeat is always enabled
-for both keys and characters.  A new key action, `GLFW_REPEAT`, has been added
-to allow the [key callback](@ref GLFWkeyfun) to distinguish an initial key press
-from a repeat.  Note that @ref glfwGetKey still returns only `GLFW_PRESS` or
-`GLFW_RELEASE`.
-
-
-@subsection moving_keys Physical key input
-
-GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to
-the values generated by the current keyboard layout.  The tokens are named
-according to the values they would have using the standard US layout, but this
-is only a convenience, as most programmers are assumed to know that layout.
-This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and
-is the same key in the same place regardless of what keyboard layouts the users
-of your program has.
-
-The key input facility was never meant for text input, although using it that
-way worked slightly better in GLFW 2.  If you were using it to input text, you
-should be using the character callback instead, on both GLFW 2 and 3.  This will
-give you the characters being input, as opposed to the keys being pressed.
-
-GLFW 3 has key tokens for all keys on a standard 105 key keyboard, so instead of
-having to remember whether to check for `a` or `A`, you now check for
-@ref GLFW_KEY_A.
-
-
-@subsection moving_joystick Joystick function changes
-
-The `glfwGetJoystickPos` function has been renamed to @ref glfwGetJoystickAxes.
-
-The `glfwGetJoystickParam` function and the `GLFW_PRESENT`, `GLFW_AXES` and
-`GLFW_BUTTONS` tokens have been replaced by the @ref glfwJoystickPresent
-function as well as axis and button counts returned by the @ref
-glfwGetJoystickAxes and @ref glfwGetJoystickButtons functions.
-
-
-@subsection moving_mbcs Win32 MBCS support
-
-The Win32 port of GLFW 3 will not compile in
-[MBCS mode](https://msdn.microsoft.com/en-us/library/5z097dxa.aspx).
-However, because the use of the Unicode version of the Win32 API doesn't affect
-the process as a whole, but only those windows created using it, it's perfectly
-possible to call MBCS functions from other parts of the same application.
-Therefore, even if an application using GLFW has MBCS mode code, there's no need
-for GLFW itself to support it.
-
-
-@subsection moving_windows Support for versions of Windows older than XP
-
-All explicit support for version of Windows older than XP has been removed.
-There is no code that actively prevents GLFW 3 from running on these earlier
-versions, but it uses Win32 functions that those versions lack.
-
-Windows XP was released in 2001, and by now (January 2015) it has not only
-replaced almost all earlier versions of Windows, but is itself rapidly being
-replaced by Windows 7 and 8.  The MSDN library doesn't even provide
-documentation for version older than Windows 2000, making it difficult to
-maintain compatibility with these versions even if it was deemed worth the
-effort.
-
-The Win32 API has also not stood still, and GLFW 3 uses many functions only
-present on Windows XP or later.  Even supporting an OS as new as XP (new
-from the perspective of GLFW 2, which still supports Windows 95) requires
-runtime checking for a number of functions that are present only on modern
-version of Windows.
-
-
-@subsection moving_syskeys Capture of system-wide hotkeys
-
-The ability to disable and capture system-wide hotkeys like Alt+Tab has been
-removed.  Modern applications, whether they're games, scientific visualisations
-or something else, are nowadays expected to be good desktop citizens and allow
-these hotkeys to function even when running in full screen mode.
-
-
-@subsection moving_terminate Automatic termination
-
-GLFW 3 does not register @ref glfwTerminate with `atexit` at initialization,
-because `exit` calls registered functions from the calling thread and while it
-is permitted to call `exit` from any thread, @ref glfwTerminate must only be
-called from the main thread.
-
-To release all resources allocated by GLFW, you should call @ref glfwTerminate
-yourself, from the main thread, before the program terminates.  Note that this
-destroys all windows not already destroyed with @ref glfwDestroyWindow,
-invalidating any window handles you may still have.
-
-
-@subsection moving_glu GLU header inclusion
-
-GLFW 3 does not by default include the GLU header and GLU itself has been
-deprecated by [Khronos](https://en.wikipedia.org/wiki/Khronos_Group).  __New
-projects should not use GLU__, but if you need it for legacy code that
-has been moved to GLFW 3, you can request that the GLFW header includes it by
-defining @ref GLFW_INCLUDE_GLU before the inclusion of the GLFW header.
-
-@par Old syntax
-@code
-#include <GL/glfw.h>
-@endcode
-
-@par New syntax
-@code
-#define GLFW_INCLUDE_GLU
-#include <GLFW/glfw3.h>
-@endcode
-
-There are many libraries that offer replacements for the functionality offered
-by GLU.  For the matrix helper functions, see math libraries like
-[GLM](https://github.com/g-truc/glm) (for C++),
-[linmath.h](https://github.com/datenwolf/linmath.h) (for C) and others.  For the
-tessellation functions, see for example
-[libtess2](https://github.com/memononen/libtess2).
-
-
-@section moving_tables Name change tables
-
-
-@subsection moving_renamed_functions Renamed functions
-
-| GLFW 2                      | GLFW 3                        | Notes |
-| --------------------------- | ----------------------------- | ----- |
-| `glfwOpenWindow`            | @ref glfwCreateWindow         | All channel bit depths are now hints
-| `glfwCloseWindow`           | @ref glfwDestroyWindow        |       |
-| `glfwOpenWindowHint`        | @ref glfwWindowHint           | Now accepts all `GLFW_*_BITS` tokens |
-| `glfwEnable`                | @ref glfwSetInputMode         |       |
-| `glfwDisable`               | @ref glfwSetInputMode         |       |
-| `glfwGetMousePos`           | @ref glfwGetCursorPos         |       |
-| `glfwSetMousePos`           | @ref glfwSetCursorPos         |       |
-| `glfwSetMousePosCallback`   | @ref glfwSetCursorPosCallback |       |
-| `glfwSetMouseWheelCallback` | @ref glfwSetScrollCallback    | Accepts two-dimensional scroll offsets as doubles |
-| `glfwGetJoystickPos`        | @ref glfwGetJoystickAxes      |       |
-| `glfwGetWindowParam`        | @ref glfwGetWindowAttrib      |       |
-| `glfwGetGLVersion`          | @ref glfwGetWindowAttrib      | Use `GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and `GLFW_CONTEXT_REVISION` |
-| `glfwGetDesktopMode`        | @ref glfwGetVideoMode         | Returns the current mode of a monitor |
-| `glfwGetJoystickParam`      | @ref glfwJoystickPresent      | The axis and button counts are provided by @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons |
-
-
-@subsection moving_renamed_types Renamed types
-
-| GLFW 2              | GLFW 3                | Notes |
-| ------------------- | --------------------- |       |
-| `GLFWmousewheelfun` | @ref GLFWscrollfun    |       |
-| `GLFWmouseposfun`   | @ref GLFWcursorposfun |       |
-
-
-@subsection moving_renamed_tokens Renamed tokens
-
-| GLFW 2                      | GLFW 3                       | Notes |
-| --------------------------- | ---------------------------- | ----- |
-| `GLFW_OPENGL_VERSION_MAJOR` | `GLFW_CONTEXT_VERSION_MAJOR` | Renamed as it applies to OpenGL ES as well |
-| `GLFW_OPENGL_VERSION_MINOR` | `GLFW_CONTEXT_VERSION_MINOR` | Renamed as it applies to OpenGL ES as well |
-| `GLFW_FSAA_SAMPLES`         | `GLFW_SAMPLES`               | Renamed to match the OpenGL API |
-| `GLFW_ACTIVE`               | `GLFW_FOCUSED`               | Renamed to match the window focus callback |
-| `GLFW_WINDOW_NO_RESIZE`     | `GLFW_RESIZABLE`             | The default has been inverted |
-| `GLFW_MOUSE_CURSOR`         | `GLFW_CURSOR`                | Used with @ref glfwSetInputMode |
-| `GLFW_KEY_ESC`              | `GLFW_KEY_ESCAPE`            |       |
-| `GLFW_KEY_DEL`              | `GLFW_KEY_DELETE`            |       |
-| `GLFW_KEY_PAGEUP`           | `GLFW_KEY_PAGE_UP`           |       |
-| `GLFW_KEY_PAGEDOWN`         | `GLFW_KEY_PAGE_DOWN`         |       |
-| `GLFW_KEY_KP_NUM_LOCK`      | `GLFW_KEY_NUM_LOCK`          |       |
-| `GLFW_KEY_LCTRL`            | `GLFW_KEY_LEFT_CONTROL`      |       |
-| `GLFW_KEY_LSHIFT`           | `GLFW_KEY_LEFT_SHIFT`        |       |
-| `GLFW_KEY_LALT`             | `GLFW_KEY_LEFT_ALT`          |       |
-| `GLFW_KEY_LSUPER`           | `GLFW_KEY_LEFT_SUPER`        |       |
-| `GLFW_KEY_RCTRL`            | `GLFW_KEY_RIGHT_CONTROL`     |       |
-| `GLFW_KEY_RSHIFT`           | `GLFW_KEY_RIGHT_SHIFT`       |       |
-| `GLFW_KEY_RALT`             | `GLFW_KEY_RIGHT_ALT`         |       |
-| `GLFW_KEY_RSUPER`           | `GLFW_KEY_RIGHT_SUPER`       |       |
-
-*/

+ 0 - 863
samples/third_party/glfw/docs/news.dox

@@ -1,863 +0,0 @@
-/*!
-
-@page news Release notes
-
-@tableofcontents
-
-
-@section news_33 Release notes for version 3.3
-
-These are the release notes for version 3.3.  For a more detailed view including
-all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
-
-Please review the caveats, deprecations and removals if your project was written
-against an earlier version of GLFW 3.
-
-
-@subsection features_33 New features in version 3.3
-
-@subsubsection gamepad_33 Gamepad input via SDL_GameControllerDB
-
-GLFW can now remap game controllers to a standard Xbox-like layout using
-a built-in copy of SDL_GameControllerDB.  Call @ref glfwJoystickIsGamepad to
-check if a joystick has a mapping, @ref glfwGetGamepadState to retrieve its
-input state, @ref glfwUpdateGamepadMappings to add newer mappings and @ref
-glfwGetGamepadName and @ref glfwGetJoystickGUID for mapping related information.
-
-For more information see @ref gamepad.
-
-
-@subsubsection moltenvk_33 Support for Vulkan on macOS via MoltenVK
-
-GLFW now supports [MoltenVK](https://moltengl.com/moltenvk/), a Vulkan
-implementation on top of the Metal API, and its `VK_MVK_macos_surface` window
-surface creation extension.  MoltenVK is included in the [macOS Vulkan
-SDK](https://vulkan.lunarg.com/).
-
-For more information see @ref vulkan_guide.
-
-
-@subsubsection content_scale_33 Content scale queries for DPI-aware rendering
-
-GLFW now provides content scales for windows and monitors, i.e. the ratio
-between their current DPI and the platform's default DPI, with @ref
-glfwGetWindowContentScale and @ref glfwGetMonitorContentScale.
-
-Changes of the content scale of a window can be received with the window content
-scale callback, set with @ref glfwSetWindowContentScaleCallback.
-
-The @ref GLFW_SCALE_TO_MONITOR window hint enables automatic resizing of a
-window by the content scale of the monitor it is placed, on platforms like
-Windows where this is necessary.  This takes effect both on creation and when
-the window is moved between monitors.  It is related to but different from
-[GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint).
-
-For more information see @ref window_scale.
-
-
-@subsubsection setwindowattrib_33 Support for updating window attributes
-
-GLFW now supports changing the [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
-[GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib),
-[GLFW_FLOATING](@ref GLFW_FLOATING_attrib),
-[GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and
-[GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib) attributes for existing
-windows with @ref glfwSetWindowAttrib.
-
-For more information see @ref window_attribs.
-
-
-@subsubsection raw_motion_33 Support for raw mouse motion
-
-GLFW now supports raw (unscaled and unaccelerated) mouse motion in disabled
-cursor mode with the [GLFW_RAW_MOUSE_MOTION](@ref GLFW_RAW_MOUSE_MOTION) input
-mode.  Raw mouse motion input is not yet implemented on macOS.  Call @ref
-glfwRawMouseMotionSupported to check if GLFW can provide raw mouse motion on the
-current system.
-
-For more information see @ref raw_mouse_motion.
-
-
-@subsubsection joysticks_33 Joystick hats
-
-GLFW can now return the state of hats (i.e. POVs or D-pads) of a joystick with
-@ref glfwGetJoystickHats.  For compatibility, hats are also exposed as buttons.
-This can be disabled with the @ref GLFW_JOYSTICK_HAT_BUTTONS initialization
-hint.
-
-For more information see @ref joystick_hat.
-
-
-@subsubsection geterror_33 Error query
-
-GLFW now supports querying the last error code for the calling thread and its
-human-readable description with @ref glfwGetError.  This can be used instead of
-or together with the error callback.
-
-For more information see @ref error_handling.
-
-
-@subsubsection init_hints_33 Support for initialization hints
-
-GLFW now supports setting library initialization hints with @ref glfwInitHint.
-These must be set before initialization to take effect.  Some of these hints are
-platform specific but are safe to set on any platform.
-
-For more information see @ref init_hints.
-
-
-@subsubsection attention_33 User attention request
-
-GLFW now supports requesting user attention with @ref
-glfwRequestWindowAttention.  Where possible this calls attention to the
-specified window.  On platforms like macOS it calls attention to the whole
-application.
-
-For more information see @ref window_attention.
-
-
-@subsubsection maximize_33 Window maximization callback
-
-GLFW now supports notifying the application that the window has been maximized
-@ref glfwSetWindowMaximizeCallback.  This is called both when the window was
-maximized by the user and when it was done with @ref glfwMaximizeWindow.
-
-For more information see @ref window_maximize.
-
-
-@subsubsection workarea_33 Query for the monitor work area
-
-GLFW now supports querying the work area of a monitor, i.e. the area not
-occupied by task bars or global menu bars, with @ref glfwGetMonitorWorkarea.  On
-platforms that lack this concept, the whole area of the monitor is returned.
-
-For more information see @ref monitor_workarea.
-
-
-@subsubsection transparency_33 Transparent windows and framebuffers
-
-GLFW now supports the creation of windows with transparent framebuffers on
-systems with desktop compositing enabled with the @ref
-GLFW_TRANSPARENT_FRAMEBUFFER window hint and attribute.  This hint must be set
-before window creation and leaves any window decorations opaque.
-
-GLFW now also supports whole window transparency with @ref glfwGetWindowOpacity
-and @ref glfwSetWindowOpacity.  This value controls the opacity of the whole
-window including decorations and unlike framebuffer transparency can be changed
-at any time after window creation.
-
-For more information see @ref window_transparency.
-
-
-@subsubsection key_scancode_33 Query for the scancode of a key
-
-GLFW now supports querying the platform dependent scancode of any physical key
-with @ref glfwGetKeyScancode.
-
-For more information see @ref input_key.
-
-
-@subsubsection center_cursor_33 Cursor centering window hint
-
-GLFW now supports controlling whether the cursor is centered over newly created
-full screen windows with the [GLFW_CENTER_CURSOR](@ref GLFW_CENTER_CURSOR_hint)
-window hint.  It is enabled by default.
-
-
-@subsubsection cursor_hover_33 Mouse cursor hover window attribute
-
-GLFW now supports polling whether the cursor is hovering over the window content
-area with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute.  This
-attribute corresponds to the [cursor enter/leave](@ref cursor_enter) event.
-
-
-@subsubsection focusonshow_33 Window hint and attribute for input focus on show
-
-GLFW now has the [GLFW_FOCUS_ON_SHOW](@ref GLFW_DECORATED_hint) window hint and
-attribute for controlling whether a window gets input focus when shown.  It is
-enabled by default.  It applies both when creating an visible window with @ref
-glfwCreateWindow and when showing it with @ref glfwShowWindow.
-
-This is a workaround for GLFW 3.0 lacking @ref glfwFocusWindow and will be
-corrected in the next major version.
-
-For more information see @ref window_hide.
-
-
-@subsubsection device_userptr_33 Monitor and joystick user pointers
-
-GLFW now supports setting and querying user pointers for connected monitors and
-joysticks with @ref glfwSetMonitorUserPointer, @ref glfwGetMonitorUserPointer,
-@ref glfwSetJoystickUserPointer and @ref glfwGetJoystickUserPointer.
-
-For more information see @ref monitor_userptr and @ref joystick_userptr.
-
-
-@subsubsection macos_nib_33 macOS menu bar from nib file
-
-GLFW will now load a `MainMenu.nib` file if found in the `Contents/Resources`
-directory of the application bundle, as a way to replace the GLFW menu bar
-without recompiling GLFW.  This behavior can be disabled with the
-[GLFW_COCOA_MENUBAR](@ref GLFW_COCOA_MENUBAR_hint) initialization hint.
-
-
-@subsubsection glext_33 Support for more context creation extensions
-
-The context hint @ref GLFW_SRGB_CAPABLE now supports OpenGL ES via
-`WGL_EXT_colorspace`, the context hint @ref GLFW_CONTEXT_NO_ERROR now supports
-`WGL_ARB_create_context_no_error` and `GLX_ARB_create_context_no_error`, the
-context hint @ref GLFW_CONTEXT_RELEASE_BEHAVIOR now supports
-`EGL_KHR_context_flush_control` and @ref glfwGetProcAddress now supports
-`EGL_KHR_get_all_proc_addresses`.
-
-
-@subsubsection osmesa_33 OSMesa off-screen context creation support
-
-GLFW now supports creating off-screen OpenGL contexts using
-[OSMesa](https://www.mesa3d.org/osmesa.html) by setting
-[GLFW_CONTEXT_CREATION_API](@ref GLFW_CONTEXT_CREATION_API_hint) to
-`GLFW_OSMESA_CONTEXT_API`.  Native access function have been added to retrieve
-the OSMesa color and depth buffers.
-
-There is also a new null backend that uses OSMesa as its native context
-creation API, intended for automated testing.  This backend does not provide
-input.
-
-
-@subsection caveats_33 Caveats for version 3.3
-
-@subsubsection joystick_layout_33 Layout of joysticks have changed
-
-The way joystick elements are arranged have changed to match SDL2 in order to
-support SDL_GameControllerDB mappings.  The layout of joysticks may
-change again if required for compatibility with SDL2.  If you need a known and
-stable layout for game controllers, see if you can switch to @ref gamepad.
-
-Existing code that depends on a specific joystick layout will likely have to be
-updated.
-
-
-@subsubsection wait_events_33 No window required to wait for events
-
-The @ref glfwWaitEvents and @ref glfwWaitEventsTimeout functions no longer need
-a window to be created to wait for events.  Before version 3.3 these functions
-would return immediately if there were no user-created windows.  On platforms
-where only windows can receive events, an internal helper window is used.
-
-Existing code that depends on the earlier behavior will likely have to be
-updated.
-
-
-@subsubsection gamma_ramp_size_33 Gamma ramp size of 256 may be rejected
-
-The documentation for versions before 3.3 stated that a gamma ramp size of 256
-would always be accepted.  This was never the case on X11 and could lead to
-artifacts on macOS.  The @ref glfwSetGamma function has been updated to always
-generate a ramp of the correct size.
-
-Existing code that hardcodes a size of 256 should be updated to use the size of
-the current ramp of a monitor when setting a new ramp for that monitor.
-
-
-@subsubsection xinput_deadzone_33 Windows XInput deadzone removed
-
-GLFW no longer applies any deadzone to the input state received from the XInput
-API.  This was never done for any other platform joystick API so this change
-makes the behavior more consistent but you will need to apply your own deadzone
-if desired.
-
-
-@subsubsection x11_clipboard_33 X11 clipboard transfer limits
-
-GLFW now supports reading clipboard text via the `INCR` method, which removes
-the limit on how much text can be read with @ref glfwGetClipboardString.
-However, writing via this method is not yet supported, so you may not be able to
-write a very large string with @ref glfwSetClipboardString even if you read it
-from the clipboard earlier.
-
-The exact size limit for writing to the clipboard is negotiated with each
-receiving application but is at least several tens of kilobytes.  Note that only
-the read limit has changed.  Any string that could be written before still can
-be.
-
-
-@subsubsection x11_linking_33 X11 extension libraries are loaded dynamically
-
-GLFW now loads all X11 extension libraries at initialization.  The only X11
-library you need to link against is `libX11`.  The header files for the
-extension libraries are still required for compilation.
-
-Existing projects and makefiles that link GLFW directly against the extension
-libraries should still build correctly but will add these libraries as load-time
-dependencies.
-
-
-@subsubsection cmake_version_33 CMake 3.0 or later is required
-
-The minimum CMake version has been raised from 2.8.12 to 3.0.  This is only
-a requirement of the GLFW CMake files.  The GLFW source files do not depend on
-CMake.
-
-
-@subsubsection caveat_fbtransparency_33 Framebuffer transparency requires DWM transparency
-
-GLFW no longer supports framebuffer transparency enabled via @ref
-GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off
-(the Transparency setting under Personalization > Window Color).
-
-
-@subsection deprecations_33 Deprecations in version 3.3
-
-@subsubsection charmods_callback_33 Character with modifiers callback
-
-The character with modifiers callback set with @ref glfwSetCharModsCallback has
-been deprecated and should if possible not be used.
-
-Existing code should still work but further bug fixes will likely not be made.
-The callback will be removed in the next major version.
-
-
-@subsubsection clipboard_window_33 Window parameter to clipboard functions
-
-The window parameter of the clipboard functions @ref glfwGetClipboardString and
-@ref glfwSetClipboardString has been deprecated and is no longer used on any
-platform.  On platforms where the clipboard must be owned by a specific window,
-an internal helper window is used.
-
-Existing code should still work unless it depends on a specific window owning
-the clipboard.  New code may pass `NULL` as the window argument.  The parameter
-will be removed in a future release.
-
-
-@subsection removals_33 Removals in 3.3
-
-@subsubsection macos_options_33 macOS specific CMake options and macros
-
-The `GLFW_USE_RETINA`, `GLFW_USE_CHDIR` and `GLFW_USE_MENUBAR` CMake options and
-the `_GLFW_USE_RETINA`, `_GLFW_USE_CHDIR` and `_GLFW_USE_MENUBAR` compile-time
-macros have been removed.
-
-These options and macros are replaced by the window hint
-[GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
-and the init hints
-[GLFW_COCOA_CHDIR_RESOURCES](@ref GLFW_COCOA_CHDIR_RESOURCES_hint) and
-[GLFW_COCOA_MENUBAR](@ref GLFW_COCOA_MENUBAR_hint).
-
-Existing projects and makefiles that set these options or define these macros
-during compilation of GLFW will still build but it will have no effect and the
-default behaviors will be used.
-
-
-@subsubsection vulkan_sdk_33 LunarG Vulkan SDK dependency
-
-The GLFW test programs that previously depended on the LunarG Vulkan SDK now
-instead uses a Vulkan loader generated by
-[glad2](https://github.com/Dav1dde/glad).  This means the GLFW CMake files no
-longer look for the Vulkan SDK.
-
-Existing CMake projects that depended on the Vulkan SDK cache variables from
-GLFW will need to call `find_package(Vulkan)` themselves.  CMake 3.7 and later
-already comes with a
-[Vulkan find module](https://cmake.org/cmake/help/latest/module/FindVulkan.html)
-similar to the one GLFW previously included.
-
-
-@subsubsection lib_suffix_33 CMake option LIB_SUFFIX
-
-The `LIB_SUFFIX` CMake option has been removed.  GLFW now uses the
-GNUInstallDirs CMake package to handle platform specific details like the
-library directory suffix and the `LIB_SUFFIX` CMake option has been removed.
-
-Existing projects and makefiles that set the `LIB_SUFFIX` option will use the
-suffix chosen by the GNUInstallDirs package and the option will be ignored.
-
-
-@subsubsection mir_removed_33 Mir support
-
-The experimental Mir support has been completely removed as the Mir project has
-implemented support for the Wayland protocol and is recommending that
-applications use that instead.
-
-Existing projects and makefiles that select Mir when compiling GLFW will fail.
-Use Wayland or X11 instead.
-
-
-@subsection symbols_33 New symbols in version 3.3
-
-@subsubsection functions_33 New functions in version 3.3
-
- - @ref glfwInitHint
- - @ref glfwGetError
- - @ref glfwGetMonitorWorkarea
- - @ref glfwGetMonitorContentScale
- - @ref glfwGetMonitorUserPointer
- - @ref glfwSetMonitorUserPointer
- - @ref glfwWindowHintString
- - @ref glfwGetWindowContentScale
- - @ref glfwGetWindowOpacity
- - @ref glfwSetWindowOpacity
- - @ref glfwRequestWindowAttention
- - @ref glfwSetWindowAttrib
- - @ref glfwSetWindowMaximizeCallback
- - @ref glfwSetWindowContentScaleCallback
- - @ref glfwRawMouseMotionSupported
- - @ref glfwGetKeyScancode
- - @ref glfwGetJoystickHats
- - @ref glfwGetJoystickGUID
- - @ref glfwGetJoystickUserPointer
- - @ref glfwSetJoystickUserPointer
- - @ref glfwJoystickIsGamepad
- - @ref glfwUpdateGamepadMappings
- - @ref glfwGetGamepadName
- - @ref glfwGetGamepadState
-
-
-@subsubsection types_33 New types in version 3.3
-
- - @ref GLFWwindowmaximizefun
- - @ref GLFWwindowcontentscalefun
- - @ref GLFWgamepadstate
-
-
-@subsubsection constants_33 New constants in version 3.3
-
- - @ref GLFW_NO_ERROR
- - @ref GLFW_JOYSTICK_HAT_BUTTONS
- - @ref GLFW_COCOA_CHDIR_RESOURCES
- - @ref GLFW_COCOA_MENUBAR
- - @ref GLFW_CENTER_CURSOR
- - @ref GLFW_TRANSPARENT_FRAMEBUFFER
- - @ref GLFW_HOVERED
- - @ref GLFW_FOCUS_ON_SHOW
- - @ref GLFW_SCALE_TO_MONITOR
- - @ref GLFW_COCOA_RETINA_FRAMEBUFFER
- - @ref GLFW_COCOA_FRAME_NAME
- - @ref GLFW_COCOA_GRAPHICS_SWITCHING
- - @ref GLFW_X11_CLASS_NAME
- - @ref GLFW_X11_INSTANCE_NAME
- - @ref GLFW_OSMESA_CONTEXT_API
- - @ref GLFW_HAT_CENTERED
- - @ref GLFW_HAT_UP
- - @ref GLFW_HAT_RIGHT
- - @ref GLFW_HAT_DOWN
- - @ref GLFW_HAT_LEFT
- - @ref GLFW_HAT_RIGHT_UP
- - @ref GLFW_HAT_RIGHT_DOWN
- - @ref GLFW_HAT_LEFT_UP
- - @ref GLFW_HAT_LEFT_DOWN
- - @ref GLFW_MOD_CAPS_LOCK
- - @ref GLFW_MOD_NUM_LOCK
- - @ref GLFW_LOCK_KEY_MODS
- - @ref GLFW_RAW_MOUSE_MOTION
- - @ref GLFW_GAMEPAD_BUTTON_A
- - @ref GLFW_GAMEPAD_BUTTON_B
- - @ref GLFW_GAMEPAD_BUTTON_X
- - @ref GLFW_GAMEPAD_BUTTON_Y
- - @ref GLFW_GAMEPAD_BUTTON_LEFT_BUMPER
- - @ref GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER
- - @ref GLFW_GAMEPAD_BUTTON_BACK
- - @ref GLFW_GAMEPAD_BUTTON_START
- - @ref GLFW_GAMEPAD_BUTTON_GUIDE
- - @ref GLFW_GAMEPAD_BUTTON_LEFT_THUMB
- - @ref GLFW_GAMEPAD_BUTTON_RIGHT_THUMB
- - @ref GLFW_GAMEPAD_BUTTON_DPAD_UP
- - @ref GLFW_GAMEPAD_BUTTON_DPAD_RIGHT
- - @ref GLFW_GAMEPAD_BUTTON_DPAD_DOWN
- - @ref GLFW_GAMEPAD_BUTTON_DPAD_LEFT
- - @ref GLFW_GAMEPAD_BUTTON_LAST
- - @ref GLFW_GAMEPAD_BUTTON_CROSS
- - @ref GLFW_GAMEPAD_BUTTON_CIRCLE
- - @ref GLFW_GAMEPAD_BUTTON_SQUARE
- - @ref GLFW_GAMEPAD_BUTTON_TRIANGLE
- - @ref GLFW_GAMEPAD_AXIS_LEFT_X
- - @ref GLFW_GAMEPAD_AXIS_LEFT_Y
- - @ref GLFW_GAMEPAD_AXIS_RIGHT_X
- - @ref GLFW_GAMEPAD_AXIS_RIGHT_Y
- - @ref GLFW_GAMEPAD_AXIS_LEFT_TRIGGER
- - @ref GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
- - @ref GLFW_GAMEPAD_AXIS_LAST
-
-
-@section news_32 Release notes for 3.2
-
-These are the release notes for version 3.2.  For a more detailed view including
-all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
-
-
-@subsection features_32 New features in version 3.2
-
-@subsubsection news_32_vulkan Support for Vulkan
-
-GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported,
-@ref glfwGetRequiredInstanceExtensions, @ref glfwGetInstanceProcAddress, @ref
-glfwGetPhysicalDevicePresentationSupport and @ref glfwCreateWindowSurface.
-Vulkan header inclusion can be selected with
-@ref GLFW_INCLUDE_VULKAN.
-
-
-@subsubsection news_32_setwindowmonitor Window mode switching
-
-GLFW now supports switching between windowed and full screen modes and updating
-the monitor and desired resolution and refresh rate of full screen windows with
-@ref glfwSetWindowMonitor.
-
-
-@subsubsection news_32_maximize Window maxmimization support
-
-GLFW now supports window maximization with @ref glfwMaximizeWindow and the
-@ref GLFW_MAXIMIZED window hint and attribute.
-
-
-@subsubsection news_32_focus Window input focus control
-
-GLFW now supports giving windows input focus with @ref glfwFocusWindow.
-
-
-@subsubsection news_32_sizelimits Window size limit support
-
-GLFW now supports setting both absolute and relative window size limits with
-@ref glfwSetWindowSizeLimits and @ref glfwSetWindowAspectRatio.
-
-
-@subsubsection news_32_keyname Localized key names
-
-GLFW now supports querying the localized name of printable keys with @ref
-glfwGetKeyName, either by key token or by scancode.
-
-
-@subsubsection news_32_waittimeout Wait for events with timeout
-
-GLFW now supports waiting for events for a set amount of time with @ref
-glfwWaitEventsTimeout.
-
-
-@subsubsection news_32_icon Window icon support
-
-GLFW now supports setting the icon of windows with @ref glfwSetWindowIcon.
-
-
-@subsubsection news_32_timer Raw timer access
-
-GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref
-glfwGetTimerFrequency.
-
-
-@subsubsection news_32_joystick Joystick connection callback
-
-GLFW now supports notifying when a joystick has been connected or disconnected
-with @ref glfwSetJoystickCallback.
-
-
-@subsubsection news_32_noapi Context-less windows
-
-GLFW now supports creating windows without a OpenGL or OpenGL ES context by
-setting the [GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`.
-
-
-@subsubsection news_32_contextapi Run-time context creation API selection
-
-GLFW now supports selecting and querying the context creation API at run-time
-with the @ref GLFW_CONTEXT_CREATION_API hint and attribute.
-
-
-@subsubsection news_32_noerror Error-free context creation
-
-GLFW now supports creating and querying OpenGL and OpenGL ES contexts that do
-not emit errors with the @ref GLFW_CONTEXT_NO_ERROR hint, provided the machine
-supports the `GL_KHR_no_error` extension.
-
-
-@subsubsection news_32_cmake CMake config-file package support
-
-GLFW now supports being used as a
-[config-file package](@ref build_link_cmake_package) from other projects for
-easy linking with the library and its dependencies.
-
-
-@section news_31 Release notes for 3.1
-
-These are the release notes for version 3.1.  For a more detailed view including
-all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
-
-
-@subsection features_31 New features in version 3.1
-
-@subsubsection news_31_cursor Custom mouse cursor images
-
-GLFW now supports creating and setting both custom cursor images and standard
-cursor shapes.  They are created with @ref glfwCreateCursor or @ref
-glfwCreateStandardCursor, set with @ref glfwSetCursor and destroyed with @ref
-glfwDestroyCursor.
-
-@see @ref cursor_object
-
-
-@subsubsection news_31_drop Path drop event
-
-GLFW now provides a callback for receiving the paths of files and directories
-dropped onto GLFW windows.  The callback is set with @ref glfwSetDropCallback.
-
-@see @ref path_drop
-
-
-@subsubsection news_31_emptyevent Main thread wake-up
-
-GLFW now provides the @ref glfwPostEmptyEvent function for posting an empty
-event from another thread to the main thread event queue, causing @ref
-glfwWaitEvents to return.
-
-@see @ref events
-
-
-@subsubsection news_31_framesize Window frame size query
-
-GLFW now supports querying the size, on each side, of the frame around the
-content area of a window, with @ref glfwGetWindowFrameSize.
-
-@see [Window size](@ref window_size)
-
-
-@subsubsection news_31_autoiconify Simultaneous multi-monitor rendering
-
-GLFW now supports disabling auto-iconification of full screen windows with
-the [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_hint) window hint.  This is
-intended for people building multi-monitor installations, where you need windows
-to stay in full screen despite losing input focus.
-
-
-@subsubsection news_31_floating Floating windows
-
-GLFW now supports floating windows, also called topmost or always on top, for
-easier debugging with the @ref GLFW_FLOATING window hint and attribute.
-
-
-@subsubsection news_31_focused Initially unfocused windows
-
-GLFW now supports preventing a windowed mode window from gaining input focus on
-creation, with the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) window hint.
-
-
-@subsubsection news_31_direct Direct access for window attributes and cursor position
-
-GLFW now queries the window input focus, visibility and iconification attributes
-and the cursor position directly instead of returning cached data.
-
-
-@subsubsection news_31_charmods Character with modifiers callback
-
-GLFW now provides a callback for character events with modifier key bits.  The
-callback is set with @ref glfwSetCharModsCallback.  Unlike the regular character
-callback, this will report character events that will not result in a character
-being input, for example if the Control key is held down.
-
-@see @ref input_char
-
-
-@subsubsection news_31_single Single buffered framebuffers
-
-GLFW now supports the creation of single buffered windows, with the @ref
-GLFW_DOUBLEBUFFER hint.
-
-
-@subsubsection news_31_glext Macro for including extension header
-
-GLFW now includes the extension header appropriate for the chosen OpenGL or
-OpenGL ES header when @ref GLFW_INCLUDE_GLEXT is defined.  GLFW does not provide
-these headers.  They must be provided by your development environment or your
-OpenGL or OpenGL ES SDK.
-
-
-@subsubsection news_31_release Context release behaviors
-
-GLFW now supports controlling and querying whether the pipeline is flushed when
-a context is made non-current, with the @ref GLFW_CONTEXT_RELEASE_BEHAVIOR hint
-and attribute, provided the machine supports the `GL_KHR_context_flush_control`
-extension.
-
-
-@subsubsection news_31_wayland (Experimental) Wayland support
-
-GLFW now has an _experimental_ Wayland display protocol backend that can be
-selected on Linux with a CMake option.
-
-
-@subsubsection news_31_mir (Experimental) Mir support
-
-GLFW now has an _experimental_ Mir display server backend that can be selected
-on Linux with a CMake option.
-
-
-@section news_30 Release notes for 3.0
-
-These are the release notes for version 3.0.  For a more detailed view including
-all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
-
-
-@subsection features_30 New features in version 3.0
-
-@subsubsection news_30_cmake CMake build system
-
-GLFW now uses the CMake build system instead of the various makefiles and
-project files used by earlier versions.  CMake is available for all platforms
-supported by GLFW, is present in most package systems and can generate
-makefiles and/or project files for most popular development environments.
-
-For more information on how to use CMake, see the
-[CMake manual](https://cmake.org/cmake/help/documentation.html).
-
-
-@subsubsection news_30_multiwnd Multi-window support
-
-GLFW now supports the creation of multiple windows, each with their own OpenGL
-or OpenGL ES context, and all window functions now take a window handle.  Event
-callbacks are now per-window and are provided with the handle of the window that
-received the event.  The @ref glfwMakeContextCurrent function has been added to
-select which context is current on a given thread.
-
-
-@subsubsection news_30_multimon Multi-monitor support
-
-GLFW now explicitly supports multiple monitors.  They can be enumerated with
-@ref glfwGetMonitors, queried with @ref glfwGetVideoModes, @ref
-glfwGetMonitorPos, @ref glfwGetMonitorName and @ref glfwGetMonitorPhysicalSize,
-and specified at window creation to make the newly created window full screen on
-that specific monitor.
-
-
-@subsubsection news_30_unicode Unicode support
-
-All string arguments to GLFW functions and all strings returned by GLFW now use
-the UTF-8 encoding.  This includes the window title, error string, clipboard
-text, monitor and joystick names as well as the extension function arguments (as
-ASCII is a subset of UTF-8).
-
-
-@subsubsection news_30_clipboard Clipboard text I/O
-
-GLFW now supports reading and writing plain text to and from the system
-clipboard, with the @ref glfwGetClipboardString and @ref glfwSetClipboardString
-functions.
-
-
-@subsubsection news_30_gamma Gamma ramp support
-
-GLFW now supports setting and reading back the gamma ramp of monitors, with the
-@ref glfwGetGammaRamp and @ref glfwSetGammaRamp functions.  There is also @ref
-glfwSetGamma, which generates a ramp from a gamma value and then sets it.
-
-
-@subsubsection news_30_gles OpenGL ES support
-
-GLFW now supports the creation of OpenGL ES contexts, by setting the
-[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_OPENGL_ES_API`, where
-creation of such contexts are supported.  Note that GLFW _does not implement_
-OpenGL ES, so your driver must provide support in a way usable by GLFW.  Modern
-Nvidia and Intel drivers support creation of OpenGL ES context using the GLX and
-WGL APIs, while AMD provides an EGL implementation instead.
-
-
-@subsubsection news_30_egl (Experimental) EGL support
-
-GLFW now has an experimental EGL context creation back end that can be selected
-through CMake options.
-
-
-@subsubsection news_30_hidpi High-DPI support
-
-GLFW now supports high-DPI monitors on both Windows and macOS, giving windows
-full resolution framebuffers where other UI elements are scaled up.  To achieve
-this, @ref glfwGetFramebufferSize and @ref glfwSetFramebufferSizeCallback have
-been added.  These work with pixels, while the rest of the GLFW API works with
-screen coordinates.  This is important as OpenGL uses pixels, not screen
-coordinates.
-
-
-@subsubsection news_30_error Error callback
-
-GLFW now has an error callback, which can provide your application with much
-more detailed diagnostics than was previously possible.  The callback is passed
-an error code and a description string.
-
-
-@subsubsection news_30_wndptr Per-window user pointer
-
-Each window now has a user-defined pointer, retrieved with @ref
-glfwGetWindowUserPointer and set with @ref glfwSetWindowUserPointer, to make it
-easier to integrate GLFW into C++ code.
-
-
-@subsubsection news_30_iconifyfun Window iconification callback
-
-Each window now has a callback for iconification and restoration events,
-which is set with @ref glfwSetWindowIconifyCallback.
-
-
-@subsubsection news_30_wndposfun Window position callback
-
-Each window now has a callback for position events, which is set with @ref
-glfwSetWindowPosCallback.
-
-
-@subsubsection news_30_wndpos Window position query
-
-The position of a window can now be retrieved using @ref glfwGetWindowPos.
-
-
-@subsubsection news_30_focusfun Window focus callback
-
-Each windows now has a callback for focus events, which is set with @ref
-glfwSetWindowFocusCallback.
-
-
-@subsubsection news_30_enterleave Cursor enter/leave callback
-
-Each window now has a callback for when the mouse cursor enters or leaves its
-content area, which is set with @ref glfwSetCursorEnterCallback.
-
-
-@subsubsection news_30_wndtitle Initial window title
-
-The title of a window is now specified at creation time, as one of the arguments
-to @ref glfwCreateWindow.
-
-
-@subsubsection news_30_hidden Hidden windows
-
-Windows can now be hidden with @ref glfwHideWindow, shown using @ref
-glfwShowWindow and created initially hidden with the @ref GLFW_VISIBLE window
-hint and attribute.  This allows for off-screen rendering in a way compatible
-with most drivers, as well as moving a window to a specific position before
-showing it.
-
-
-@subsubsection news_30_undecorated Undecorated windows
-
-Windowed mode windows can now be created without decorations, e.g. things like
-a frame, a title bar, with the @ref GLFW_DECORATED window hint and attribute.
-This allows for the creation of things like splash screens.
-
-
-@subsubsection news_30_keymods Modifier key bit masks
-
-[Modifier key bit mask](@ref mods) parameters have been added to the
-[mouse button](@ref GLFWmousebuttonfun) and [key](@ref GLFWkeyfun) callbacks.
-
-
-@subsubsection news_30_scancode Platform-specific scancodes
-
-A scancode parameter has been added to the [key callback](@ref GLFWkeyfun). Keys
-that don't have a [key token](@ref keys) still get passed on with the key
-parameter set to `GLFW_KEY_UNKNOWN`.  These scancodes will vary between machines
-and are intended to be used for key bindings.
-
-
-@subsubsection news_30_jsname Joystick names
-
-The name of a joystick can now be retrieved using @ref glfwGetJoystickName.
-
-
-@subsubsection news_30_doxygen Doxygen documentation
-
-You are reading it.
-
-*/

+ 0 - 365
samples/third_party/glfw/docs/quick.dox

@@ -1,365 +0,0 @@
-/*!
-
-@page quick_guide Getting started
-
-@tableofcontents
-
-This guide takes you through writing a simple application using GLFW 3.  The
-application will create a window and OpenGL context, render a rotating triangle
-and exit when the user closes the window or presses _Escape_.  This guide will
-introduce a few of the most commonly used functions, but there are many more.
-
-This guide assumes no experience with earlier versions of GLFW.  If you
-have used GLFW 2 in the past, read @ref moving_guide, as some functions
-behave differently in GLFW 3.
-
-
-@section quick_steps Step by step
-
-@subsection quick_include Including the GLFW header
-
-In the source files of your application where you use GLFW, you need to include
-its header file.
-
-@code
-#include <GLFW/glfw3.h>
-@endcode
-
-This header provides all the constants, types and function prototypes of the
-GLFW API.
-
-By default it also includes the OpenGL header from your development environment.
-On some platforms this header only supports older versions of OpenGL.  The most
-extreme case is Windows, where it typically only supports OpenGL 1.2.
-
-Most programs will instead use an
-[extension loader library](@ref context_glext_auto) and include its header.
-This example uses files generated by [glad](https://gen.glad.sh/).  The GLFW
-header can detect most such headers if they are included first and will then not
-include the one from your development environment.
-
-@code
-#include <glad/gl.h>
-#include <GLFW/glfw3.h>
-@endcode
-
-To make sure there will be no header conflicts, you can define @ref
-GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the
-development environment header.  This also allows the two headers to be included
-in any order.
-
-@code
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-#include <glad/gl.h>
-@endcode
-
-
-@subsection quick_init_term Initializing and terminating GLFW
-
-Before you can use most GLFW functions, the library must be initialized.  On
-successful initialization, `GLFW_TRUE` is returned.  If an error occurred,
-`GLFW_FALSE` is returned.
-
-@code
-if (!glfwInit())
-{
-    // Initialization failed
-}
-@endcode
-
-Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be one and zero.
-
-When you are done using GLFW, typically just before the application exits, you
-need to terminate GLFW.
-
-@code
-glfwTerminate();
-@endcode
-
-This destroys any remaining windows and releases any other resources allocated by
-GLFW.  After this call, you must initialize GLFW again before using any GLFW
-functions that require it.
-
-
-@subsection quick_capture_error Setting an error callback
-
-Most events are reported through callbacks, whether it's a key being pressed,
-a GLFW window being moved, or an error occurring.  Callbacks are C functions (or
-C++ static methods) that are called by GLFW with arguments describing the event.
-
-In case a GLFW function fails, an error is reported to the GLFW error callback.
-You can receive these reports with an error callback.  This function must have
-the signature below but may do anything permitted in other callbacks.
-
-@code
-void error_callback(int error, const char* description)
-{
-    fprintf(stderr, "Error: %s\n", description);
-}
-@endcode
-
-Callback functions must be set, so GLFW knows to call them.  The function to set
-the error callback is one of the few GLFW functions that may be called before
-initialization, which lets you be notified of errors both during and after
-initialization.
-
-@code
-glfwSetErrorCallback(error_callback);
-@endcode
-
-
-@subsection quick_create_window Creating a window and context
-
-The window and its OpenGL context are created with a single call to @ref
-glfwCreateWindow, which returns a handle to the created combined window and
-context object
-
-@code
-GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
-if (!window)
-{
-    // Window or OpenGL context creation failed
-}
-@endcode
-
-This creates a 640 by 480 windowed mode window with an OpenGL context.  If
-window or OpenGL context creation fails, `NULL` will be returned.  You should
-always check the return value.  While window creation rarely fails, context
-creation depends on properly installed drivers and may fail even on machines
-with the necessary hardware.
-
-By default, the OpenGL context GLFW creates may have any version.  You can
-require a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and
-`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation.  If the required minimum
-version is not supported on the machine, context (and window) creation fails.
-
-@code
-glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
-glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
-if (!window)
-{
-    // Window or context creation failed
-}
-@endcode
-
-The window handle is passed to all window related functions and is provided to
-along to all window related callbacks, so they can tell which window received
-the event.
-
-When a window and context is no longer needed, destroy it.
-
-@code
-glfwDestroyWindow(window);
-@endcode
-
-Once this function is called, no more events will be delivered for that window
-and its handle becomes invalid.
-
-
-@subsection quick_context_current Making the OpenGL context current
-
-Before you can use the OpenGL API, you must have a current OpenGL context.
-
-@code
-glfwMakeContextCurrent(window);
-@endcode
-
-The context will remain current until you make another context current or until
-the window owning the current context is destroyed.
-
-If you are using an [extension loader library](@ref context_glext_auto) to
-access modern OpenGL then this is when to initialize it, as the loader needs
-a current context to load from.  This example uses
-[glad](https://github.com/Dav1dde/glad), but the same rule applies to all such
-libraries.
-
-@code
-gladLoadGL(glfwGetProcAddress);
-@endcode
-
-
-@subsection quick_window_close Checking the window close flag
-
-Each window has a flag indicating whether the window should be closed.
-
-When the user attempts to close the window, either by pressing the close widget
-in the title bar or using a key combination like Alt+F4, this flag is set to 1.
-Note that __the window isn't actually closed__, so you are expected to monitor
-this flag and either destroy the window or give some kind of feedback to the
-user.
-
-@code
-while (!glfwWindowShouldClose(window))
-{
-    // Keep running
-}
-@endcode
-
-You can be notified when the user is attempting to close the window by setting
-a close callback with @ref glfwSetWindowCloseCallback.  The callback will be
-called immediately after the close flag has been set.
-
-You can also set it yourself with @ref glfwSetWindowShouldClose.  This can be
-useful if you want to interpret other kinds of input as closing the window, like
-for example pressing the _Escape_ key.
-
-
-@subsection quick_key_input Receiving input events
-
-Each window has a large number of callbacks that can be set to receive all the
-various kinds of events.  To receive key press and release events, create a key
-callback function.
-
-@code
-static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
-{
-    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
-        glfwSetWindowShouldClose(window, GLFW_TRUE);
-}
-@endcode
-
-The key callback, like other window related callbacks, are set per-window.
-
-@code
-glfwSetKeyCallback(window, key_callback);
-@endcode
-
-In order for event callbacks to be called when events occur, you need to process
-events as described below.
-
-
-@subsection quick_render Rendering with OpenGL
-
-Once you have a current OpenGL context, you can use OpenGL normally.  In this
-tutorial, a multi-colored rotating triangle will be rendered.  The framebuffer
-size needs to be retrieved for `glViewport`.
-
-@code
-int width, height;
-glfwGetFramebufferSize(window, &width, &height);
-glViewport(0, 0, width, height);
-@endcode
-
-You can also set a framebuffer size callback using @ref
-glfwSetFramebufferSizeCallback and be notified when the size changes.
-
-The details of how to render with OpenGL is outside the scope of this tutorial,
-but there are many excellent resources for learning modern OpenGL.  Here are
-a few of them:
-
- - [Anton's OpenGL 4 Tutorials](https://antongerdelan.net/opengl/)
- - [Learn OpenGL](https://learnopengl.com/)
- - [Open.GL](https://open.gl/)
-
-These all happen to use GLFW, but OpenGL itself works the same whatever API you
-use to create the window and context.
-
-
-@subsection quick_timer Reading the timer
-
-To create smooth animation, a time source is needed.  GLFW provides a timer that
-returns the number of seconds since initialization.  The time source used is the
-most accurate on each platform and generally has micro- or nanosecond
-resolution.
-
-@code
-double time = glfwGetTime();
-@endcode
-
-
-@subsection quick_swap_buffers Swapping buffers
-
-GLFW windows by default use double buffering.  That means that each window has
-two rendering buffers; a front buffer and a back buffer.  The front buffer is
-the one being displayed and the back buffer the one you render to.
-
-When the entire frame has been rendered, the buffers need to be swapped with one
-another, so the back buffer becomes the front buffer and vice versa.
-
-@code
-glfwSwapBuffers(window);
-@endcode
-
-The swap interval indicates how many frames to wait until swapping the buffers,
-commonly known as _vsync_.  By default, the swap interval is zero, meaning
-buffer swapping will occur immediately.  On fast machines, many of those frames
-will never be seen, as the screen is still only updated typically 60-75 times
-per second, so this wastes a lot of CPU and GPU cycles.
-
-Also, because the buffers will be swapped in the middle the screen update,
-leading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing).
-
-For these reasons, applications will typically want to set the swap interval to
-one.  It can be set to higher values, but this is usually not recommended,
-because of the input latency it leads to.
-
-@code
-glfwSwapInterval(1);
-@endcode
-
-This function acts on the current context and will fail unless a context is
-current.
-
-
-@subsection quick_process_events Processing events
-
-GLFW needs to communicate regularly with the window system both in order to
-receive events and to show that the application hasn't locked up.  Event
-processing must be done regularly while you have visible windows and is normally
-done each frame after buffer swapping.
-
-There are two methods for processing pending events; polling and waiting.  This
-example will use event polling, which processes only those events that have
-already been received and then returns immediately.
-
-@code
-glfwPollEvents();
-@endcode
-
-This is the best choice when rendering continually, like most games do.  If
-instead you only need to update your rendering once you have received new input,
-@ref glfwWaitEvents is a better choice.  It waits until at least one event has
-been received, putting the thread to sleep in the meantime, and then processes
-all received events.  This saves a great deal of CPU cycles and is useful for,
-for example, many kinds of editing tools.
-
-
-@section quick_example Putting it together
-
-Now that you know how to initialize GLFW, create a window and poll for
-keyboard input, it's possible to create a simple program.
-
-This program creates a 640 by 480 windowed mode window and starts a loop that
-clears the screen, renders a triangle and processes events until the user either
-presses _Escape_ or closes the window.
-
-@snippet simple.c code
-
-The program above can be found in the
-[source package](https://www.glfw.org/download.html) as `examples/simple.c`
-and is compiled along with all other examples when you build GLFW.  If you
-built GLFW from the source package then you already have this as `simple.exe` on
-Windows, `simple` on Linux or `simple.app` on macOS.
-
-This tutorial used only a few of the many functions GLFW provides.  There are
-guides for each of the areas covered by GLFW.  Each guide will introduce all the
-functions for that category.
-
- - @ref intro_guide
- - @ref window_guide
- - @ref context_guide
- - @ref monitor_guide
- - @ref input_guide
-
-You can access reference documentation for any GLFW function by clicking it and
-the reference for each function links to related functions and guide sections.
-
-The tutorial ends here.  Once you have written a program that uses GLFW, you
-will need to compile and link it.  How to do that depends on the development
-environment you are using and is best explained by the documentation for that
-environment.  To learn about the details that are specific to GLFW, see
-@ref build_guide.
-
-*/

ファイルの差分が大きいため隠しています
+ 0 - 877
samples/third_party/glfw/docs/spaces.svg


+ 0 - 235
samples/third_party/glfw/docs/vulkan.dox

@@ -1,235 +0,0 @@
-/*!
-
-@page vulkan_guide Vulkan guide
-
-@tableofcontents
-
-This guide is intended to fill the gaps between the official [Vulkan
-resources](https://www.khronos.org/vulkan/) and the rest of the GLFW
-documentation and is not a replacement for either.  It assumes some familiarity
-with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to
-the Vulkan documentation to explain the details of Vulkan functions.
-
-To develop for Vulkan you should download the [LunarG Vulkan
-SDK](https://vulkan.lunarg.com/) for your platform.  Apart from headers and link
-libraries, they also provide the validation layers necessary for development.
-
-The [Vulkan Tutorial](https://vulkan-tutorial.com/) has more information on how
-to use GLFW and Vulkan.  The [Khronos Vulkan
-Samples](https://github.com/KhronosGroup/Vulkan-Samples) also use GLFW, although
-with a small framework in between.
-
-For details on a specific Vulkan support function, see the @ref vulkan.  There
-are also guides for the other areas of the GLFW API.
-
- - @ref intro_guide
- - @ref window_guide
- - @ref context_guide
- - @ref monitor_guide
- - @ref input_guide
-
-
-@section vulkan_loader Linking against the Vulkan loader
-
-By default, GLFW will look for the Vulkan loader on demand at runtime via its
-standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other
-Unix-like systems and `libvulkan.1.dylib` on macOS).  This means that GLFW does
-not need to be linked against the loader.  However, it also means that if you
-are using the static library form of the Vulkan loader GLFW will either fail to
-find it or (worse) use the wrong one.
-
-The @ref GLFW_VULKAN_STATIC CMake option makes GLFW call the Vulkan loader
-directly instead of dynamically loading it at runtime.  Not linking against the
-Vulkan loader will then be a compile-time error.
-
-@macos Because the Vulkan loader and ICD are not installed globally on macOS,
-you need to set up the application bundle according to the LunarG SDK
-documentation.  This is explained in more detail in the
-[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
-
-
-@section vulkan_include Including the Vulkan and GLFW header files
-
-To include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including
-the GLFW header.
-
-@code
-#define GLFW_INCLUDE_VULKAN
-#include <GLFW/glfw3.h>
-@endcode
-
-If you instead want to include the Vulkan header from a custom location or use
-your own custom Vulkan header then do this before the GLFW header.
-
-@code
-#include <path/to/vulkan.h>
-#include <GLFW/glfw3.h>
-@endcode
-
-Unless a Vulkan header is included, either by the GLFW header or above it, any
-GLFW functions that take or return Vulkan types will not be declared.
-
-The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part
-of GLFW to work.  Define them only if you are using these extensions directly.
-
-
-@section vulkan_support Querying for Vulkan support
-
-If you are linking directly against the Vulkan loader then you can skip this
-section.  The canonical desktop loader library exports all Vulkan core and
-Khronos extension functions, allowing them to be called directly.
-
-If you are loading the Vulkan loader dynamically instead of linking directly
-against it, you can check for the availability of a loader and ICD with @ref
-glfwVulkanSupported.
-
-@code
-if (glfwVulkanSupported())
-{
-    // Vulkan is available, at least for compute
-}
-@endcode
-
-This function returns `GLFW_TRUE` if the Vulkan loader and any minimally
-functional ICD was found.
-
-If one or both were not found, calling any other Vulkan related GLFW function
-will generate a @ref GLFW_API_UNAVAILABLE error.
-
-
-@subsection vulkan_proc Querying Vulkan function pointers
-
-To load any Vulkan core or extension function from the found loader, call @ref
-glfwGetInstanceProcAddress.  To load functions needed for instance creation,
-pass `NULL` as the instance.
-
-@code
-PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance)
-    glfwGetInstanceProcAddress(NULL, "vkCreateInstance");
-@endcode
-
-Once you have created an instance, you can load from it all other Vulkan core
-functions and functions from any instance extensions you enabled.
-
-@code
-PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice)
-    glfwGetInstanceProcAddress(instance, "vkCreateDevice");
-@endcode
-
-This function in turn calls `vkGetInstanceProcAddr`.  If that fails, the
-function falls back to a platform-specific query of the Vulkan loader (i.e.
-`dlsym` or `GetProcAddress`).  If that also fails, the function returns `NULL`.
-For more information about `vkGetInstanceProcAddr`, see the Vulkan
-documentation.
-
-Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions
-of Vulkan function.  This function can be retrieved from an instance with @ref
-glfwGetInstanceProcAddress.
-
-@code
-PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
-    glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
-@endcode
-
-Device-specific functions may execute a little bit faster, due to not having to
-dispatch internally based on the device passed to them.  For more information
-about `vkGetDeviceProcAddr`, see the Vulkan documentation.
-
-
-@section vulkan_ext Querying required Vulkan extensions
-
-To do anything useful with Vulkan you need to create an instance.  If you want
-to use Vulkan to render to a window, you must enable the instance extensions
-GLFW requires to create Vulkan surfaces.
-
-To query the instance extensions required, call @ref
-glfwGetRequiredInstanceExtensions.
-
-@code
-uint32_t count;
-const char** extensions = glfwGetRequiredInstanceExtensions(&count);
-@endcode
-
-These extensions must all be enabled when creating instances that are going to
-be passed to @ref glfwGetPhysicalDevicePresentationSupport and @ref
-glfwCreateWindowSurface.  The set of extensions will vary depending on platform
-and may also vary depending on graphics drivers and other factors.
-
-If it fails it will return `NULL` and GLFW will not be able to create Vulkan
-window surfaces.  You can still use Vulkan for off-screen rendering and compute
-work.
-
-If successful the returned array will always include `VK_KHR_surface`, so if
-you don't require any additional extensions you can pass this list directly to
-the `VkInstanceCreateInfo` struct.
-
-@code
-VkInstanceCreateInfo ici;
-
-memset(&ici, 0, sizeof(ici));
-ici.enabledExtensionCount = count;
-ici.ppEnabledExtensionNames = extensions;
-...
-@endcode
-
-Additional extensions may be required by future versions of GLFW.  You should
-check whether any extensions you wish to enable are already in the returned
-array, as it is an error to specify an extension more than once in the
-`VkInstanceCreateInfo` struct.
-
-
-@section vulkan_present Querying for Vulkan presentation support
-
-Not every queue family of every Vulkan device can present images to surfaces.
-To check whether a specific queue family of a physical device supports image
-presentation without first having to create a window and surface, call @ref
-glfwGetPhysicalDevicePresentationSupport.
-
-@code
-if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index))
-{
-    // Queue family supports image presentation
-}
-@endcode
-
-The `VK_KHR_surface` extension additionally provides the
-`vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on
-an existing Vulkan surface.
-
-
-@section vulkan_window Creating the window
-
-Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan,
-there is no need to create a context.  You can disable context creation with the
-[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint.
-
-@code
-glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
-GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL);
-@endcode
-
-See @ref context_less for more information.
-
-
-@section vulkan_surface Creating a Vulkan window surface
-
-You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension)
-for a GLFW window with @ref glfwCreateWindowSurface.
-
-@code
-VkSurfaceKHR surface;
-VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface);
-if (err)
-{
-    // Window surface creation failed
-}
-@endcode
-
-If an OpenGL or OpenGL ES context was created on the window, the context has
-ownership of the presentation on the window and a Vulkan surface cannot be
-created.
-
-It is your responsibility to destroy the surface.  GLFW does not destroy it for
-you.  Call `vkDestroySurfaceKHR` function from the same extension to destroy it.
-
-*/

ファイルの差分が大きいため隠しています
+ 0 - 1412
samples/third_party/glfw/docs/window.dox


+ 0 - 93
samples/third_party/glfw/examples/CMakeLists.txt

@@ -1,93 +0,0 @@
-
-link_libraries(glfw)
-
-include_directories("${GLFW_SOURCE_DIR}/deps")
-
-if (MATH_LIBRARY)
-    link_libraries("${MATH_LIBRARY}")
-endif()
-
-# Workaround for the MS CRT deprecating parts of the standard library
-if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
-    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
-endif()
-
-if (WIN32)
-    set(ICON glfw.rc)
-elseif (APPLE)
-    set(ICON glfw.icns)
-endif()
-
-if (${CMAKE_VERSION} VERSION_EQUAL "3.1.0" OR
-    ${CMAKE_VERSION} VERSION_GREATER "3.1.0")
-    set(CMAKE_C_STANDARD 99)
-else()
-    # Remove this fallback when removing support for CMake version less than 3.1
-    add_compile_options("$<$<C_COMPILER_ID:AppleClang>:-std=c99>"
-                        "$<$<C_COMPILER_ID:Clang>:-std=c99>"
-                        "$<$<C_COMPILER_ID:GNU>:-std=c99>")
-
-endif()
-
-set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h"
-            "${GLFW_SOURCE_DIR}/deps/glad_gl.c")
-set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h"
-           "${GLFW_SOURCE_DIR}/deps/getopt.c")
-set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h"
-                "${GLFW_SOURCE_DIR}/deps/tinycthread.c")
-
-add_executable(boing WIN32 MACOSX_BUNDLE boing.c ${ICON} ${GLAD_GL})
-add_executable(gears WIN32 MACOSX_BUNDLE gears.c ${ICON} ${GLAD_GL})
-add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD_GL})
-add_executable(offscreen offscreen.c ${ICON} ${GLAD_GL})
-add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD_GL})
-add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${ICON} ${GLAD_GL})
-add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD_GL})
-add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD_GL})
-add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
-
-target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}")
-if (RT_LIBRARY)
-    target_link_libraries(particles "${RT_LIBRARY}")
-endif()
-
-set(GUI_ONLY_BINARIES boing gears heightmap particles sharing simple splitview
-    wave)
-set(CONSOLE_BINARIES offscreen)
-
-set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
-                      FOLDER "GLFW3/Examples")
-
-if (GLFW_USE_OSMESA)
-    target_compile_definitions(offscreen PRIVATE USE_NATIVE_OSMESA)
-endif()
-
-if (MSVC)
-    # Tell MSVC to use main instead of WinMain
-    set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
-                          LINK_FLAGS "/ENTRY:mainCRTStartup")
-elseif (CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
-    # Tell Clang using MS CRT to use main instead of WinMain
-    set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
-                          LINK_FLAGS "-Wl,/entry:mainCRTStartup")
-endif()
-
-if (APPLE)
-    set_target_properties(boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
-    set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
-    set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap")
-    set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
-    set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")
-    set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
-    set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
-    set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
-
-    set_source_files_properties(glfw.icns PROPERTIES
-                                MACOSX_PACKAGE_LOCATION "Resources")
-    set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
-                          MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
-                          MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}
-                          MACOSX_BUNDLE_ICON_FILE glfw.icns
-                          MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in")
-endif()
-

+ 0 - 679
samples/third_party/glfw/examples/boing.c

@@ -1,679 +0,0 @@
-/*****************************************************************************
- * Title:   GLBoing
- * Desc:    Tribute to Amiga Boing.
- * Author:  Jim Brooks  <gfx@jimbrooks.org>
- *          Original Amiga authors were R.J. Mical and Dale Luck.
- *          GLFW conversion by Marcus Geelnard
- * Notes:   - 360' = 2*PI [radian]
- *
- *          - Distances between objects are created by doing a relative
- *            Z translations.
- *
- *          - Although OpenGL enticingly supports alpha-blending,
- *            the shadow of the original Boing didn't affect the color
- *            of the grid.
- *
- *          - [Marcus] Changed timing scheme from interval driven to frame-
- *            time based animation steps (which results in much smoother
- *            movement)
- *
- * History of Amiga Boing:
- *
- * Boing was demonstrated on the prototype Amiga (codenamed "Lorraine") in
- * 1985. According to legend, it was written ad-hoc in one night by
- * R. J. Mical and Dale Luck. Because the bouncing ball animation was so fast
- * and smooth, attendees did not believe the Amiga prototype was really doing
- * the rendering. Suspecting a trick, they began looking around the booth for
- * a hidden computer or VCR.
- *****************************************************************************/
-
-#if defined(_MSC_VER)
- // Make MS math.h define M_PI
- #define _USE_MATH_DEFINES
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include <glad/gl.h>
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-#include <linmath.h>
-
-
-/*****************************************************************************
- * Various declarations and macros
- *****************************************************************************/
-
-/* Prototypes */
-void init( void );
-void display( void );
-void reshape( GLFWwindow* window, int w, int h );
-void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods );
-void mouse_button_callback( GLFWwindow* window, int button, int action, int mods );
-void cursor_position_callback( GLFWwindow* window, double x, double y );
-void DrawBoingBall( void );
-void BounceBall( double dt );
-void DrawBoingBallBand( GLfloat long_lo, GLfloat long_hi );
-void DrawGrid( void );
-
-#define RADIUS           70.f
-#define STEP_LONGITUDE   22.5f                   /* 22.5 makes 8 bands like original Boing */
-#define STEP_LATITUDE    22.5f
-
-#define DIST_BALL       (RADIUS * 2.f + RADIUS * 0.1f)
-
-#define VIEW_SCENE_DIST (DIST_BALL * 3.f + 200.f)/* distance from viewer to middle of boing area */
-#define GRID_SIZE       (RADIUS * 4.5f)          /* length (width) of grid */
-#define BOUNCE_HEIGHT   (RADIUS * 2.1f)
-#define BOUNCE_WIDTH    (RADIUS * 2.1f)
-
-#define SHADOW_OFFSET_X -20.f
-#define SHADOW_OFFSET_Y  10.f
-#define SHADOW_OFFSET_Z   0.f
-
-#define WALL_L_OFFSET   0.f
-#define WALL_R_OFFSET   5.f
-
-/* Animation speed (50.0 mimics the original GLUT demo speed) */
-#define ANIMATION_SPEED 50.f
-
-/* Maximum allowed delta time per physics iteration */
-#define MAX_DELTA_T 0.02f
-
-/* Draw ball, or its shadow */
-typedef enum { DRAW_BALL, DRAW_BALL_SHADOW } DRAW_BALL_ENUM;
-
-/* Vertex type */
-typedef struct {float x; float y; float z;} vertex_t;
-
-/* Global vars */
-int windowed_xpos, windowed_ypos, windowed_width, windowed_height;
-int width, height;
-GLfloat deg_rot_y       = 0.f;
-GLfloat deg_rot_y_inc   = 2.f;
-int override_pos        = GLFW_FALSE;
-GLfloat cursor_x        = 0.f;
-GLfloat cursor_y        = 0.f;
-GLfloat ball_x          = -RADIUS;
-GLfloat ball_y          = -RADIUS;
-GLfloat ball_x_inc      = 1.f;
-GLfloat ball_y_inc      = 2.f;
-DRAW_BALL_ENUM drawBallHow;
-double  t;
-double  t_old = 0.f;
-double  dt;
-
-/* Random number generator */
-#ifndef RAND_MAX
- #define RAND_MAX 4095
-#endif
-
-
-/*****************************************************************************
- * Truncate a degree.
- *****************************************************************************/
-GLfloat TruncateDeg( GLfloat deg )
-{
-   if ( deg >= 360.f )
-      return (deg - 360.f);
-   else
-      return deg;
-}
-
-/*****************************************************************************
- * Convert a degree (360-based) into a radian.
- * 360' = 2 * PI
- *****************************************************************************/
-double deg2rad( double deg )
-{
-   return deg / 360 * (2 * M_PI);
-}
-
-/*****************************************************************************
- * 360' sin().
- *****************************************************************************/
-double sin_deg( double deg )
-{
-   return sin( deg2rad( deg ) );
-}
-
-/*****************************************************************************
- * 360' cos().
- *****************************************************************************/
-double cos_deg( double deg )
-{
-   return cos( deg2rad( deg ) );
-}
-
-/*****************************************************************************
- * Compute a cross product (for a normal vector).
- *
- * c = a x b
- *****************************************************************************/
-void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n )
-{
-   GLfloat u1, u2, u3;
-   GLfloat v1, v2, v3;
-
-   u1 = b.x - a.x;
-   u2 = b.y - a.y;
-   u3 = b.y - a.z;
-
-   v1 = c.x - a.x;
-   v2 = c.y - a.y;
-   v3 = c.z - a.z;
-
-   n->x = u2 * v3 - v2 * u3;
-   n->y = u3 * v1 - v3 * u1;
-   n->z = u1 * v2 - v1 * u2;
-}
-
-
-#define BOING_DEBUG 0
-
-
-/*****************************************************************************
- * init()
- *****************************************************************************/
-void init( void )
-{
-   /*
-    * Clear background.
-    */
-   glClearColor( 0.55f, 0.55f, 0.55f, 0.f );
-
-   glShadeModel( GL_FLAT );
-}
-
-
-/*****************************************************************************
- * display()
- *****************************************************************************/
-void display(void)
-{
-   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-   glPushMatrix();
-
-   drawBallHow = DRAW_BALL_SHADOW;
-   DrawBoingBall();
-
-   DrawGrid();
-
-   drawBallHow = DRAW_BALL;
-   DrawBoingBall();
-
-   glPopMatrix();
-   glFlush();
-}
-
-
-/*****************************************************************************
- * reshape()
- *****************************************************************************/
-void reshape( GLFWwindow* window, int w, int h )
-{
-   mat4x4 projection, view;
-
-   glViewport( 0, 0, (GLsizei)w, (GLsizei)h );
-
-   glMatrixMode( GL_PROJECTION );
-   mat4x4_perspective( projection,
-                       2.f * (float) atan2( RADIUS, 200.f ),
-                       (float)w / (float)h,
-                       1.f, VIEW_SCENE_DIST );
-   glLoadMatrixf((const GLfloat*) projection);
-
-   glMatrixMode( GL_MODELVIEW );
-   {
-      vec3 eye = { 0.f, 0.f, VIEW_SCENE_DIST };
-      vec3 center = { 0.f, 0.f, 0.f };
-      vec3 up = { 0.f, -1.f, 0.f };
-      mat4x4_look_at( view, eye, center, up );
-   }
-   glLoadMatrixf((const GLfloat*) view);
-}
-
-void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods )
-{
-    if (action != GLFW_PRESS)
-        return;
-
-    if (key == GLFW_KEY_ESCAPE && mods == 0)
-        glfwSetWindowShouldClose(window, GLFW_TRUE);
-    if ((key == GLFW_KEY_ENTER && mods == GLFW_MOD_ALT) ||
-        (key == GLFW_KEY_F11 && mods == GLFW_MOD_ALT))
-    {
-        if (glfwGetWindowMonitor(window))
-        {
-            glfwSetWindowMonitor(window, NULL,
-                                 windowed_xpos, windowed_ypos,
-                                 windowed_width, windowed_height, 0);
-        }
-        else
-        {
-            GLFWmonitor* monitor = glfwGetPrimaryMonitor();
-            if (monitor)
-            {
-                const GLFWvidmode* mode = glfwGetVideoMode(monitor);
-                glfwGetWindowPos(window, &windowed_xpos, &windowed_ypos);
-                glfwGetWindowSize(window, &windowed_width, &windowed_height);
-                glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
-            }
-        }
-    }
-}
-
-static void set_ball_pos ( GLfloat x, GLfloat y )
-{
-   ball_x = (width / 2) - x;
-   ball_y = y - (height / 2);
-}
-
-void mouse_button_callback( GLFWwindow* window, int button, int action, int mods )
-{
-   if (button != GLFW_MOUSE_BUTTON_LEFT)
-      return;
-
-   if (action == GLFW_PRESS)
-   {
-      override_pos = GLFW_TRUE;
-      set_ball_pos(cursor_x, cursor_y);
-   }
-   else
-   {
-      override_pos = GLFW_FALSE;
-   }
-}
-
-void cursor_position_callback( GLFWwindow* window, double x, double y )
-{
-   cursor_x = (float) x;
-   cursor_y = (float) y;
-
-   if ( override_pos )
-      set_ball_pos(cursor_x, cursor_y);
-}
-
-/*****************************************************************************
- * Draw the Boing ball.
- *
- * The Boing ball is sphere in which each facet is a rectangle.
- * Facet colors alternate between red and white.
- * The ball is built by stacking latitudinal circles.  Each circle is composed
- * of a widely-separated set of points, so that each facet is noticeably large.
- *****************************************************************************/
-void DrawBoingBall( void )
-{
-   GLfloat lon_deg;     /* degree of longitude */
-   double dt_total, dt2;
-
-   glPushMatrix();
-   glMatrixMode( GL_MODELVIEW );
-
-  /*
-   * Another relative Z translation to separate objects.
-   */
-   glTranslatef( 0.0, 0.0, DIST_BALL );
-
-   /* Update ball position and rotation (iterate if necessary) */
-   dt_total = dt;
-   while( dt_total > 0.0 )
-   {
-       dt2 = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total;
-       dt_total -= dt2;
-       BounceBall( dt2 );
-       deg_rot_y = TruncateDeg( deg_rot_y + deg_rot_y_inc*((float)dt2*ANIMATION_SPEED) );
-   }
-
-   /* Set ball position */
-   glTranslatef( ball_x, ball_y, 0.0 );
-
-  /*
-   * Offset the shadow.
-   */
-   if ( drawBallHow == DRAW_BALL_SHADOW )
-   {
-      glTranslatef( SHADOW_OFFSET_X,
-                    SHADOW_OFFSET_Y,
-                    SHADOW_OFFSET_Z );
-   }
-
-  /*
-   * Tilt the ball.
-   */
-   glRotatef( -20.0, 0.0, 0.0, 1.0 );
-
-  /*
-   * Continually rotate ball around Y axis.
-   */
-   glRotatef( deg_rot_y, 0.0, 1.0, 0.0 );
-
-  /*
-   * Set OpenGL state for Boing ball.
-   */
-   glCullFace( GL_FRONT );
-   glEnable( GL_CULL_FACE );
-   glEnable( GL_NORMALIZE );
-
-  /*
-   * Build a faceted latitude slice of the Boing ball,
-   * stepping same-sized vertical bands of the sphere.
-   */
-   for ( lon_deg = 0;
-         lon_deg < 180;
-         lon_deg += STEP_LONGITUDE )
-   {
-     /*
-      * Draw a latitude circle at this longitude.
-      */
-      DrawBoingBallBand( lon_deg,
-                         lon_deg + STEP_LONGITUDE );
-   }
-
-   glPopMatrix();
-
-   return;
-}
-
-
-/*****************************************************************************
- * Bounce the ball.
- *****************************************************************************/
-void BounceBall( double delta_t )
-{
-   GLfloat sign;
-   GLfloat deg;
-
-   if ( override_pos )
-     return;
-
-   /* Bounce on walls */
-   if ( ball_x >  (BOUNCE_WIDTH/2 + WALL_R_OFFSET ) )
-   {
-      ball_x_inc = -0.5f - 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX;
-      deg_rot_y_inc = -deg_rot_y_inc;
-   }
-   if ( ball_x < -(BOUNCE_HEIGHT/2 + WALL_L_OFFSET) )
-   {
-      ball_x_inc =  0.5f + 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX;
-      deg_rot_y_inc = -deg_rot_y_inc;
-   }
-
-   /* Bounce on floor / roof */
-   if ( ball_y >  BOUNCE_HEIGHT/2      )
-   {
-      ball_y_inc = -0.75f - 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX;
-   }
-   if ( ball_y < -BOUNCE_HEIGHT/2*0.85 )
-   {
-      ball_y_inc =  0.75f + 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX;
-   }
-
-   /* Update ball position */
-   ball_x += ball_x_inc * ((float)delta_t*ANIMATION_SPEED);
-   ball_y += ball_y_inc * ((float)delta_t*ANIMATION_SPEED);
-
-  /*
-   * Simulate the effects of gravity on Y movement.
-   */
-   if ( ball_y_inc < 0 ) sign = -1.0; else sign = 1.0;
-
-   deg = (ball_y + BOUNCE_HEIGHT/2) * 90 / BOUNCE_HEIGHT;
-   if ( deg > 80 ) deg = 80;
-   if ( deg < 10 ) deg = 10;
-
-   ball_y_inc = sign * 4.f * (float) sin_deg( deg );
-}
-
-
-/*****************************************************************************
- * Draw a faceted latitude band of the Boing ball.
- *
- * Parms:   long_lo, long_hi
- *          Low and high longitudes of slice, resp.
- *****************************************************************************/
-void DrawBoingBallBand( GLfloat long_lo,
-                        GLfloat long_hi )
-{
-   vertex_t vert_ne;            /* "ne" means south-east, so on */
-   vertex_t vert_nw;
-   vertex_t vert_sw;
-   vertex_t vert_se;
-   vertex_t vert_norm;
-   GLfloat  lat_deg;
-   static int colorToggle = 0;
-
-  /*
-   * Iterate through the points of a latitude circle.
-   * A latitude circle is a 2D set of X,Z points.
-   */
-   for ( lat_deg = 0;
-         lat_deg <= (360 - STEP_LATITUDE);
-         lat_deg += STEP_LATITUDE )
-   {
-     /*
-      * Color this polygon with red or white.
-      */
-      if ( colorToggle )
-         glColor3f( 0.8f, 0.1f, 0.1f );
-      else
-         glColor3f( 0.95f, 0.95f, 0.95f );
-#if 0
-      if ( lat_deg >= 180 )
-         if ( colorToggle )
-            glColor3f( 0.1f, 0.8f, 0.1f );
-         else
-            glColor3f( 0.5f, 0.5f, 0.95f );
-#endif
-      colorToggle = ! colorToggle;
-
-     /*
-      * Change color if drawing shadow.
-      */
-      if ( drawBallHow == DRAW_BALL_SHADOW )
-         glColor3f( 0.35f, 0.35f, 0.35f );
-
-     /*
-      * Assign each Y.
-      */
-      vert_ne.y = vert_nw.y = (float) cos_deg(long_hi) * RADIUS;
-      vert_sw.y = vert_se.y = (float) cos_deg(long_lo) * RADIUS;
-
-     /*
-      * Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude.
-      * Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude),
-      * while long=90 (sin(90)=1) is at equator.
-      */
-      vert_ne.x = (float) cos_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
-      vert_se.x = (float) cos_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo                  ));
-      vert_nw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
-      vert_sw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo                  ));
-
-      vert_ne.z = (float) sin_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
-      vert_se.z = (float) sin_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo                  ));
-      vert_nw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
-      vert_sw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo                  ));
-
-     /*
-      * Draw the facet.
-      */
-      glBegin( GL_POLYGON );
-
-      CrossProduct( vert_ne, vert_nw, vert_sw, &vert_norm );
-      glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z );
-
-      glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z );
-      glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z );
-      glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z );
-      glVertex3f( vert_se.x, vert_se.y, vert_se.z );
-
-      glEnd();
-
-#if BOING_DEBUG
-      printf( "----------------------------------------------------------- \n" );
-      printf( "lat = %f  long_lo = %f  long_hi = %f \n", lat_deg, long_lo, long_hi );
-      printf( "vert_ne  x = %.8f  y = %.8f  z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z );
-      printf( "vert_nw  x = %.8f  y = %.8f  z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z );
-      printf( "vert_se  x = %.8f  y = %.8f  z = %.8f \n", vert_se.x, vert_se.y, vert_se.z );
-      printf( "vert_sw  x = %.8f  y = %.8f  z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z );
-#endif
-
-   }
-
-  /*
-   * Toggle color so that next band will opposite red/white colors than this one.
-   */
-   colorToggle = ! colorToggle;
-
-  /*
-   * This circular band is done.
-   */
-   return;
-}
-
-
-/*****************************************************************************
- * Draw the purple grid of lines, behind the Boing ball.
- * When the Workbench is dropped to the bottom, Boing shows 12 rows.
- *****************************************************************************/
-void DrawGrid( void )
-{
-   int              row, col;
-   const int        rowTotal    = 12;                   /* must be divisible by 2 */
-   const int        colTotal    = rowTotal;             /* must be same as rowTotal */
-   const GLfloat    widthLine   = 2.0;                  /* should be divisible by 2 */
-   const GLfloat    sizeCell    = GRID_SIZE / rowTotal;
-   const GLfloat    z_offset    = -40.0;
-   GLfloat          xl, xr;
-   GLfloat          yt, yb;
-
-   glPushMatrix();
-   glDisable( GL_CULL_FACE );
-
-  /*
-   * Another relative Z translation to separate objects.
-   */
-   glTranslatef( 0.0, 0.0, DIST_BALL );
-
-  /*
-   * Draw vertical lines (as skinny 3D rectangles).
-   */
-   for ( col = 0; col <= colTotal; col++ )
-   {
-     /*
-      * Compute co-ords of line.
-      */
-      xl = -GRID_SIZE / 2 + col * sizeCell;
-      xr = xl + widthLine;
-
-      yt =  GRID_SIZE / 2;
-      yb = -GRID_SIZE / 2 - widthLine;
-
-      glBegin( GL_POLYGON );
-
-      glColor3f( 0.6f, 0.1f, 0.6f );               /* purple */
-
-      glVertex3f( xr, yt, z_offset );       /* NE */
-      glVertex3f( xl, yt, z_offset );       /* NW */
-      glVertex3f( xl, yb, z_offset );       /* SW */
-      glVertex3f( xr, yb, z_offset );       /* SE */
-
-      glEnd();
-   }
-
-  /*
-   * Draw horizontal lines (as skinny 3D rectangles).
-   */
-   for ( row = 0; row <= rowTotal; row++ )
-   {
-     /*
-      * Compute co-ords of line.
-      */
-      yt = GRID_SIZE / 2 - row * sizeCell;
-      yb = yt - widthLine;
-
-      xl = -GRID_SIZE / 2;
-      xr =  GRID_SIZE / 2 + widthLine;
-
-      glBegin( GL_POLYGON );
-
-      glColor3f( 0.6f, 0.1f, 0.6f );               /* purple */
-
-      glVertex3f( xr, yt, z_offset );       /* NE */
-      glVertex3f( xl, yt, z_offset );       /* NW */
-      glVertex3f( xl, yb, z_offset );       /* SW */
-      glVertex3f( xr, yb, z_offset );       /* SE */
-
-      glEnd();
-   }
-
-   glPopMatrix();
-
-   return;
-}
-
-
-/*======================================================================*
- * main()
- *======================================================================*/
-
-int main( void )
-{
-   GLFWwindow* window;
-
-   /* Init GLFW */
-   if( !glfwInit() )
-      exit( EXIT_FAILURE );
-
-   window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL );
-   if (!window)
-   {
-       glfwTerminate();
-       exit( EXIT_FAILURE );
-   }
-
-   glfwSetWindowAspectRatio(window, 1, 1);
-
-   glfwSetFramebufferSizeCallback(window, reshape);
-   glfwSetKeyCallback(window, key_callback);
-   glfwSetMouseButtonCallback(window, mouse_button_callback);
-   glfwSetCursorPosCallback(window, cursor_position_callback);
-
-   glfwMakeContextCurrent(window);
-   gladLoadGL(glfwGetProcAddress);
-   glfwSwapInterval( 1 );
-
-   glfwGetFramebufferSize(window, &width, &height);
-   reshape(window, width, height);
-
-   glfwSetTime( 0.0 );
-
-   init();
-
-   /* Main loop */
-   for (;;)
-   {
-       /* Timing */
-       t = glfwGetTime();
-       dt = t - t_old;
-       t_old = t;
-
-       /* Draw one frame */
-       display();
-
-       /* Swap buffers */
-       glfwSwapBuffers(window);
-       glfwPollEvents();
-
-       /* Check if we are still running */
-       if (glfwWindowShouldClose(window))
-           break;
-   }
-
-   glfwTerminate();
-   exit( EXIT_SUCCESS );
-}
-

+ 0 - 360
samples/third_party/glfw/examples/gears.c

@@ -1,360 +0,0 @@
-/*
- * 3-D gear wheels.  This program is in the public domain.
- *
- * Command line options:
- *    -info      print GL implementation information
- *    -exit      automatically exit after 30 seconds
- *
- *
- * Brian Paul
- *
- *
- * Marcus Geelnard:
- *   - Conversion to GLFW
- *   - Time based rendering (frame rate independent)
- *   - Slightly modified camera that should work better for stereo viewing
- *
- *
- * Camilla Löwy:
- *   - Removed FPS counter (this is not a benchmark)
- *   - Added a few comments
- *   - Enabled vsync
- */
-
-#if defined(_MSC_VER)
- // Make MS math.h define M_PI
- #define _USE_MATH_DEFINES
-#endif
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glad/gl.h>
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-/**
-
-  Draw a gear wheel.  You'll probably want to call this function when
-  building a display list since we do a lot of trig here.
-
-  Input:  inner_radius - radius of hole at center
-          outer_radius - radius at center of teeth
-          width - width of gear teeth - number of teeth
-          tooth_depth - depth of tooth
-
- **/
-
-static void
-gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
-  GLint teeth, GLfloat tooth_depth)
-{
-  GLint i;
-  GLfloat r0, r1, r2;
-  GLfloat angle, da;
-  GLfloat u, v, len;
-
-  r0 = inner_radius;
-  r1 = outer_radius - tooth_depth / 2.f;
-  r2 = outer_radius + tooth_depth / 2.f;
-
-  da = 2.f * (float) M_PI / teeth / 4.f;
-
-  glShadeModel(GL_FLAT);
-
-  glNormal3f(0.f, 0.f, 1.f);
-
-  /* draw front face */
-  glBegin(GL_QUAD_STRIP);
-  for (i = 0; i <= teeth; i++) {
-    angle = i * 2.f * (float) M_PI / teeth;
-    glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f);
-    glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f);
-    if (i < teeth) {
-      glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f);
-      glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f);
-    }
-  }
-  glEnd();
-
-  /* draw front sides of teeth */
-  glBegin(GL_QUADS);
-  da = 2.f * (float) M_PI / teeth / 4.f;
-  for (i = 0; i < teeth; i++) {
-    angle = i * 2.f * (float) M_PI / teeth;
-
-    glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f);
-    glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f);
-    glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f);
-    glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f);
-  }
-  glEnd();
-
-  glNormal3f(0.0, 0.0, -1.0);
-
-  /* draw back face */
-  glBegin(GL_QUAD_STRIP);
-  for (i = 0; i <= teeth; i++) {
-    angle = i * 2.f * (float) M_PI / teeth;
-    glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f);
-    glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f);
-    if (i < teeth) {
-      glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f);
-      glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f);
-    }
-  }
-  glEnd();
-
-  /* draw back sides of teeth */
-  glBegin(GL_QUADS);
-  da = 2.f * (float) M_PI / teeth / 4.f;
-  for (i = 0; i < teeth; i++) {
-    angle = i * 2.f * (float) M_PI / teeth;
-
-    glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f);
-    glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f);
-    glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f);
-    glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f);
-  }
-  glEnd();
-
-  /* draw outward faces of teeth */
-  glBegin(GL_QUAD_STRIP);
-  for (i = 0; i < teeth; i++) {
-    angle = i * 2.f * (float) M_PI / teeth;
-
-    glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f);
-    glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f);
-    u = r2 * (float) cos(angle + da) - r1 * (float) cos(angle);
-    v = r2 * (float) sin(angle + da) - r1 * (float) sin(angle);
-    len = (float) sqrt(u * u + v * v);
-    u /= len;
-    v /= len;
-    glNormal3f(v, -u, 0.0);
-    glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f);
-    glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f);
-    glNormal3f((float) cos(angle), (float) sin(angle), 0.f);
-    glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f);
-    glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f);
-    u = r1 * (float) cos(angle + 3 * da) - r2 * (float) cos(angle + 2 * da);
-    v = r1 * (float) sin(angle + 3 * da) - r2 * (float) sin(angle + 2 * da);
-    glNormal3f(v, -u, 0.f);
-    glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f);
-    glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f);
-    glNormal3f((float) cos(angle), (float) sin(angle), 0.f);
-  }
-
-  glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), width * 0.5f);
-  glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), -width * 0.5f);
-
-  glEnd();
-
-  glShadeModel(GL_SMOOTH);
-
-  /* draw inside radius cylinder */
-  glBegin(GL_QUAD_STRIP);
-  for (i = 0; i <= teeth; i++) {
-    angle = i * 2.f * (float) M_PI / teeth;
-    glNormal3f(-(float) cos(angle), -(float) sin(angle), 0.f);
-    glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f);
-    glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f);
-  }
-  glEnd();
-
-}
-
-
-static GLfloat view_rotx = 20.f, view_roty = 30.f, view_rotz = 0.f;
-static GLint gear1, gear2, gear3;
-static GLfloat angle = 0.f;
-
-/* OpenGL draw function & timing */
-static void draw(void)
-{
-  glClearColor(0.0, 0.0, 0.0, 0.0);
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-  glPushMatrix();
-    glRotatef(view_rotx, 1.0, 0.0, 0.0);
-    glRotatef(view_roty, 0.0, 1.0, 0.0);
-    glRotatef(view_rotz, 0.0, 0.0, 1.0);
-
-    glPushMatrix();
-      glTranslatef(-3.0, -2.0, 0.0);
-      glRotatef(angle, 0.0, 0.0, 1.0);
-      glCallList(gear1);
-    glPopMatrix();
-
-    glPushMatrix();
-      glTranslatef(3.1f, -2.f, 0.f);
-      glRotatef(-2.f * angle - 9.f, 0.f, 0.f, 1.f);
-      glCallList(gear2);
-    glPopMatrix();
-
-    glPushMatrix();
-      glTranslatef(-3.1f, 4.2f, 0.f);
-      glRotatef(-2.f * angle - 25.f, 0.f, 0.f, 1.f);
-      glCallList(gear3);
-    glPopMatrix();
-
-  glPopMatrix();
-}
-
-
-/* update animation parameters */
-static void animate(void)
-{
-  angle = 100.f * (float) glfwGetTime();
-}
-
-
-/* change view angle, exit upon ESC */
-void key( GLFWwindow* window, int k, int s, int action, int mods )
-{
-  if( action != GLFW_PRESS ) return;
-
-  switch (k) {
-  case GLFW_KEY_Z:
-    if( mods & GLFW_MOD_SHIFT )
-      view_rotz -= 5.0;
-    else
-      view_rotz += 5.0;
-    break;
-  case GLFW_KEY_ESCAPE:
-    glfwSetWindowShouldClose(window, GLFW_TRUE);
-    break;
-  case GLFW_KEY_UP:
-    view_rotx += 5.0;
-    break;
-  case GLFW_KEY_DOWN:
-    view_rotx -= 5.0;
-    break;
-  case GLFW_KEY_LEFT:
-    view_roty += 5.0;
-    break;
-  case GLFW_KEY_RIGHT:
-    view_roty -= 5.0;
-    break;
-  default:
-    return;
-  }
-}
-
-
-/* new window size */
-void reshape( GLFWwindow* window, int width, int height )
-{
-  GLfloat h = (GLfloat) height / (GLfloat) width;
-  GLfloat xmax, znear, zfar;
-
-  znear = 5.0f;
-  zfar  = 30.0f;
-  xmax  = znear * 0.5f;
-
-  glViewport( 0, 0, (GLint) width, (GLint) height );
-  glMatrixMode( GL_PROJECTION );
-  glLoadIdentity();
-  glFrustum( -xmax, xmax, -xmax*h, xmax*h, znear, zfar );
-  glMatrixMode( GL_MODELVIEW );
-  glLoadIdentity();
-  glTranslatef( 0.0, 0.0, -20.0 );
-}
-
-
-/* program & OpenGL initialization */
-static void init(void)
-{
-  static GLfloat pos[4] = {5.f, 5.f, 10.f, 0.f};
-  static GLfloat red[4] = {0.8f, 0.1f, 0.f, 1.f};
-  static GLfloat green[4] = {0.f, 0.8f, 0.2f, 1.f};
-  static GLfloat blue[4] = {0.2f, 0.2f, 1.f, 1.f};
-
-  glLightfv(GL_LIGHT0, GL_POSITION, pos);
-  glEnable(GL_CULL_FACE);
-  glEnable(GL_LIGHTING);
-  glEnable(GL_LIGHT0);
-  glEnable(GL_DEPTH_TEST);
-
-  /* make the gears */
-  gear1 = glGenLists(1);
-  glNewList(gear1, GL_COMPILE);
-  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
-  gear(1.f, 4.f, 1.f, 20, 0.7f);
-  glEndList();
-
-  gear2 = glGenLists(1);
-  glNewList(gear2, GL_COMPILE);
-  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
-  gear(0.5f, 2.f, 2.f, 10, 0.7f);
-  glEndList();
-
-  gear3 = glGenLists(1);
-  glNewList(gear3, GL_COMPILE);
-  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
-  gear(1.3f, 2.f, 0.5f, 10, 0.7f);
-  glEndList();
-
-  glEnable(GL_NORMALIZE);
-}
-
-
-/* program entry */
-int main(int argc, char *argv[])
-{
-    GLFWwindow* window;
-    int width, height;
-
-    if( !glfwInit() )
-    {
-        fprintf( stderr, "Failed to initialize GLFW\n" );
-        exit( EXIT_FAILURE );
-    }
-
-    glfwWindowHint(GLFW_DEPTH_BITS, 16);
-    glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
-
-    window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
-    if (!window)
-    {
-        fprintf( stderr, "Failed to open GLFW window\n" );
-        glfwTerminate();
-        exit( EXIT_FAILURE );
-    }
-
-    // Set callback functions
-    glfwSetFramebufferSizeCallback(window, reshape);
-    glfwSetKeyCallback(window, key);
-
-    glfwMakeContextCurrent(window);
-    gladLoadGL(glfwGetProcAddress);
-    glfwSwapInterval( 1 );
-
-    glfwGetFramebufferSize(window, &width, &height);
-    reshape(window, width, height);
-
-    // Parse command-line options
-    init();
-
-    // Main loop
-    while( !glfwWindowShouldClose(window) )
-    {
-        // Draw gears
-        draw();
-
-        // Update animation
-        animate();
-
-        // Swap buffers
-        glfwSwapBuffers(window);
-        glfwPollEvents();
-    }
-
-    // Terminate GLFW
-    glfwTerminate();
-
-    // Exit program
-    exit( EXIT_SUCCESS );
-}
-

BIN
samples/third_party/glfw/examples/glfw.icns


BIN
samples/third_party/glfw/examples/glfw.ico


+ 0 - 3
samples/third_party/glfw/examples/glfw.rc

@@ -1,3 +0,0 @@
-
-GLFW_ICON               ICON            "glfw.ico"
-

+ 0 - 512
samples/third_party/glfw/examples/heightmap.c

@@ -1,512 +0,0 @@
-//========================================================================
-// Heightmap example program using OpenGL 3 core profile
-// Copyright (c) 2010 Olivier Delannoy
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <assert.h>
-#include <stddef.h>
-
-#include <glad/gl.h>
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-/* Map height updates */
-#define MAX_CIRCLE_SIZE (5.0f)
-#define MAX_DISPLACEMENT (1.0f)
-#define DISPLACEMENT_SIGN_LIMIT (0.3f)
-#define MAX_ITER (200)
-#define NUM_ITER_AT_A_TIME (1)
-
-/* Map general information */
-#define MAP_SIZE (10.0f)
-#define MAP_NUM_VERTICES (80)
-#define MAP_NUM_TOTAL_VERTICES (MAP_NUM_VERTICES*MAP_NUM_VERTICES)
-#define MAP_NUM_LINES (3* (MAP_NUM_VERTICES - 1) * (MAP_NUM_VERTICES - 1) + \
-               2 * (MAP_NUM_VERTICES - 1))
-
-
-/**********************************************************************
- * Default shader programs
- *********************************************************************/
-
-static const char* vertex_shader_text =
-"#version 150\n"
-"uniform mat4 project;\n"
-"uniform mat4 modelview;\n"
-"in float x;\n"
-"in float y;\n"
-"in float z;\n"
-"\n"
-"void main()\n"
-"{\n"
-"   gl_Position = project * modelview * vec4(x, y, z, 1.0);\n"
-"}\n";
-
-static const char* fragment_shader_text =
-"#version 150\n"
-"out vec4 color;\n"
-"void main()\n"
-"{\n"
-"    color = vec4(0.2, 1.0, 0.2, 1.0); \n"
-"}\n";
-
-/**********************************************************************
- * Values for shader uniforms
- *********************************************************************/
-
-/* Frustum configuration */
-static GLfloat view_angle = 45.0f;
-static GLfloat aspect_ratio = 4.0f/3.0f;
-static GLfloat z_near = 1.0f;
-static GLfloat z_far = 100.f;
-
-/* Projection matrix */
-static GLfloat projection_matrix[16] = {
-    1.0f, 0.0f, 0.0f, 0.0f,
-    0.0f, 1.0f, 0.0f, 0.0f,
-    0.0f, 0.0f, 1.0f, 0.0f,
-    0.0f, 0.0f, 0.0f, 1.0f
-};
-
-/* Model view matrix */
-static GLfloat modelview_matrix[16] = {
-    1.0f, 0.0f, 0.0f, 0.0f,
-    0.0f, 1.0f, 0.0f, 0.0f,
-    0.0f, 0.0f, 1.0f, 0.0f,
-    0.0f, 0.0f, 0.0f, 1.0f
-};
-
-/**********************************************************************
- * Heightmap vertex and index data
- *********************************************************************/
-
-static GLfloat map_vertices[3][MAP_NUM_TOTAL_VERTICES];
-static GLuint  map_line_indices[2*MAP_NUM_LINES];
-
-/* Store uniform location for the shaders
- * Those values are setup as part of the process of creating
- * the shader program. They should not be used before creating
- * the program.
- */
-static GLuint mesh;
-static GLuint mesh_vbo[4];
-
-/**********************************************************************
- * OpenGL helper functions
- *********************************************************************/
-
-/* Creates a shader object of the specified type using the specified text
- */
-static GLuint make_shader(GLenum type, const char* text)
-{
-    GLuint shader;
-    GLint shader_ok;
-    GLsizei log_length;
-    char info_log[8192];
-
-    shader = glCreateShader(type);
-    if (shader != 0)
-    {
-        glShaderSource(shader, 1, (const GLchar**)&text, NULL);
-        glCompileShader(shader);
-        glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
-        if (shader_ok != GL_TRUE)
-        {
-            fprintf(stderr, "ERROR: Failed to compile %s shader\n", (type == GL_FRAGMENT_SHADER) ? "fragment" : "vertex" );
-            glGetShaderInfoLog(shader, 8192, &log_length,info_log);
-            fprintf(stderr, "ERROR: \n%s\n\n", info_log);
-            glDeleteShader(shader);
-            shader = 0;
-        }
-    }
-    return shader;
-}
-
-/* Creates a program object using the specified vertex and fragment text
- */
-static GLuint make_shader_program(const char* vs_text, const char* fs_text)
-{
-    GLuint program = 0u;
-    GLint program_ok;
-    GLuint vertex_shader = 0u;
-    GLuint fragment_shader = 0u;
-    GLsizei log_length;
-    char info_log[8192];
-
-    vertex_shader = make_shader(GL_VERTEX_SHADER, vs_text);
-    if (vertex_shader != 0u)
-    {
-        fragment_shader = make_shader(GL_FRAGMENT_SHADER, fs_text);
-        if (fragment_shader != 0u)
-        {
-            /* make the program that connect the two shader and link it */
-            program = glCreateProgram();
-            if (program != 0u)
-            {
-                /* attach both shader and link */
-                glAttachShader(program, vertex_shader);
-                glAttachShader(program, fragment_shader);
-                glLinkProgram(program);
-                glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
-
-                if (program_ok != GL_TRUE)
-                {
-                    fprintf(stderr, "ERROR, failed to link shader program\n");
-                    glGetProgramInfoLog(program, 8192, &log_length, info_log);
-                    fprintf(stderr, "ERROR: \n%s\n\n", info_log);
-                    glDeleteProgram(program);
-                    glDeleteShader(fragment_shader);
-                    glDeleteShader(vertex_shader);
-                    program = 0u;
-                }
-            }
-        }
-        else
-        {
-            fprintf(stderr, "ERROR: Unable to load fragment shader\n");
-            glDeleteShader(vertex_shader);
-        }
-    }
-    else
-    {
-        fprintf(stderr, "ERROR: Unable to load vertex shader\n");
-    }
-    return program;
-}
-
-/**********************************************************************
- * Geometry creation functions
- *********************************************************************/
-
-/* Generate vertices and indices for the heightmap
- */
-static void init_map(void)
-{
-    int i;
-    int j;
-    int k;
-    GLfloat step = MAP_SIZE / (MAP_NUM_VERTICES - 1);
-    GLfloat x = 0.0f;
-    GLfloat z = 0.0f;
-    /* Create a flat grid */
-    k = 0;
-    for (i = 0 ; i < MAP_NUM_VERTICES ; ++i)
-    {
-        for (j = 0 ; j < MAP_NUM_VERTICES ; ++j)
-        {
-            map_vertices[0][k] = x;
-            map_vertices[1][k] = 0.0f;
-            map_vertices[2][k] = z;
-            z += step;
-            ++k;
-        }
-        x += step;
-        z = 0.0f;
-    }
-#if DEBUG_ENABLED
-    for (i = 0 ; i < MAP_NUM_TOTAL_VERTICES ; ++i)
-    {
-        printf ("Vertice %d (%f, %f, %f)\n",
-                i, map_vertices[0][i], map_vertices[1][i], map_vertices[2][i]);
-
-    }
-#endif
-    /* create indices */
-    /* line fan based on i
-     * i+1
-     * |  / i + n + 1
-     * | /
-     * |/
-     * i --- i + n
-     */
-
-    /* close the top of the square */
-    k = 0;
-    for (i = 0 ; i < MAP_NUM_VERTICES  -1 ; ++i)
-    {
-        map_line_indices[k++] = (i + 1) * MAP_NUM_VERTICES -1;
-        map_line_indices[k++] = (i + 2) * MAP_NUM_VERTICES -1;
-    }
-    /* close the right of the square */
-    for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i)
-    {
-        map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i;
-        map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i + 1;
-    }
-
-    for (i = 0 ; i < (MAP_NUM_VERTICES - 1) ; ++i)
-    {
-        for (j = 0 ; j < (MAP_NUM_VERTICES - 1) ; ++j)
-        {
-            int ref = i * (MAP_NUM_VERTICES) + j;
-            map_line_indices[k++] = ref;
-            map_line_indices[k++] = ref + 1;
-
-            map_line_indices[k++] = ref;
-            map_line_indices[k++] = ref + MAP_NUM_VERTICES;
-
-            map_line_indices[k++] = ref;
-            map_line_indices[k++] = ref + MAP_NUM_VERTICES + 1;
-        }
-    }
-
-#ifdef DEBUG_ENABLED
-    for (k = 0 ; k < 2 * MAP_NUM_LINES ; k += 2)
-    {
-        int beg, end;
-        beg = map_line_indices[k];
-        end = map_line_indices[k+1];
-        printf ("Line %d: %d -> %d (%f, %f, %f) -> (%f, %f, %f)\n",
-                k / 2, beg, end,
-                map_vertices[0][beg], map_vertices[1][beg], map_vertices[2][beg],
-                map_vertices[0][end], map_vertices[1][end], map_vertices[2][end]);
-    }
-#endif
-}
-
-static void generate_heightmap__circle(float* center_x, float* center_y,
-        float* size, float* displacement)
-{
-    float sign;
-    /* random value for element in between [0-1.0] */
-    *center_x = (MAP_SIZE * rand()) / (float) RAND_MAX;
-    *center_y = (MAP_SIZE * rand()) / (float) RAND_MAX;
-    *size = (MAX_CIRCLE_SIZE * rand()) / (float) RAND_MAX;
-    sign = (1.0f * rand()) / (float) RAND_MAX;
-    sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f;
-    *displacement = (sign * (MAX_DISPLACEMENT * rand())) / (float) RAND_MAX;
-}
-
-/* Run the specified number of iterations of the generation process for the
- * heightmap
- */
-static void update_map(int num_iter)
-{
-    assert(num_iter > 0);
-    while(num_iter)
-    {
-        /* center of the circle */
-        float center_x;
-        float center_z;
-        float circle_size;
-        float disp;
-        size_t ii;
-        generate_heightmap__circle(&center_x, &center_z, &circle_size, &disp);
-        disp = disp / 2.0f;
-        for (ii = 0u ; ii < MAP_NUM_TOTAL_VERTICES ; ++ii)
-        {
-            GLfloat dx = center_x - map_vertices[0][ii];
-            GLfloat dz = center_z - map_vertices[2][ii];
-            GLfloat pd = (2.0f * (float) sqrt((dx * dx) + (dz * dz))) / circle_size;
-            if (fabs(pd) <= 1.0f)
-            {
-                /* tx,tz is within the circle */
-                GLfloat new_height = disp + (float) (cos(pd*3.14f)*disp);
-                map_vertices[1][ii] += new_height;
-            }
-        }
-        --num_iter;
-    }
-}
-
-/**********************************************************************
- * OpenGL helper functions
- *********************************************************************/
-
-/* Create VBO, IBO and VAO objects for the heightmap geometry and bind them to
- * the specified program object
- */
-static void make_mesh(GLuint program)
-{
-    GLuint attrloc;
-
-    glGenVertexArrays(1, &mesh);
-    glGenBuffers(4, mesh_vbo);
-    glBindVertexArray(mesh);
-    /* Prepare the data for drawing through a buffer inidices */
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_vbo[3]);
-    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* MAP_NUM_LINES * 2, map_line_indices, GL_STATIC_DRAW);
-
-    /* Prepare the attributes for rendering */
-    attrloc = glGetAttribLocation(program, "x");
-    glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[0]);
-    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[0][0], GL_STATIC_DRAW);
-    glEnableVertexAttribArray(attrloc);
-    glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
-
-    attrloc = glGetAttribLocation(program, "z");
-    glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[2]);
-    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[2][0], GL_STATIC_DRAW);
-    glEnableVertexAttribArray(attrloc);
-    glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
-
-    attrloc = glGetAttribLocation(program, "y");
-    glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[1]);
-    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0], GL_DYNAMIC_DRAW);
-    glEnableVertexAttribArray(attrloc);
-    glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
-}
-
-/* Update VBO vertices from source data
- */
-static void update_mesh(void)
-{
-    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0]);
-}
-
-/**********************************************************************
- * GLFW callback functions
- *********************************************************************/
-
-static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
-{
-    switch(key)
-    {
-        case GLFW_KEY_ESCAPE:
-            /* Exit program on Escape */
-            glfwSetWindowShouldClose(window, GLFW_TRUE);
-            break;
-    }
-}
-
-static void error_callback(int error, const char* description)
-{
-    fprintf(stderr, "Error: %s\n", description);
-}
-
-int main(int argc, char** argv)
-{
-    GLFWwindow* window;
-    int iter;
-    double dt;
-    double last_update_time;
-    int frame;
-    float f;
-    GLint uloc_modelview;
-    GLint uloc_project;
-    int width, height;
-
-    GLuint shader_program;
-
-    glfwSetErrorCallback(error_callback);
-
-    if (!glfwInit())
-        exit(EXIT_FAILURE);
-
-    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
-    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
-    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
-    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
-
-    window = glfwCreateWindow(800, 600, "GLFW OpenGL3 Heightmap demo", NULL, NULL);
-    if (! window )
-    {
-        glfwTerminate();
-        exit(EXIT_FAILURE);
-    }
-
-    /* Register events callback */
-    glfwSetKeyCallback(window, key_callback);
-
-    glfwMakeContextCurrent(window);
-    gladLoadGL(glfwGetProcAddress);
-
-    /* Prepare opengl resources for rendering */
-    shader_program = make_shader_program(vertex_shader_text, fragment_shader_text);
-
-    if (shader_program == 0u)
-    {
-        glfwTerminate();
-        exit(EXIT_FAILURE);
-    }
-
-    glUseProgram(shader_program);
-    uloc_project   = glGetUniformLocation(shader_program, "project");
-    uloc_modelview = glGetUniformLocation(shader_program, "modelview");
-
-    /* Compute the projection matrix */
-    f = 1.0f / tanf(view_angle / 2.0f);
-    projection_matrix[0]  = f / aspect_ratio;
-    projection_matrix[5]  = f;
-    projection_matrix[10] = (z_far + z_near)/ (z_near - z_far);
-    projection_matrix[11] = -1.0f;
-    projection_matrix[14] = 2.0f * (z_far * z_near) / (z_near - z_far);
-    glUniformMatrix4fv(uloc_project, 1, GL_FALSE, projection_matrix);
-
-    /* Set the camera position */
-    modelview_matrix[12]  = -5.0f;
-    modelview_matrix[13]  = -5.0f;
-    modelview_matrix[14]  = -20.0f;
-    glUniformMatrix4fv(uloc_modelview, 1, GL_FALSE, modelview_matrix);
-
-    /* Create mesh data */
-    init_map();
-    make_mesh(shader_program);
-
-    /* Create vao + vbo to store the mesh */
-    /* Create the vbo to store all the information for the grid and the height */
-
-    /* setup the scene ready for rendering */
-    glfwGetFramebufferSize(window, &width, &height);
-    glViewport(0, 0, width, height);
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
-    /* main loop */
-    frame = 0;
-    iter = 0;
-    last_update_time = glfwGetTime();
-
-    while (!glfwWindowShouldClose(window))
-    {
-        ++frame;
-        /* render the next frame */
-        glClear(GL_COLOR_BUFFER_BIT);
-        glDrawElements(GL_LINES, 2* MAP_NUM_LINES , GL_UNSIGNED_INT, 0);
-
-        /* display and process events through callbacks */
-        glfwSwapBuffers(window);
-        glfwPollEvents();
-        /* Check the frame rate and update the heightmap if needed */
-        dt = glfwGetTime();
-        if ((dt - last_update_time) > 0.2)
-        {
-            /* generate the next iteration of the heightmap */
-            if (iter < MAX_ITER)
-            {
-                update_map(NUM_ITER_AT_A_TIME);
-                update_mesh();
-                iter += NUM_ITER_AT_A_TIME;
-            }
-            last_update_time = dt;
-            frame = 0;
-        }
-    }
-
-    glfwTerminate();
-    exit(EXIT_SUCCESS);
-}
-

+ 0 - 177
samples/third_party/glfw/examples/offscreen.c

@@ -1,177 +0,0 @@
-//========================================================================
-// Offscreen rendering example
-// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include <glad/gl.h>
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-#if USE_NATIVE_OSMESA
- #define GLFW_EXPOSE_NATIVE_OSMESA
- #include <GLFW/glfw3native.h>
-#endif
-
-#include "linmath.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#define STB_IMAGE_WRITE_IMPLEMENTATION
-#include <stb_image_write.h>
-
-static const struct
-{
-    float x, y;
-    float r, g, b;
-} vertices[3] =
-{
-    { -0.6f, -0.4f, 1.f, 0.f, 0.f },
-    {  0.6f, -0.4f, 0.f, 1.f, 0.f },
-    {   0.f,  0.6f, 0.f, 0.f, 1.f }
-};
-
-static const char* vertex_shader_text =
-"#version 110\n"
-"uniform mat4 MVP;\n"
-"attribute vec3 vCol;\n"
-"attribute vec2 vPos;\n"
-"varying vec3 color;\n"
-"void main()\n"
-"{\n"
-"    gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
-"    color = vCol;\n"
-"}\n";
-
-static const char* fragment_shader_text =
-"#version 110\n"
-"varying vec3 color;\n"
-"void main()\n"
-"{\n"
-"    gl_FragColor = vec4(color, 1.0);\n"
-"}\n";
-
-static void error_callback(int error, const char* description)
-{
-    fprintf(stderr, "Error: %s\n", description);
-}
-
-int main(void)
-{
-    GLFWwindow* window;
-    GLuint vertex_buffer, vertex_shader, fragment_shader, program;
-    GLint mvp_location, vpos_location, vcol_location;
-    float ratio;
-    int width, height;
-    mat4x4 mvp;
-    char* buffer;
-
-    glfwSetErrorCallback(error_callback);
-
-    glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
-
-    if (!glfwInit())
-        exit(EXIT_FAILURE);
-
-    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
-    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
-
-    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
-    if (!window)
-    {
-        glfwTerminate();
-        exit(EXIT_FAILURE);
-    }
-
-    glfwMakeContextCurrent(window);
-    gladLoadGL(glfwGetProcAddress);
-
-    // NOTE: OpenGL error checks have been omitted for brevity
-
-    glGenBuffers(1, &vertex_buffer);
-    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
-    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
-    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
-    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
-    glCompileShader(vertex_shader);
-
-    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
-    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
-    glCompileShader(fragment_shader);
-
-    program = glCreateProgram();
-    glAttachShader(program, vertex_shader);
-    glAttachShader(program, fragment_shader);
-    glLinkProgram(program);
-
-    mvp_location = glGetUniformLocation(program, "MVP");
-    vpos_location = glGetAttribLocation(program, "vPos");
-    vcol_location = glGetAttribLocation(program, "vCol");
-
-    glEnableVertexAttribArray(vpos_location);
-    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
-                          sizeof(vertices[0]), (void*) 0);
-    glEnableVertexAttribArray(vcol_location);
-    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
-                          sizeof(vertices[0]), (void*) (sizeof(float) * 2));
-
-    glfwGetFramebufferSize(window, &width, &height);
-    ratio = width / (float) height;
-
-    glViewport(0, 0, width, height);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    mat4x4_ortho(mvp, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
-
-    glUseProgram(program);
-    glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
-    glDrawArrays(GL_TRIANGLES, 0, 3);
-    glFinish();
-
-#if USE_NATIVE_OSMESA
-    glfwGetOSMesaColorBuffer(window, &width, &height, NULL, (void**) &buffer);
-#else
-    buffer = calloc(4, width * height);
-    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-#endif
-
-    // Write image Y-flipped because OpenGL
-    stbi_write_png("offscreen.png",
-                   width, height, 4,
-                   buffer + (width * 4 * (height - 1)),
-                   -width * 4);
-
-#if USE_NATIVE_OSMESA
-    // Here is where there's nothing
-#else
-    free(buffer);
-#endif
-
-    glfwDestroyWindow(window);
-
-    glfwTerminate();
-    exit(EXIT_SUCCESS);
-}
-

ファイルの差分が大きいため隠しています
+ 0 - 1073
samples/third_party/glfw/examples/particles.c


+ 0 - 234
samples/third_party/glfw/examples/sharing.c

@@ -1,234 +0,0 @@
-//========================================================================
-// Context sharing example
-// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include <glad/gl.h>
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "getopt.h"
-#include "linmath.h"
-
-static const char* vertex_shader_text =
-"#version 110\n"
-"uniform mat4 MVP;\n"
-"attribute vec2 vPos;\n"
-"varying vec2 texcoord;\n"
-"void main()\n"
-"{\n"
-"    gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
-"    texcoord = vPos;\n"
-"}\n";
-
-static const char* fragment_shader_text =
-"#version 110\n"
-"uniform sampler2D texture;\n"
-"uniform vec3 color;\n"
-"varying vec2 texcoord;\n"
-"void main()\n"
-"{\n"
-"    gl_FragColor = vec4(color * texture2D(texture, texcoord).rgb, 1.0);\n"
-"}\n";
-
-static const vec2 vertices[4] =
-{
-    { 0.f, 0.f },
-    { 1.f, 0.f },
-    { 1.f, 1.f },
-    { 0.f, 1.f }
-};
-
-static void error_callback(int error, const char* description)
-{
-    fprintf(stderr, "Error: %s\n", description);
-}
-
-static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
-{
-    if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
-        glfwSetWindowShouldClose(window, GLFW_TRUE);
-}
-
-int main(int argc, char** argv)
-{
-    GLFWwindow* windows[2];
-    GLuint texture, program, vertex_buffer;
-    GLint mvp_location, vpos_location, color_location, texture_location;
-
-    glfwSetErrorCallback(error_callback);
-
-    if (!glfwInit())
-        exit(EXIT_FAILURE);
-
-    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
-    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-
-    windows[0] = glfwCreateWindow(400, 400, "First", NULL, NULL);
-    if (!windows[0])
-    {
-        glfwTerminate();
-        exit(EXIT_FAILURE);
-    }
-
-    glfwSetKeyCallback(windows[0], key_callback);
-
-    glfwMakeContextCurrent(windows[0]);
-
-    // Only enable vsync for the first of the windows to be swapped to
-    // avoid waiting out the interval for each window
-    glfwSwapInterval(1);
-
-    // The contexts are created with the same APIs so the function
-    // pointers should be re-usable between them
-    gladLoadGL(glfwGetProcAddress);
-
-    // Create the OpenGL objects inside the first context, created above
-    // All objects will be shared with the second context, created below
-    {
-        int x, y;
-        char pixels[16 * 16];
-        GLuint vertex_shader, fragment_shader;
-
-        glGenTextures(1, &texture);
-        glBindTexture(GL_TEXTURE_2D, texture);
-
-        srand((unsigned int) glfwGetTimerValue());
-
-        for (y = 0;  y < 16;  y++)
-        {
-            for (x = 0;  x < 16;  x++)
-                pixels[y * 16 + x] = rand() % 256;
-        }
-
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-        vertex_shader = glCreateShader(GL_VERTEX_SHADER);
-        glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
-        glCompileShader(vertex_shader);
-
-        fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
-        glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
-        glCompileShader(fragment_shader);
-
-        program = glCreateProgram();
-        glAttachShader(program, vertex_shader);
-        glAttachShader(program, fragment_shader);
-        glLinkProgram(program);
-
-        mvp_location = glGetUniformLocation(program, "MVP");
-        color_location = glGetUniformLocation(program, "color");
-        texture_location = glGetUniformLocation(program, "texture");
-        vpos_location = glGetAttribLocation(program, "vPos");
-
-        glGenBuffers(1, &vertex_buffer);
-        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
-        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-    }
-
-    glUseProgram(program);
-    glUniform1i(texture_location, 0);
-
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, texture);
-
-    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
-    glEnableVertexAttribArray(vpos_location);
-    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
-                          sizeof(vertices[0]), (void*) 0);
-
-    windows[1] = glfwCreateWindow(400, 400, "Second", NULL, windows[0]);
-    if (!windows[1])
-    {
-        glfwTerminate();
-        exit(EXIT_FAILURE);
-    }
-
-    // Place the second window to the right of the first
-    {
-        int xpos, ypos, left, right, width;
-
-        glfwGetWindowSize(windows[0], &width, NULL);
-        glfwGetWindowFrameSize(windows[0], &left, NULL, &right, NULL);
-        glfwGetWindowPos(windows[0], &xpos, &ypos);
-
-        glfwSetWindowPos(windows[1], xpos + width + left + right, ypos);
-    }
-
-    glfwSetKeyCallback(windows[1], key_callback);
-
-    glfwMakeContextCurrent(windows[1]);
-
-    // While objects are shared, the global context state is not and will
-    // need to be set up for each context
-
-    glUseProgram(program);
-
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, texture);
-
-    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
-    glEnableVertexAttribArray(vpos_location);
-    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
-                          sizeof(vertices[0]), (void*) 0);
-
-    while (!glfwWindowShouldClose(windows[0]) &&
-           !glfwWindowShouldClose(windows[1]))
-    {
-        int i;
-        const vec3 colors[2] =
-        {
-            { 0.8f, 0.4f, 1.f },
-            { 0.3f, 0.4f, 1.f }
-        };
-
-        for (i = 0;  i < 2;  i++)
-        {
-            int width, height;
-            mat4x4 mvp;
-
-            glfwGetFramebufferSize(windows[i], &width, &height);
-            glfwMakeContextCurrent(windows[i]);
-
-            glViewport(0, 0, width, height);
-
-            mat4x4_ortho(mvp, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f);
-            glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
-            glUniform3fv(color_location, 1, colors[i]);
-            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-            glfwSwapBuffers(windows[i]);
-        }
-
-        glfwWaitEvents();
-    }
-
-    glfwTerminate();
-    exit(EXIT_SUCCESS);
-}
-

+ 0 - 0
samples/third_party/glfw/examples/simple.c


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません