From 99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c Mon Sep 17 00:00:00 2001 From: lbavoil Date: Fri, 25 Mar 2016 13:01:54 +0100 Subject: GFSDK_HBAO+_distro_r3.0_cl20573789 --- build/platforms/vs2015/GFSDK_SSAO.sln | 145 + build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj | 121 + .../vs2015/GFSDK_SSAO_D3D11.vcxproj.filters | 108 + .../platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj | 122 + .../vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj.filters | 108 + build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj | 123 + .../vs2015/GFSDK_SSAO_D3D12.vcxproj.filters | 114 + .../platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj | 123 + .../vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj.filters | 111 + build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj | 126 + .../platforms/vs2015/GFSDK_SSAO_GL.vcxproj.filters | 117 + .../vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj | 346 + .../GFSDK_SSAO_Shaders_D3D11.vcxproj.filters | 54 + .../platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj | 304 + .../vs2015/GFSDK_SSAO_Shaders_GL.vcxproj.filters | 45 + build/tools/HLSLcc/May_2014/.gitattributes | 22 + build/tools/HLSLcc/May_2014/.gitignore | 69 + build/tools/HLSLcc/May_2014/include/hlslcc.h | 451 + build/tools/HLSLcc/May_2014/include/hlslcc.hpp | 5 + build/tools/HLSLcc/May_2014/include/pstdint.h | 800 + build/tools/HLSLcc/May_2014/license.txt | 52 + build/tools/HLSLcc/May_2014/mk/CMakeLists.txt | 117 + build/tools/HLSLcc/May_2014/offline/cjson/cJSON.c | 567 + build/tools/HLSLcc/May_2014/offline/cjson/cJSON.h | 141 + build/tools/HLSLcc/May_2014/offline/hash.h | 125 + .../May_2014/offline/serializeReflection.cpp | 204 + .../HLSLcc/May_2014/offline/serializeReflection.h | 8 + build/tools/HLSLcc/May_2014/offline/timer.cpp | 37 + build/tools/HLSLcc/May_2014/offline/timer.h | 26 + .../HLSLcc/May_2014/offline/toGLSLStandalone.cpp | 677 + build/tools/HLSLcc/May_2014/src/cbstring/bsafe.c | 85 + build/tools/HLSLcc/May_2014/src/cbstring/bsafe.h | 43 + build/tools/HLSLcc/May_2014/src/cbstring/bstraux.c | 1133 + build/tools/HLSLcc/May_2014/src/cbstring/bstraux.h | 112 + build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.c | 2975 + build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.h | 304 + .../tools/HLSLcc/May_2014/src/cbstring/bstrlib.txt | 3201 + build/tools/HLSLcc/May_2014/src/cbstring/gpl.txt | 339 + .../tools/HLSLcc/May_2014/src/cbstring/license.txt | 29 + .../tools/HLSLcc/May_2014/src/cbstring/porting.txt | 172 + .../HLSLcc/May_2014/src/cbstring/security.txt | 221 + build/tools/HLSLcc/May_2014/src/decode.c | 1640 + build/tools/HLSLcc/May_2014/src/decodeDX9.c | 1146 + .../HLSLcc/May_2014/src/internal_includes/debug.h | 18 + .../HLSLcc/May_2014/src/internal_includes/decode.h | 15 + .../May_2014/src/internal_includes/hlslcc_malloc.c | 6 + .../May_2014/src/internal_includes/hlslcc_malloc.h | 12 + .../May_2014/src/internal_includes/languages.h | 202 + .../May_2014/src/internal_includes/reflect.h | 67 + .../May_2014/src/internal_includes/shaderLimits.h | 13 + .../May_2014/src/internal_includes/structs.h | 273 + .../src/internal_includes/toGLSLDeclaration.h | 16 + .../src/internal_includes/toGLSLInstruction.h | 15 + .../May_2014/src/internal_includes/toGLSLOperand.h | 31 + .../HLSLcc/May_2014/src/internal_includes/tokens.h | 798 + .../May_2014/src/internal_includes/tokensDX9.h | 301 + build/tools/HLSLcc/May_2014/src/reflect.c | 1085 + build/tools/HLSLcc/May_2014/src/toGLSL.c | 900 + .../tools/HLSLcc/May_2014/src/toGLSLDeclaration.c | 2436 + .../tools/HLSLcc/May_2014/src/toGLSLInstruction.c | 4305 + build/tools/HLSLcc/May_2014/src/toGLSLOperand.c | 1557 + build/tools/ShaderBuildTool/ShaderBuildTool.cpp | 388 + build/tools/ShaderBuildTool/ShaderBuildTool.sln | 28 + .../tools/ShaderBuildTool/ShaderBuildTool.vcxproj | 168 + .../ShaderBuildTool.vcxproj.filters | 33 + build/tools/ShaderBuildTool/stdafx.cpp | 8 + build/tools/ShaderBuildTool/stdafx.h | 19 + build/tools/ShaderBuildTool/targetver.h | 8 + build/tools/Stringify/Stringify.cpp | 49 + build/tools/Stringify/Stringify.sln | 20 + build/tools/Stringify/Stringify.vcxproj | 93 + build/tools/Stringify/Stringify.vcxproj.filters | 33 + build/tools/Stringify/stdafx.cpp | 8 + build/tools/Stringify/stdafx.h | 19 + build/tools/Stringify/targetver.h | 8 + doc/.buildinfo | 4 + doc/_images/AOBias_0_0.png | Bin 0 -> 267815 bytes doc/_images/AOBias_0_3.png | Bin 0 -> 209374 bytes doc/_images/AO_Radius_1.png | Bin 0 -> 207119 bytes doc/_images/AO_Radius_4.png | Bin 0 -> 239925 bytes doc/_images/BackgroundAO_OFF.png | Bin 0 -> 411299 bytes doc/_images/BackgroundAO_ON.png | Bin 0 -> 436356 bytes doc/_images/Blur_Radius_4.png | Bin 0 -> 263060 bytes doc/_images/Blur_Sharpness_0.png | Bin 0 -> 195443 bytes doc/_images/Blur_Sharpness_8.png | Bin 0 -> 241658 bytes doc/_images/ForegroundAO_OFF.png | Bin 0 -> 411362 bytes doc/_images/ForegroundAO_ON.png | Bin 0 -> 402565 bytes doc/_images/No_Blur.png | Bin 0 -> 368923 bytes ...us-in-tom-clancys-splinter-cell-blacklist-2.jpg | Bin 0 -> 147837 bytes doc/_images/pipeline_with_input_normals.png | Bin 0 -> 95828 bytes doc/_images/pipeline_without_input_normals.png | Bin 0 -> 83534 bytes doc/_sources/changelog.txt | 95 + doc/_sources/index.txt | 37 + doc/_sources/product.txt | 294 + doc/_sources/releasenotes.txt | 35 + .../Sphinx-1.2.dist-info/DESCRIPTION.txt | 31 + .../setuptools-2.1.dist-info/DESCRIPTION.txt | 1742 + .../ext/autosummary/templates/autosummary/base.txt | 6 + .../autosummary/templates/autosummary/class.txt | 30 + .../autosummary/templates/autosummary/module.txt | 37 + .../tests/roots/test-only-directive/contents.txt | 6 + .../tests/roots/test-only-directive/only.txt | 203 + doc/_static/AOBias_0_0.png | Bin 0 -> 267815 bytes doc/_static/AOBias_0_3.png | Bin 0 -> 209374 bytes doc/_static/AO_Radius_1.png | Bin 0 -> 207119 bytes doc/_static/AO_Radius_4.png | Bin 0 -> 239925 bytes doc/_static/BackgroundAO_OFF.png | Bin 0 -> 411299 bytes doc/_static/BackgroundAO_ON.png | Bin 0 -> 436356 bytes doc/_static/Blur_Radius_4.png | Bin 0 -> 263060 bytes doc/_static/Blur_Sharpness_0.png | Bin 0 -> 195443 bytes doc/_static/Blur_Sharpness_8.png | Bin 0 -> 241658 bytes doc/_static/DINWebPro-Black.woff | Bin 0 -> 51992 bytes doc/_static/DINWebPro-BlackIta.woff | Bin 0 -> 48080 bytes doc/_static/DINWebPro-Bold.woff | Bin 0 -> 52552 bytes doc/_static/DINWebPro-BoldIta.woff | Bin 0 -> 47636 bytes doc/_static/DINWebPro-Ita.woff | Bin 0 -> 49144 bytes doc/_static/DINWebPro-Light.woff | Bin 0 -> 51236 bytes doc/_static/DINWebPro-LightIta.woff | Bin 0 -> 47388 bytes doc/_static/DINWebPro-Medium.woff | Bin 0 -> 52420 bytes doc/_static/DINWebPro-MediumIta.woff | Bin 0 -> 48704 bytes doc/_static/DINWebPro.woff | Bin 0 -> 53444 bytes doc/_static/ForegroundAO_OFF.png | Bin 0 -> 411362 bytes doc/_static/ForegroundAO_ON.png | Bin 0 -> 402565 bytes doc/_static/No_Blur.png | Bin 0 -> 368923 bytes doc/_static/application.css | 8998 +++ doc/_static/bootstrap.css | 6167 ++ doc/_static/bootstrap.js | 2280 + doc/_static/default.css | 55 + doc/_static/developerzone_gameworks_logo.png | Bin 0 -> 4123 bytes doc/_static/doctools.js | 235 + ...us-in-tom-clancys-splinter-cell-blacklist-2.jpg | Bin 0 -> 147837 bytes doc/_static/jquery.js | 2 + doc/_static/minus.gif | Bin 0 -> 837 bytes doc/_static/nvidia-logo-header.png | Bin 0 -> 2673 bytes doc/_static/pipeline_with_input_normals.png | Bin 0 -> 95828 bytes doc/_static/pipeline_without_input_normals.png | Bin 0 -> 83534 bytes doc/_static/plus.gif | Bin 0 -> 841 bytes doc/_static/pygments.css | 62 + doc/_static/searchtools.js | 622 + doc/_static/sidebar.js | 159 + doc/_static/space.gif | Bin 0 -> 42 bytes doc/_static/styleguide.css | 102 + doc/_static/underscore.js | 31 + doc/changelog.html | 239 + doc/genindex.html | 160 + doc/index.html | 172 + doc/objects.inv | 8 + doc/product.html | 403 + doc/releasenotes.html | 171 + doc/search.html | 165 + doc/searchindex.js | 1 + .../Sphinx-1.2.dist-info/DESCRIPTION.html | 176 + .../setuptools-2.1.dist-info/DESCRIPTION.html | 1957 + .../autosummary/templates/autosummary/base.html | 152 + .../autosummary/templates/autosummary/class.html | 152 + .../autosummary/templates/autosummary/module.html | 152 + .../tests/roots/test-only-directive/contents.html | 224 + .../tests/roots/test-only-directive/only.html | 292 + include/GFSDK_SSAO.h | 1390 + lib/GFSDK_SSAO.h | 1390 + .../AntTweakBar/1.16/include/AntTweakBar.h | 386 + samples/D3D11/media/directx.ico | Bin 0 -> 25214 bytes samples/D3D11/src/BinMeshReader.h | 81 + samples/D3D11/src/DeviceManager.cpp | 608 + samples/D3D11/src/DeviceManager.h | 150 + samples/D3D11/src/GPUTimers.cpp | 133 + samples/D3D11/src/GPUTimers.h | 68 + samples/D3D11/src/InputDumpReader.h | 539 + samples/D3D11/src/InputDumpWriter.h | 265 + samples/D3D11/src/SSAO11.cpp | 598 + samples/D3D11/src/SSAO11.manifest | 22 + samples/D3D11/src/SSAO11.rc | 72 + samples/D3D11/src/SSAO11_2015.sln | 22 + samples/D3D11/src/SSAO11_2015.vcxproj | 451 + samples/D3D11/src/SSAO11_2015.vcxproj.filters | 25 + samples/D3D11/src/SceneRTs.h | 196 + samples/D3D11/src/SibenikIndices.bin | Bin 0 -> 939564 bytes samples/D3D11/src/SibenikVertices.bin | Bin 0 -> 1189884 bytes samples/D3D11/src/shaders/bin/CopyColorPS.h | 168 + .../D3D11/src/shaders/bin/FullScreenTriangleVS.h | 168 + samples/D3D11/src/shaders/bin/GeometryPS.h | 315 + samples/D3D11/src/shaders/bin/GeometryVS.h | 293 + samples/D3D11/src/shaders/compile.bat | 15 + samples/D3D11/src/shaders/src/Scene3D.hlsl | 122 + samples/D3D12/external/imgui/.travis.yml | 17 + samples/D3D12/external/imgui/README.md | 152 + .../directx12_example/directx12_example.vcxproj | 156 + .../directx12_example.vcxproj.filters | 42 + .../examples/directx12_example/imgui_impl_dx12.cpp | 826 + .../examples/directx12_example/imgui_impl_dx12.h | 23 + .../imgui/examples/directx12_example/main.cpp | 225 + .../external/imgui/extra_fonts/Cousine-Regular.ttf | Bin 0 -> 43912 bytes .../D3D12/external/imgui/extra_fonts/DroidSans.ttf | Bin 0 -> 190044 bytes .../external/imgui/extra_fonts/Karla-Regular.ttf | Bin 0 -> 16848 bytes .../external/imgui/extra_fonts/ProggyClean.ttf | Bin 0 -> 41208 bytes .../external/imgui/extra_fonts/ProggyTiny.ttf | Bin 0 -> 35656 bytes .../D3D12/external/imgui/extra_fonts/README.txt | 116 + .../imgui/extra_fonts/binary_to_compressed_c.cpp | 364 + samples/D3D12/external/imgui/imconfig.h | 56 + samples/D3D12/external/imgui/imgui.cpp | 8920 ++ samples/D3D12/external/imgui/imgui.h | 1250 + samples/D3D12/external/imgui/imgui_demo.cpp | 2048 + samples/D3D12/external/imgui/imgui_draw.cpp | 2108 + samples/D3D12/external/imgui/imgui_internal.h | 664 + samples/D3D12/external/imgui/stb_rect_pack.h | 547 + samples/D3D12/external/imgui/stb_textedit.h | 1261 + samples/D3D12/external/imgui/stb_truetype.h | 3221 + samples/D3D12/src/BinMeshReader.h | 60 + samples/D3D12/src/SSAO12_2015.sln | 28 + samples/D3D12/src/SibenikIndices.bin | Bin 0 -> 939564 bytes samples/D3D12/src/SibenikVertices.bin | Bin 0 -> 1189884 bytes samples/D3D12/src/Viewer.cpp | 1216 + samples/D3D12/src/Viewer.hlsl | 40 + samples/D3D12/src/Viewer.vcxproj | 229 + samples/D3D12/src/Viewer.vcxproj.filters | 57 + samples/D3D12/src/WaveFrontReader.h | 541 + samples/D3D12/src/d3dx12.h | 1508 + samples/D3D12/src/d3dx12p.h | 1590 + src/API.cpp | 240 + src/AppState_DX11.cpp | 91 + src/AppState_DX11.h | 73 + src/AppState_GL.cpp | 104 + src/AppState_GL.h | 88 + src/BuildVersion.h | 51 + src/Common.h | 77 + src/Common_DX12.h | 253 + src/Common_GL.h | 1318 + src/ConstantBuffers.cpp | 189 + src/ConstantBuffers.h | 496 + src/GLSLProgram.h | 233 + src/InputDepthInfo.h | 178 + src/InputNormalInfo.h | 129 + src/InputViewport.h | 131 + src/MathUtil.h | 83 + src/MatrixView.h | 47 + src/OutputInfo.h | 170 + src/PerfMarkers.h | 88 + src/PipelineStateObjects_DX12.cpp | 621 + src/PipelineStateObjects_DX12.h | 601 + src/ProjectionMatrixInfo.cpp | 63 + src/ProjectionMatrixInfo.h | 72 + src/RandomTexture.cpp | 184 + src/RandomTexture.h | 90 + src/RenderOptions.h | 41 + src/RenderTargets_DX11.h | 324 + src/RenderTargets_DX12.h | 407 + src/RenderTargets_GL.h | 403 + src/Renderer_DX11.cpp | 766 + src/Renderer_DX11.h | 242 + src/Renderer_DX12.cpp | 749 + src/Renderer_DX12.h | 200 + src/Renderer_GL.cpp | 556 + src/Renderer_GL.h | 223 + src/Shaders_DX11.cpp | 42 + src/Shaders_DX11.h | 204 + src/Shaders_DX12.cpp | 38 + src/Shaders_DX12.h | 220 + src/Shaders_GL.cpp | 190 + src/Shaders_GL.h | 326 + src/States_DX11.cpp | 191 + src/States_DX11.h | 107 + src/States_DX12.cpp | 200 + src/States_DX12.h | 95 + src/States_GL.cpp | 97 + src/States_GL.h | 39 + src/TextureUtil.h | 135 + src/TimestampQueries.h | 340 + src/UserTexture.h | 257 + src/VAO_GL.h | 55 + src/Viewports.h | 42 + src/d3dx12.h | 1508 + src/shaders/compile_glsl.bat | 13 + src/shaders/compile_hlsl.bat | 3 + src/shaders/helper_fxc.bat | 14 + src/shaders/helper_hlsl_cc.bat | 20 + src/shaders/out/d3d11/BlurX_PS.cpp | 1674 + src/shaders/out/d3d11/BlurX_PS.h | 49 + src/shaders/out/d3d11/BlurY_PS.cpp | 1769 + src/shaders/out/d3d11/BlurY_PS.h | 49 + src/shaders/out/d3d11/CoarseAO_GS.cpp | 179 + src/shaders/out/d3d11/CoarseAO_GS.h | 27 + src/shaders/out/d3d11/CoarseAO_PS.cpp | 80529 +++++++++++++++++++ src/shaders/out/d3d11/CoarseAO_PS.h | 72 + src/shaders/out/d3d11/CopyDepth_PS.cpp | 232 + src/shaders/out/d3d11/CopyDepth_PS.h | 38 + src/shaders/out/d3d11/DebugAO_PS.cpp | 6717 ++ src/shaders/out/d3d11/DebugAO_PS.h | 38 + src/shaders/out/d3d11/DebugNormals_PS.cpp | 801 + src/shaders/out/d3d11/DebugNormals_PS.h | 39 + src/shaders/out/d3d11/DeinterleaveDepth_PS.cpp | 235 + src/shaders/out/d3d11/DeinterleaveDepth_PS.h | 27 + src/shaders/out/d3d11/FullScreenTriangle_VS.cpp | 129 + src/shaders/out/d3d11/FullScreenTriangle_VS.h | 27 + src/shaders/out/d3d11/LinearizeDepth_PS.cpp | 272 + src/shaders/out/d3d11/LinearizeDepth_PS.h | 38 + src/shaders/out/d3d11/ReconstructNormal_PS.cpp | 392 + src/shaders/out/d3d11/ReconstructNormal_PS.h | 27 + src/shaders/out/d3d11/ReinterleaveAO_PS.cpp | 303 + src/shaders/out/d3d11/ReinterleaveAO_PS.h | 38 + src/shaders/out/gl/BlurX_PS.cpp | 453 + src/shaders/out/gl/BlurX_PS.h | 49 + src/shaders/out/gl/BlurY_PS.cpp | 465 + src/shaders/out/gl/BlurY_PS.h | 49 + src/shaders/out/gl/CoarseAO_PS.cpp | 15519 ++++ src/shaders/out/gl/CoarseAO_PS.h | 72 + src/shaders/out/gl/CopyDepth_PS.cpp | 139 + src/shaders/out/gl/CopyDepth_PS.h | 38 + src/shaders/out/gl/DebugNormals_PS.cpp | 313 + src/shaders/out/gl/DebugNormals_PS.h | 39 + src/shaders/out/gl/DeinterleaveDepth_PS.cpp | 112 + src/shaders/out/gl/DeinterleaveDepth_PS.h | 27 + src/shaders/out/gl/LinearizeDepth_PS.cpp | 145 + src/shaders/out/gl/LinearizeDepth_PS.h | 38 + src/shaders/out/gl/ReconstructNormal_PS.cpp | 125 + src/shaders/out/gl/ReconstructNormal_PS.h | 27 + src/shaders/out/gl/ReinterleaveAO_PS.cpp | 128 + src/shaders/out/gl/ReinterleaveAO_PS.h | 38 + src/shaders/src/BlurX_PS.hlsl | 27 + src/shaders/src/BlurY_PS.hlsl | 29 + src/shaders/src/Blur_Common.hlsl | 206 + src/shaders/src/CoarseAO_GS.hlsl | 35 + src/shaders/src/CoarseAO_PS.hlsl | 217 + src/shaders/src/ConstantBuffers.hlsl | 131 + src/shaders/src/CopyDepth_PS.hlsl | 41 + src/shaders/src/DebugAO_PS.hlsl | 169 + src/shaders/src/DebugNormals_PS.hlsl | 42 + src/shaders/src/DeinterleaveDepth_PS.hlsl | 95 + src/shaders/src/FetchNormal_Common.hlsl | 60 + src/shaders/src/FullScreenTriangle_VS.hlsl | 43 + src/shaders/src/LinearizeDepth_PS.hlsl | 49 + src/shaders/src/ReconstructNormal_Common.hlsl | 95 + src/shaders/src/ReconstructNormal_PS.hlsl | 26 + src/shaders/src/ReinterleaveAO_PS.hlsl | 70 + src/shaders/src/SharedDefines.h | 37 + 334 files changed, 216665 insertions(+) create mode 100644 build/platforms/vs2015/GFSDK_SSAO.sln create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj.filters create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj.filters create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj.filters create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj create mode 100644 build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj.filters create mode 100644 build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj create mode 100644 build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj.filters create mode 100644 build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj create mode 100644 build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj.filters create mode 100644 build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj create mode 100644 build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj.filters create mode 100644 build/tools/HLSLcc/May_2014/.gitattributes create mode 100644 build/tools/HLSLcc/May_2014/.gitignore create mode 100644 build/tools/HLSLcc/May_2014/include/hlslcc.h create mode 100644 build/tools/HLSLcc/May_2014/include/hlslcc.hpp create mode 100644 build/tools/HLSLcc/May_2014/include/pstdint.h create mode 100644 build/tools/HLSLcc/May_2014/license.txt create mode 100644 build/tools/HLSLcc/May_2014/mk/CMakeLists.txt create mode 100644 build/tools/HLSLcc/May_2014/offline/cjson/cJSON.c create mode 100644 build/tools/HLSLcc/May_2014/offline/cjson/cJSON.h create mode 100644 build/tools/HLSLcc/May_2014/offline/hash.h create mode 100644 build/tools/HLSLcc/May_2014/offline/serializeReflection.cpp create mode 100644 build/tools/HLSLcc/May_2014/offline/serializeReflection.h create mode 100644 build/tools/HLSLcc/May_2014/offline/timer.cpp create mode 100644 build/tools/HLSLcc/May_2014/offline/timer.h create mode 100644 build/tools/HLSLcc/May_2014/offline/toGLSLStandalone.cpp create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/bsafe.c create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/bsafe.h create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/bstraux.c create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/bstraux.h create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.c create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.h create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.txt create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/gpl.txt create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/license.txt create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/porting.txt create mode 100644 build/tools/HLSLcc/May_2014/src/cbstring/security.txt create mode 100644 build/tools/HLSLcc/May_2014/src/decode.c create mode 100644 build/tools/HLSLcc/May_2014/src/decodeDX9.c create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/debug.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/decode.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.c create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/languages.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/reflect.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/shaderLimits.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/structs.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLDeclaration.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLInstruction.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLOperand.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/tokens.h create mode 100644 build/tools/HLSLcc/May_2014/src/internal_includes/tokensDX9.h create mode 100644 build/tools/HLSLcc/May_2014/src/reflect.c create mode 100644 build/tools/HLSLcc/May_2014/src/toGLSL.c create mode 100644 build/tools/HLSLcc/May_2014/src/toGLSLDeclaration.c create mode 100644 build/tools/HLSLcc/May_2014/src/toGLSLInstruction.c create mode 100644 build/tools/HLSLcc/May_2014/src/toGLSLOperand.c create mode 100644 build/tools/ShaderBuildTool/ShaderBuildTool.cpp create mode 100644 build/tools/ShaderBuildTool/ShaderBuildTool.sln create mode 100644 build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj create mode 100644 build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj.filters create mode 100644 build/tools/ShaderBuildTool/stdafx.cpp create mode 100644 build/tools/ShaderBuildTool/stdafx.h create mode 100644 build/tools/ShaderBuildTool/targetver.h create mode 100644 build/tools/Stringify/Stringify.cpp create mode 100644 build/tools/Stringify/Stringify.sln create mode 100644 build/tools/Stringify/Stringify.vcxproj create mode 100644 build/tools/Stringify/Stringify.vcxproj.filters create mode 100644 build/tools/Stringify/stdafx.cpp create mode 100644 build/tools/Stringify/stdafx.h create mode 100644 build/tools/Stringify/targetver.h create mode 100644 doc/.buildinfo create mode 100644 doc/_images/AOBias_0_0.png create mode 100644 doc/_images/AOBias_0_3.png create mode 100644 doc/_images/AO_Radius_1.png create mode 100644 doc/_images/AO_Radius_4.png create mode 100644 doc/_images/BackgroundAO_OFF.png create mode 100644 doc/_images/BackgroundAO_ON.png create mode 100644 doc/_images/Blur_Radius_4.png create mode 100644 doc/_images/Blur_Sharpness_0.png create mode 100644 doc/_images/Blur_Sharpness_8.png create mode 100644 doc/_images/ForegroundAO_OFF.png create mode 100644 doc/_images/ForegroundAO_ON.png create mode 100644 doc/_images/No_Blur.png create mode 100644 doc/_images/hbao-plus-in-tom-clancys-splinter-cell-blacklist-2.jpg create mode 100644 doc/_images/pipeline_with_input_normals.png create mode 100644 doc/_images/pipeline_without_input_normals.png create mode 100644 doc/_sources/changelog.txt create mode 100644 doc/_sources/index.txt create mode 100644 doc/_sources/product.txt create mode 100644 doc/_sources/releasenotes.txt create mode 100644 doc/_sources/sphinx/python-2.7.5/Lib/site-packages/Sphinx-1.2.dist-info/DESCRIPTION.txt create mode 100644 doc/_sources/sphinx/python-2.7.5/Lib/site-packages/setuptools-2.1.dist-info/DESCRIPTION.txt create mode 100644 doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/base.txt create mode 100644 doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/class.txt create mode 100644 doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/module.txt create mode 100644 doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/contents.txt create mode 100644 doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/only.txt create mode 100644 doc/_static/AOBias_0_0.png create mode 100644 doc/_static/AOBias_0_3.png create mode 100644 doc/_static/AO_Radius_1.png create mode 100644 doc/_static/AO_Radius_4.png create mode 100644 doc/_static/BackgroundAO_OFF.png create mode 100644 doc/_static/BackgroundAO_ON.png create mode 100644 doc/_static/Blur_Radius_4.png create mode 100644 doc/_static/Blur_Sharpness_0.png create mode 100644 doc/_static/Blur_Sharpness_8.png create mode 100644 doc/_static/DINWebPro-Black.woff create mode 100644 doc/_static/DINWebPro-BlackIta.woff create mode 100644 doc/_static/DINWebPro-Bold.woff create mode 100644 doc/_static/DINWebPro-BoldIta.woff create mode 100644 doc/_static/DINWebPro-Ita.woff create mode 100644 doc/_static/DINWebPro-Light.woff create mode 100644 doc/_static/DINWebPro-LightIta.woff create mode 100644 doc/_static/DINWebPro-Medium.woff create mode 100644 doc/_static/DINWebPro-MediumIta.woff create mode 100644 doc/_static/DINWebPro.woff create mode 100644 doc/_static/ForegroundAO_OFF.png create mode 100644 doc/_static/ForegroundAO_ON.png create mode 100644 doc/_static/No_Blur.png create mode 100644 doc/_static/application.css create mode 100644 doc/_static/bootstrap.css create mode 100644 doc/_static/bootstrap.js create mode 100644 doc/_static/default.css create mode 100644 doc/_static/developerzone_gameworks_logo.png create mode 100644 doc/_static/doctools.js create mode 100644 doc/_static/hbao-plus-in-tom-clancys-splinter-cell-blacklist-2.jpg create mode 100644 doc/_static/jquery.js create mode 100644 doc/_static/minus.gif create mode 100644 doc/_static/nvidia-logo-header.png create mode 100644 doc/_static/pipeline_with_input_normals.png create mode 100644 doc/_static/pipeline_without_input_normals.png create mode 100644 doc/_static/plus.gif create mode 100644 doc/_static/pygments.css create mode 100644 doc/_static/searchtools.js create mode 100644 doc/_static/sidebar.js create mode 100644 doc/_static/space.gif create mode 100644 doc/_static/styleguide.css create mode 100644 doc/_static/underscore.js create mode 100644 doc/changelog.html create mode 100644 doc/genindex.html create mode 100644 doc/index.html create mode 100644 doc/objects.inv create mode 100644 doc/product.html create mode 100644 doc/releasenotes.html create mode 100644 doc/search.html create mode 100644 doc/searchindex.js create mode 100644 doc/sphinx/python-2.7.5/Lib/site-packages/Sphinx-1.2.dist-info/DESCRIPTION.html create mode 100644 doc/sphinx/python-2.7.5/Lib/site-packages/setuptools-2.1.dist-info/DESCRIPTION.html create mode 100644 doc/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/base.html create mode 100644 doc/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/class.html create mode 100644 doc/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/module.html create mode 100644 doc/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/contents.html create mode 100644 doc/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/only.html create mode 100644 include/GFSDK_SSAO.h create mode 100644 lib/GFSDK_SSAO.h create mode 100644 samples/D3D11/external/AntTweakBar/1.16/include/AntTweakBar.h create mode 100644 samples/D3D11/media/directx.ico create mode 100644 samples/D3D11/src/BinMeshReader.h create mode 100644 samples/D3D11/src/DeviceManager.cpp create mode 100644 samples/D3D11/src/DeviceManager.h create mode 100644 samples/D3D11/src/GPUTimers.cpp create mode 100644 samples/D3D11/src/GPUTimers.h create mode 100644 samples/D3D11/src/InputDumpReader.h create mode 100644 samples/D3D11/src/InputDumpWriter.h create mode 100644 samples/D3D11/src/SSAO11.cpp create mode 100644 samples/D3D11/src/SSAO11.manifest create mode 100644 samples/D3D11/src/SSAO11.rc create mode 100644 samples/D3D11/src/SSAO11_2015.sln create mode 100644 samples/D3D11/src/SSAO11_2015.vcxproj create mode 100644 samples/D3D11/src/SSAO11_2015.vcxproj.filters create mode 100644 samples/D3D11/src/SceneRTs.h create mode 100644 samples/D3D11/src/SibenikIndices.bin create mode 100644 samples/D3D11/src/SibenikVertices.bin create mode 100644 samples/D3D11/src/shaders/bin/CopyColorPS.h create mode 100644 samples/D3D11/src/shaders/bin/FullScreenTriangleVS.h create mode 100644 samples/D3D11/src/shaders/bin/GeometryPS.h create mode 100644 samples/D3D11/src/shaders/bin/GeometryVS.h create mode 100644 samples/D3D11/src/shaders/compile.bat create mode 100644 samples/D3D11/src/shaders/src/Scene3D.hlsl create mode 100644 samples/D3D12/external/imgui/.travis.yml create mode 100644 samples/D3D12/external/imgui/README.md create mode 100644 samples/D3D12/external/imgui/examples/directx12_example/directx12_example.vcxproj create mode 100644 samples/D3D12/external/imgui/examples/directx12_example/directx12_example.vcxproj.filters create mode 100644 samples/D3D12/external/imgui/examples/directx12_example/imgui_impl_dx12.cpp create mode 100644 samples/D3D12/external/imgui/examples/directx12_example/imgui_impl_dx12.h create mode 100644 samples/D3D12/external/imgui/examples/directx12_example/main.cpp create mode 100644 samples/D3D12/external/imgui/extra_fonts/Cousine-Regular.ttf create mode 100644 samples/D3D12/external/imgui/extra_fonts/DroidSans.ttf create mode 100644 samples/D3D12/external/imgui/extra_fonts/Karla-Regular.ttf create mode 100644 samples/D3D12/external/imgui/extra_fonts/ProggyClean.ttf create mode 100644 samples/D3D12/external/imgui/extra_fonts/ProggyTiny.ttf create mode 100644 samples/D3D12/external/imgui/extra_fonts/README.txt create mode 100644 samples/D3D12/external/imgui/extra_fonts/binary_to_compressed_c.cpp create mode 100644 samples/D3D12/external/imgui/imconfig.h create mode 100644 samples/D3D12/external/imgui/imgui.cpp create mode 100644 samples/D3D12/external/imgui/imgui.h create mode 100644 samples/D3D12/external/imgui/imgui_demo.cpp create mode 100644 samples/D3D12/external/imgui/imgui_draw.cpp create mode 100644 samples/D3D12/external/imgui/imgui_internal.h create mode 100644 samples/D3D12/external/imgui/stb_rect_pack.h create mode 100644 samples/D3D12/external/imgui/stb_textedit.h create mode 100644 samples/D3D12/external/imgui/stb_truetype.h create mode 100644 samples/D3D12/src/BinMeshReader.h create mode 100644 samples/D3D12/src/SSAO12_2015.sln create mode 100644 samples/D3D12/src/SibenikIndices.bin create mode 100644 samples/D3D12/src/SibenikVertices.bin create mode 100644 samples/D3D12/src/Viewer.cpp create mode 100644 samples/D3D12/src/Viewer.hlsl create mode 100644 samples/D3D12/src/Viewer.vcxproj create mode 100644 samples/D3D12/src/Viewer.vcxproj.filters create mode 100644 samples/D3D12/src/WaveFrontReader.h create mode 100644 samples/D3D12/src/d3dx12.h create mode 100644 samples/D3D12/src/d3dx12p.h create mode 100644 src/API.cpp create mode 100644 src/AppState_DX11.cpp create mode 100644 src/AppState_DX11.h create mode 100644 src/AppState_GL.cpp create mode 100644 src/AppState_GL.h create mode 100644 src/BuildVersion.h create mode 100644 src/Common.h create mode 100644 src/Common_DX12.h create mode 100644 src/Common_GL.h create mode 100644 src/ConstantBuffers.cpp create mode 100644 src/ConstantBuffers.h create mode 100644 src/GLSLProgram.h create mode 100644 src/InputDepthInfo.h create mode 100644 src/InputNormalInfo.h create mode 100644 src/InputViewport.h create mode 100644 src/MathUtil.h create mode 100644 src/MatrixView.h create mode 100644 src/OutputInfo.h create mode 100644 src/PerfMarkers.h create mode 100644 src/PipelineStateObjects_DX12.cpp create mode 100644 src/PipelineStateObjects_DX12.h create mode 100644 src/ProjectionMatrixInfo.cpp create mode 100644 src/ProjectionMatrixInfo.h create mode 100644 src/RandomTexture.cpp create mode 100644 src/RandomTexture.h create mode 100644 src/RenderOptions.h create mode 100644 src/RenderTargets_DX11.h create mode 100644 src/RenderTargets_DX12.h create mode 100644 src/RenderTargets_GL.h create mode 100644 src/Renderer_DX11.cpp create mode 100644 src/Renderer_DX11.h create mode 100644 src/Renderer_DX12.cpp create mode 100644 src/Renderer_DX12.h create mode 100644 src/Renderer_GL.cpp create mode 100644 src/Renderer_GL.h create mode 100644 src/Shaders_DX11.cpp create mode 100644 src/Shaders_DX11.h create mode 100644 src/Shaders_DX12.cpp create mode 100644 src/Shaders_DX12.h create mode 100644 src/Shaders_GL.cpp create mode 100644 src/Shaders_GL.h create mode 100644 src/States_DX11.cpp create mode 100644 src/States_DX11.h create mode 100644 src/States_DX12.cpp create mode 100644 src/States_DX12.h create mode 100644 src/States_GL.cpp create mode 100644 src/States_GL.h create mode 100644 src/TextureUtil.h create mode 100644 src/TimestampQueries.h create mode 100644 src/UserTexture.h create mode 100644 src/VAO_GL.h create mode 100644 src/Viewports.h create mode 100644 src/d3dx12.h create mode 100644 src/shaders/compile_glsl.bat create mode 100644 src/shaders/compile_hlsl.bat create mode 100644 src/shaders/helper_fxc.bat create mode 100644 src/shaders/helper_hlsl_cc.bat create mode 100644 src/shaders/out/d3d11/BlurX_PS.cpp create mode 100644 src/shaders/out/d3d11/BlurX_PS.h create mode 100644 src/shaders/out/d3d11/BlurY_PS.cpp create mode 100644 src/shaders/out/d3d11/BlurY_PS.h create mode 100644 src/shaders/out/d3d11/CoarseAO_GS.cpp create mode 100644 src/shaders/out/d3d11/CoarseAO_GS.h create mode 100644 src/shaders/out/d3d11/CoarseAO_PS.cpp create mode 100644 src/shaders/out/d3d11/CoarseAO_PS.h create mode 100644 src/shaders/out/d3d11/CopyDepth_PS.cpp create mode 100644 src/shaders/out/d3d11/CopyDepth_PS.h create mode 100644 src/shaders/out/d3d11/DebugAO_PS.cpp create mode 100644 src/shaders/out/d3d11/DebugAO_PS.h create mode 100644 src/shaders/out/d3d11/DebugNormals_PS.cpp create mode 100644 src/shaders/out/d3d11/DebugNormals_PS.h create mode 100644 src/shaders/out/d3d11/DeinterleaveDepth_PS.cpp create mode 100644 src/shaders/out/d3d11/DeinterleaveDepth_PS.h create mode 100644 src/shaders/out/d3d11/FullScreenTriangle_VS.cpp create mode 100644 src/shaders/out/d3d11/FullScreenTriangle_VS.h create mode 100644 src/shaders/out/d3d11/LinearizeDepth_PS.cpp create mode 100644 src/shaders/out/d3d11/LinearizeDepth_PS.h create mode 100644 src/shaders/out/d3d11/ReconstructNormal_PS.cpp create mode 100644 src/shaders/out/d3d11/ReconstructNormal_PS.h create mode 100644 src/shaders/out/d3d11/ReinterleaveAO_PS.cpp create mode 100644 src/shaders/out/d3d11/ReinterleaveAO_PS.h create mode 100644 src/shaders/out/gl/BlurX_PS.cpp create mode 100644 src/shaders/out/gl/BlurX_PS.h create mode 100644 src/shaders/out/gl/BlurY_PS.cpp create mode 100644 src/shaders/out/gl/BlurY_PS.h create mode 100644 src/shaders/out/gl/CoarseAO_PS.cpp create mode 100644 src/shaders/out/gl/CoarseAO_PS.h create mode 100644 src/shaders/out/gl/CopyDepth_PS.cpp create mode 100644 src/shaders/out/gl/CopyDepth_PS.h create mode 100644 src/shaders/out/gl/DebugNormals_PS.cpp create mode 100644 src/shaders/out/gl/DebugNormals_PS.h create mode 100644 src/shaders/out/gl/DeinterleaveDepth_PS.cpp create mode 100644 src/shaders/out/gl/DeinterleaveDepth_PS.h create mode 100644 src/shaders/out/gl/LinearizeDepth_PS.cpp create mode 100644 src/shaders/out/gl/LinearizeDepth_PS.h create mode 100644 src/shaders/out/gl/ReconstructNormal_PS.cpp create mode 100644 src/shaders/out/gl/ReconstructNormal_PS.h create mode 100644 src/shaders/out/gl/ReinterleaveAO_PS.cpp create mode 100644 src/shaders/out/gl/ReinterleaveAO_PS.h create mode 100644 src/shaders/src/BlurX_PS.hlsl create mode 100644 src/shaders/src/BlurY_PS.hlsl create mode 100644 src/shaders/src/Blur_Common.hlsl create mode 100644 src/shaders/src/CoarseAO_GS.hlsl create mode 100644 src/shaders/src/CoarseAO_PS.hlsl create mode 100644 src/shaders/src/ConstantBuffers.hlsl create mode 100644 src/shaders/src/CopyDepth_PS.hlsl create mode 100644 src/shaders/src/DebugAO_PS.hlsl create mode 100644 src/shaders/src/DebugNormals_PS.hlsl create mode 100644 src/shaders/src/DeinterleaveDepth_PS.hlsl create mode 100644 src/shaders/src/FetchNormal_Common.hlsl create mode 100644 src/shaders/src/FullScreenTriangle_VS.hlsl create mode 100644 src/shaders/src/LinearizeDepth_PS.hlsl create mode 100644 src/shaders/src/ReconstructNormal_Common.hlsl create mode 100644 src/shaders/src/ReconstructNormal_PS.hlsl create mode 100644 src/shaders/src/ReinterleaveAO_PS.hlsl create mode 100644 src/shaders/src/SharedDefines.h diff --git a/build/platforms/vs2015/GFSDK_SSAO.sln b/build/platforms/vs2015/GFSDK_SSAO.sln new file mode 100644 index 0000000..b82f355 --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO.sln @@ -0,0 +1,145 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleApp_D3D11", "..\..\..\samples\D3D11\src\SSAO11_2015.vcxproj", "{A66D14E4-918C-493C-81C9-7661CCCE336D}" + ProjectSection(ProjectDependencies) = postProject + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A} = {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleApp_D3D12", "..\..\..\samples\D3D12\src\Viewer.vcxproj", "{CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}" + ProjectSection(ProjectDependencies) = postProject + {9E9A59CE-F50F-454A-A922-17324373A3A5} = {9E9A59CE-F50F-454A-A922-17324373A3A5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GFSDK_SSAO_D3D11", "GFSDK_SSAO_D3D11.vcxproj", "{94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}" + ProjectSection(ProjectDependencies) = postProject + {A64D27A9-CD59-476B-B5CB-0260A408793B} = {A64D27A9-CD59-476B-B5CB-0260A408793B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GFSDK_SSAO_D3D11_UWP", "GFSDK_SSAO_D3D11_UWP.vcxproj", "{D213334C-5B95-414B-AED9-F203FFD1D00D}" + ProjectSection(ProjectDependencies) = postProject + {A64D27A9-CD59-476B-B5CB-0260A408793B} = {A64D27A9-CD59-476B-B5CB-0260A408793B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GFSDK_SSAO_D3D12", "GFSDK_SSAO_D3D12.vcxproj", "{9E9A59CE-F50F-454A-A922-17324373A3A5}" + ProjectSection(ProjectDependencies) = postProject + {A64D27A9-CD59-476B-B5CB-0260A408793B} = {A64D27A9-CD59-476B-B5CB-0260A408793B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GFSDK_SSAO_D3D12_UWP", "GFSDK_SSAO_D3D12_UWP.vcxproj", "{EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}" + ProjectSection(ProjectDependencies) = postProject + {A64D27A9-CD59-476B-B5CB-0260A408793B} = {A64D27A9-CD59-476B-B5CB-0260A408793B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GFSDK_SSAO_GL", "GFSDK_SSAO_GL.vcxproj", "{5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}" + ProjectSection(ProjectDependencies) = postProject + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7} = {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GFSDK_SSAO_Shaders_D3D11", "GFSDK_SSAO_Shaders_D3D11.vcxproj", "{A64D27A9-CD59-476B-B5CB-0260A408793B}" + ProjectSection(ProjectDependencies) = postProject + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE} = {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GFSDK_SSAO_Shaders_GL", "GFSDK_SSAO_Shaders_GL.vcxproj", "{10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}" + ProjectSection(ProjectDependencies) = postProject + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE} = {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShaderBuildTool", "..\..\tools\ShaderBuildTool\ShaderBuildTool.vcxproj", "{438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Debug|x64.ActiveCfg = Debug|x64 + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Debug|x64.Build.0 = Debug|x64 + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Debug|x86.ActiveCfg = Debug|Win32 + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Debug|x86.Build.0 = Debug|Win32 + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Release|x64.ActiveCfg = Release|x64 + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Release|x64.Build.0 = Release|x64 + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Release|x86.ActiveCfg = Release|Win32 + {A66D14E4-918C-493C-81C9-7661CCCE336D}.Release|x86.Build.0 = Release|Win32 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x64.ActiveCfg = Debug|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x64.Build.0 = Debug|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x86.ActiveCfg = Debug|Win32 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x86.Build.0 = Debug|Win32 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x64.ActiveCfg = Release|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x64.Build.0 = Release|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x86.ActiveCfg = Release|Win32 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x86.Build.0 = Release|Win32 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Debug|x64.ActiveCfg = Release_MT|x64 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Debug|x64.Build.0 = Release_MT|x64 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Debug|x86.ActiveCfg = Release_MT|Win32 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Debug|x86.Build.0 = Release_MT|Win32 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Release|x64.ActiveCfg = Release_MT|x64 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Release|x64.Build.0 = Release_MT|x64 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Release|x86.ActiveCfg = Release_MT|Win32 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A}.Release|x86.Build.0 = Release_MT|Win32 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Debug|x64.ActiveCfg = Release_MT|x64 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Debug|x64.Build.0 = Release_MT|x64 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Debug|x86.ActiveCfg = Release_MT|Win32 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Debug|x86.Build.0 = Release_MT|Win32 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Release|x64.ActiveCfg = Release_MT|x64 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Release|x64.Build.0 = Release_MT|x64 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Release|x86.ActiveCfg = Release_MT|Win32 + {D213334C-5B95-414B-AED9-F203FFD1D00D}.Release|x86.Build.0 = Release_MT|Win32 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Debug|x64.ActiveCfg = Release_MT|x64 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Debug|x64.Build.0 = Release_MT|x64 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Debug|x86.ActiveCfg = Release_MT|Win32 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Debug|x86.Build.0 = Release_MT|Win32 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Release|x64.ActiveCfg = Release_MT|x64 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Release|x64.Build.0 = Release_MT|x64 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Release|x86.ActiveCfg = Release_MT|Win32 + {9E9A59CE-F50F-454A-A922-17324373A3A5}.Release|x86.Build.0 = Release_MT|Win32 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Debug|x64.ActiveCfg = Release_MT|x64 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Debug|x64.Build.0 = Release_MT|x64 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Debug|x86.ActiveCfg = Release_MT|Win32 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Debug|x86.Build.0 = Release_MT|Win32 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Release|x64.ActiveCfg = Release_MT|x64 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Release|x64.Build.0 = Release_MT|x64 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Release|x86.ActiveCfg = Release_MT|Win32 + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F}.Release|x86.Build.0 = Release_MT|Win32 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Debug|x64.ActiveCfg = Release_MT|x64 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Debug|x64.Build.0 = Release_MT|x64 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Debug|x86.ActiveCfg = Release_MT|Win32 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Debug|x86.Build.0 = Release_MT|Win32 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Release|x64.ActiveCfg = Release_MT|x64 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Release|x64.Build.0 = Release_MT|x64 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Release|x86.ActiveCfg = Release_MT|Win32 + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED}.Release|x86.Build.0 = Release_MT|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Debug|x64.ActiveCfg = release|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Debug|x64.Build.0 = release|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Debug|x86.ActiveCfg = release|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Debug|x86.Build.0 = release|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Release|x64.ActiveCfg = release|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Release|x64.Build.0 = release|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Release|x86.ActiveCfg = release|Win32 + {A64D27A9-CD59-476B-B5CB-0260A408793B}.Release|x86.Build.0 = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Debug|x64.ActiveCfg = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Debug|x64.Build.0 = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Debug|x86.ActiveCfg = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Debug|x86.Build.0 = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Release|x64.ActiveCfg = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Release|x64.Build.0 = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Release|x86.ActiveCfg = release|Win32 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7}.Release|x86.Build.0 = release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x64.ActiveCfg = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x64.Build.0 = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x86.ActiveCfg = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x86.Build.0 = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x64.ActiveCfg = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x64.Build.0 = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x86.ActiveCfg = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj b/build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj new file mode 100644 index 0000000..291200b --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj @@ -0,0 +1,121 @@ + + + + + Release_MT + Win32 + + + Release_MT + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GFSDK_SSAO_D3D11 + {94E21C5D-95F5-4096-AEE0-C7C51F7FE02A} + NVUT + Win32Proj + 10.0.10240.0 + + + + DynamicLibrary + v140 + + + DynamicLibrary + v140 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(ProjectDir)\..\..\..\lib\ + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + $(ProjectName).win32 + $(ProjectDir)\..\..\..\lib\ + $(ProjectName).win64 + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + + + + MaxSpeed + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D11=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + MultiThreaded + Level4 + true + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreaded + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D11=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + Level4 + true + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj.filters b/build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj.filters new file mode 100644 index 0000000..a2aff9d --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D11.vcxproj.filters @@ -0,0 +1,108 @@ + + + + + {d42751f8-4011-40ee-97c3-976090cadc37} + + + {243c99c2-39c0-487d-b64d-d4643bd732d8} + + + + + Interface File + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj b/build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj new file mode 100644 index 0000000..57cac75 --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj @@ -0,0 +1,122 @@ + + + + + Release_MT + Win32 + + + Release_MT + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GFSDK_SSAO_D3D11_UWP + {D213334C-5B95-414B-AED9-F203FFD1D00D} + GFSDK_SSAO_D3D11 + true + Windows Store + 10.0.10586.0 + 10.0.10240.0 + 10.0 + + + + DynamicLibrary + v140 + true + + + DynamicLibrary + v140 + true + + + + + <_ProjectFileVersion>10.0.30319.1 + $(ProjectDir)\..\..\..\lib\ + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + $(ProjectName).win32 + $(ProjectDir)\..\..\..\lib\ + $(ProjectName).win64 + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + + + + MaxSpeed + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D11=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level4 + true + true + NotUsing + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreadedDLL + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D11=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + Level4 + true + true + NotUsing + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj.filters b/build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj.filters new file mode 100644 index 0000000..1d64b32 --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D11_UWP.vcxproj.filters @@ -0,0 +1,108 @@ + + + + + {a28a9eba-6b62-4076-8796-a83f363bff1d} + + + {99a36ca2-586b-4f47-8cfc-ea6863886c47} + + + + + Interface File + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj b/build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj new file mode 100644 index 0000000..48496b3 --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj @@ -0,0 +1,123 @@ + + + + + Release_MT + Win32 + + + Release_MT + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GFSDK_SSAO_D3D12 + {9E9A59CE-F50F-454A-A922-17324373A3A5} + NVUT + Win32Proj + 10.0.10240.0 + + + + DynamicLibrary + v140 + + + DynamicLibrary + v140 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(ProjectDir)\..\..\..\lib\ + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + $(ProjectName).win32 + $(ProjectDir)\..\..\..\lib\ + $(ProjectName).win64 + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + + + + MaxSpeed + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D12=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + MultiThreaded + Level3 + true + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + D3D12.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreaded + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D12=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + Level3 + true + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + D3D12.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj.filters b/build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj.filters new file mode 100644 index 0000000..4712b9d --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D12.vcxproj.filters @@ -0,0 +1,114 @@ + + + + + {2e6becb1-d116-4188-aa8c-27e1f6395817} + + + {c0007558-06e6-4f7c-a9c5-2ece74e8d9b1} + + + + + Interface File + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj b/build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj new file mode 100644 index 0000000..fd007cd --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj @@ -0,0 +1,123 @@ + + + + + Release_MT + Win32 + + + Release_MT + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GFSDK_SSAO_D3D12_UWP + {EBAE8F1C-7EBC-44AA-BF1A-B34F057A187F} + GFSDK_SSAO_D3D12 + true + Windows Store + 10.0.10586.0 + 10.0.10240.0 + 10.0 + + + + DynamicLibrary + v140 + true + + + DynamicLibrary + v140 + true + + + + + <_ProjectFileVersion>10.0.30319.1 + $(ProjectDir)\..\..\..\lib\ + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + $(ProjectName).win32 + $(ProjectDir)\..\..\..\lib\ + $(ProjectName).win64 + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + + + + MaxSpeed + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D12=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + true + true + NotUsing + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + D3D12.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + MultiThreadedDLL + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_D3D12=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + Level3 + true + true + NotUsing + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + D3D12.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj.filters b/build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj.filters new file mode 100644 index 0000000..a73f098 --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_D3D12_UWP.vcxproj.filters @@ -0,0 +1,111 @@ + + + + + {94f98865-bad1-4c4b-8f14-83d0acc7ce84} + + + {c60f5470-d3dc-4d7f-856a-29e7d120cb66} + + + + + Interface File + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj b/build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj new file mode 100644 index 0000000..8cb852d --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj @@ -0,0 +1,126 @@ + + + + + Release_MT + Win32 + + + Release_MT + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GFSDK_SSAO_GL + {5C00BDFE-5300-4BF1-BFC2-DAB7998C6DED} + NVUT + Win32Proj + 8.1 + + + + DynamicLibrary + v140 + + + DynamicLibrary + v140 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(ProjectDir)\..\..\..\lib\ + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + $(ProjectName).win32 + $(ProjectDir)\..\..\..\lib\ + $(ProjectName).win64 + Temp\$(ProjectName)\$(Platform)\$(Configuration)\ + + + + MaxSpeed + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_GL=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + MultiThreaded + Level4 + true + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + %LIB% + + + + + MultiThreaded + $(OUTPUT_DIR_LIB);$(ProjectDir)\..\..\..\include + SUPPORT_GL=1;_WINDLL;GLEW_STATIC;NDEBUG;_WINDOWS;UNICODE;%(PreprocessorDefinitions) + Level4 + true + + + $(OutDir)$(ProjectName)_MT.lib + + + true + $(OutDir)$(TargetName).pdb + %LIB% + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj.filters b/build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj.filters new file mode 100644 index 0000000..037c6f6 --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_GL.vcxproj.filters @@ -0,0 +1,117 @@ + + + + + {e9d2f88f-5038-42d1-9cb4-7f0a065bf947} + + + {8ecd298b-23f3-4738-b9f3-07fbc1548369} + + + + + Interface File + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj b/build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj new file mode 100644 index 0000000..e93a78a --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj @@ -0,0 +1,346 @@ + + + + + debug + Win32 + + + perfdev + Win32 + + + release + Win32 + + + + title + + v110 + 11.0 + {A64D27A9-CD59-476B-B5CB-0260A408793B} + + + + Utility + v140 + + + Utility + v140 + + + Utility + v140 + + + + + + + + + + + + + + + $(SolutionDir)/out\\ + ./Win32/GFSDK_SSAO_Shaders_D3D11/debug\ + .lib + GFSDK_SSAO_Shaders_D3D11 + AllRules.ruleset + + + + + + true + false + false + Fast + Default + /d2Zi+ + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Level4 + NotUsing + + + EditAndContinue + + + + + $(OutDir)GFSDK_SSAO_Shaders_D3D11.lib + %(AdditionalLibraryDirectories) + $(OutDir)/GFSDK_SSAO_Shaders_D3D11.lib.pdb + MachineX86 + + + + + true + + + + $(SolutionDir)/out\\ + ./Win32/GFSDK_SSAO_Shaders_D3D11/perfdev\ + .lib + GFSDK_SSAO_Shaders_D3D11 + AllRules.ruleset + + + + + + true + false + false + Fast + Default + /d2Zi+ + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Level4 + NotUsing + + + EditAndContinue + + + + + $(OutDir)GFSDK_SSAO_Shaders_D3D11.lib + %(AdditionalLibraryDirectories) + $(OutDir)/GFSDK_SSAO_Shaders_D3D11.lib.pdb + MachineX86 + + + + + true + + + + $(SolutionDir)/out\\ + ./Win32/GFSDK_SSAO_Shaders_D3D11/release\ + .lib + GFSDK_SSAO_Shaders_D3D11 + AllRules.ruleset + + + + + + true + false + false + Fast + Default + /d2Zi+ + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Level4 + NotUsing + + + EditAndContinue + + + + + $(OutDir)GFSDK_SSAO_Shaders_D3D11.lib + %(AdditionalLibraryDirectories) + $(OutDir)/GFSDK_SSAO_Shaders_D3D11.lib.pdb + MachineX86 + + + + + true + + + + + + + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CopyDepth_PS.hlsl CopyDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CopyDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CopyDepth_PS.hlsl CopyDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CopyDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CopyDepth_PS.hlsl CopyDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CopyDepth_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\LinearizeDepth_PS.hlsl LinearizeDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\LinearizeDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\LinearizeDepth_PS.hlsl LinearizeDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\LinearizeDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\LinearizeDepth_PS.hlsl LinearizeDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\LinearizeDepth_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DeinterleaveDepth_PS.hlsl DeinterleaveDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DeinterleaveDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DeinterleaveDepth_PS.hlsl DeinterleaveDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DeinterleaveDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DeinterleaveDepth_PS.hlsl DeinterleaveDepth_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DeinterleaveDepth_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugNormals_PS.hlsl DebugNormals_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DebugNormals_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugNormals_PS.hlsl DebugNormals_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DebugNormals_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugNormals_PS.hlsl DebugNormals_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DebugNormals_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReconstructNormal_PS.hlsl ReconstructNormal_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\ReconstructNormal_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReconstructNormal_PS.hlsl ReconstructNormal_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\ReconstructNormal_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReconstructNormal_PS.hlsl ReconstructNormal_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\ReconstructNormal_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CoarseAO_PS.hlsl CoarseAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CoarseAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CoarseAO_PS.hlsl CoarseAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CoarseAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CoarseAO_PS.hlsl CoarseAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CoarseAO_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReinterleaveAO_PS.hlsl ReinterleaveAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\ReinterleaveAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReinterleaveAO_PS.hlsl ReinterleaveAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\ReinterleaveAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReinterleaveAO_PS.hlsl ReinterleaveAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\ReinterleaveAO_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurX_PS.hlsl BlurX_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\BlurX_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurX_PS.hlsl BlurX_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\BlurX_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurX_PS.hlsl BlurX_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\BlurX_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurY_PS.hlsl BlurY_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\BlurY_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurY_PS.hlsl BlurY_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\BlurY_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurY_PS.hlsl BlurY_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\BlurY_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe vs_5_0 ..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl FullScreenTriangle_VS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\FullScreenTriangle_VS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe vs_5_0 ..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl FullScreenTriangle_VS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\FullScreenTriangle_VS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe vs_5_0 ..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl FullScreenTriangle_VS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\FullScreenTriangle_VS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugAO_PS.hlsl DebugAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;DebugAO_Common.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DebugAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugAO_PS.hlsl DebugAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;DebugAO_Common.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DebugAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugAO_PS.hlsl DebugAO_PS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;DebugAO_Common.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\DebugAO_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe gs_5_0 ..\..\..\src\shaders\src\CoarseAO_GS.hlsl CoarseAO_GS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CoarseAO_GS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe gs_5_0 ..\..\..\src\shaders\src\CoarseAO_GS.hlsl CoarseAO_GS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CoarseAO_GS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe gs_5_0 ..\..\..\src\shaders\src\CoarseAO_GS.hlsl CoarseAO_GS ..\..\..\src\shaders\out\D3D11 ..\..\..\src\shaders\compile_hlsl.bat D3D11 + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl + FXC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\D3D11\CoarseAO_GS.h; + + + + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj.filters b/build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj.filters new file mode 100644 index 0000000..db199ed --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_Shaders_D3D11.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + + + + + Shader Includes + + + + + + + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj b/build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj new file mode 100644 index 0000000..550601c --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj @@ -0,0 +1,304 @@ + + + + + debug + Win32 + + + perfdev + Win32 + + + release + Win32 + + + + title + + v110 + 11.0 + {10AECFFA-BF67-4FF4-B543-0C8F1E3B2EB7} + + + + Utility + v140 + + + Utility + v140 + + + Utility + v140 + + + + + + + + + + + + + + + $(SolutionDir)/out\\ + ./Win32/GFSDK_SSAO_Shaders_GL/debug\ + .lib + GFSDK_SSAO_Shaders_GL + AllRules.ruleset + + + + + + true + false + false + Fast + Default + /d2Zi+ + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Level4 + NotUsing + + + EditAndContinue + + + + + $(OutDir)GFSDK_SSAO_Shaders_GL.lib + %(AdditionalLibraryDirectories) + $(OutDir)/GFSDK_SSAO_Shaders_GL.lib.pdb + MachineX86 + + + + + true + + + + $(SolutionDir)/out\\ + ./Win32/GFSDK_SSAO_Shaders_GL/perfdev\ + .lib + GFSDK_SSAO_Shaders_GL + AllRules.ruleset + + + + + + true + false + false + Fast + Default + /d2Zi+ + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Level4 + NotUsing + + + EditAndContinue + + + + + $(OutDir)GFSDK_SSAO_Shaders_GL.lib + %(AdditionalLibraryDirectories) + $(OutDir)/GFSDK_SSAO_Shaders_GL.lib.pdb + MachineX86 + + + + + true + + + + $(SolutionDir)/out\\ + ./Win32/GFSDK_SSAO_Shaders_GL/release\ + .lib + GFSDK_SSAO_Shaders_GL + AllRules.ruleset + + + + + + true + false + false + Fast + Default + /d2Zi+ + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Level4 + NotUsing + + + EditAndContinue + + + + + $(OutDir)GFSDK_SSAO_Shaders_GL.lib + %(AdditionalLibraryDirectories) + $(OutDir)/GFSDK_SSAO_Shaders_GL.lib.pdb + MachineX86 + + + + + true + + + + + + + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CopyDepth_PS.hlsl CopyDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::CopyDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\CopyDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CopyDepth_PS.hlsl CopyDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::CopyDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\CopyDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CopyDepth_PS.hlsl CopyDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::CopyDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\CopyDepth_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\LinearizeDepth_PS.hlsl LinearizeDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::LinearizeDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\LinearizeDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\LinearizeDepth_PS.hlsl LinearizeDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::LinearizeDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\LinearizeDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\LinearizeDepth_PS.hlsl LinearizeDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::LinearizeDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\LinearizeDepth_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DeinterleaveDepth_PS.hlsl DeinterleaveDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::DeinterleaveDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\DeinterleaveDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DeinterleaveDepth_PS.hlsl DeinterleaveDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::DeinterleaveDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\DeinterleaveDepth_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DeinterleaveDepth_PS.hlsl DeinterleaveDepth_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::DeinterleaveDepth_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\DeinterleaveDepth_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugNormals_PS.hlsl DebugNormals_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::DebugNormals_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\DebugNormals_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugNormals_PS.hlsl DebugNormals_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::DebugNormals_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\DebugNormals_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\DebugNormals_PS.hlsl DebugNormals_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::DebugNormals_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\DebugNormals_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReconstructNormal_PS.hlsl ReconstructNormal_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::ReconstructNormal_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\ReconstructNormal_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReconstructNormal_PS.hlsl ReconstructNormal_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::ReconstructNormal_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\ReconstructNormal_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReconstructNormal_PS.hlsl ReconstructNormal_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::ReconstructNormal_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ReconstructNormal_Common.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\ReconstructNormal_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CoarseAO_PS.hlsl CoarseAO_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::CoarseAO_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\CoarseAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CoarseAO_PS.hlsl CoarseAO_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::CoarseAO_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\CoarseAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\CoarseAO_PS.hlsl CoarseAO_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::CoarseAO_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FetchNormal_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\CoarseAO_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReinterleaveAO_PS.hlsl ReinterleaveAO_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::ReinterleaveAO_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\ReinterleaveAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReinterleaveAO_PS.hlsl ReinterleaveAO_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::ReinterleaveAO_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\ReinterleaveAO_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\ReinterleaveAO_PS.hlsl ReinterleaveAO_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::ReinterleaveAO_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\ReinterleaveAO_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurX_PS.hlsl BlurX_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::BlurX_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\BlurX_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurX_PS.hlsl BlurX_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::BlurX_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\BlurX_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurX_PS.hlsl BlurX_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::BlurX_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\BlurX_PS.h; + + + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurY_PS.hlsl BlurY_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::BlurY_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\BlurY_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurY_PS.hlsl BlurY_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::BlurY_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\BlurY_PS.h; + CMD /C ..\..\..\src\shaders\ShaderBuildTool.exe ps_5_0 ..\..\..\src\shaders\src\BlurY_PS.hlsl BlurY_PS ..\..\..\src\shaders\out\GL ..\..\..\src\shaders\compile_glsl.bat GL GLSLPrograms::BlurY_PS + ..\..\..\src\shaders\src\SharedDefines.h;..\..\..\src\shaders\src\ConstantBuffers.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\Blur_Common.hlsl;..\..\..\src\shaders\src\FullScreenTriangle_VS.hlsl;..\..\..\src\shaders\src\ConstantBuffers.hlsl + HLSLCC - %(Filename)%(Extension) + ..\..\..\src\shaders\out\GL\BlurY_PS.h; + + + + + + \ No newline at end of file diff --git a/build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj.filters b/build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj.filters new file mode 100644 index 0000000..d1f3308 --- /dev/null +++ b/build/platforms/vs2015/GFSDK_SSAO_Shaders_GL.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + + + + + Shader Includes + + + + + + + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + \ No newline at end of file diff --git a/build/tools/HLSLcc/May_2014/.gitattributes b/build/tools/HLSLcc/May_2014/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/build/tools/HLSLcc/May_2014/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/build/tools/HLSLcc/May_2014/.gitignore b/build/tools/HLSLcc/May_2014/.gitignore new file mode 100644 index 0000000..64a878e --- /dev/null +++ b/build/tools/HLSLcc/May_2014/.gitignore @@ -0,0 +1,69 @@ + +bin/ +obj/ +lib/ + +CMakeCache.txt +CMakeFiles +Makefile +cmake_install.cmake +install_manifest.txt + +tests/results/ + +# Visual Studio +*.suo +*.user +*.sdf +*.sln +*.opensdf +*.obj +*.vcxproj +*.vcxproj.filters +*.tlog +*.cache + +# CMake +*.lastbuildstate +mk/*.dir +mk/ipch/ +mk/Win32/ +tests/apps/mk/**/*.dir/ +tests/apps/mk/ipch/ +tests/apps/mk/Win32/ + +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +# *.o hlsl bytecode in tests dir are .o +*.so +*.nexe + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db \ No newline at end of file diff --git a/build/tools/HLSLcc/May_2014/include/hlslcc.h b/build/tools/HLSLcc/May_2014/include/hlslcc.h new file mode 100644 index 0000000..5ab1108 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/include/hlslcc.h @@ -0,0 +1,451 @@ +#ifndef HLSLCC_H_ +#define HLSLCC_H_ + +#if defined (_WIN32) && defined(HLSLCC_DYNLIB) + #define HLSLCC_APIENTRY __stdcall + #if defined(libHLSLcc_EXPORTS) + #define HLSLCC_API __declspec(dllexport) + #else + #define HLSLCC_API __declspec(dllimport) + #endif +#else + #define HLSLCC_APIENTRY + #define HLSLCC_API +#endif + +#include "pstdint.h" + +typedef enum +{ + LANG_DEFAULT,// Depends on the HLSL shader model. + LANG_ES_100, + LANG_ES_300, + LANG_ES_310, + LANG_120, + LANG_130, + LANG_140, + LANG_150, + LANG_330, + LANG_400, + LANG_410, + LANG_420, + LANG_430, + LANG_440, +} GLLang; + +typedef struct { + uint32_t ARB_explicit_attrib_location : 1; + uint32_t ARB_explicit_uniform_location : 1; + uint32_t ARB_shading_language_420pack : 1; +}GlExtensions; + +enum {MAX_SHADER_VEC4_OUTPUT = 512}; +enum {MAX_SHADER_VEC4_INPUT = 512}; +enum {MAX_TEXTURES = 128}; +enum {MAX_FORK_PHASES = 2}; +enum {MAX_FUNCTION_BODIES = 1024}; +enum {MAX_CLASS_TYPES = 1024}; +enum {MAX_FUNCTION_POINTERS = 128}; + +//Reflection +#define MAX_REFLECT_STRING_LENGTH 512 +#define MAX_SHADER_VARS 256 +#define MAX_CBUFFERS 256 +#define MAX_UAV 256 +#define MAX_FUNCTION_TABLES 256 +#define MAX_RESOURCE_BINDINGS 256 + +typedef enum SPECIAL_NAME +{ + NAME_UNDEFINED = 0, + NAME_POSITION = 1, + NAME_CLIP_DISTANCE = 2, + NAME_CULL_DISTANCE = 3, + NAME_RENDER_TARGET_ARRAY_INDEX = 4, + NAME_VIEWPORT_ARRAY_INDEX = 5, + NAME_VERTEX_ID = 6, + NAME_PRIMITIVE_ID = 7, + NAME_INSTANCE_ID = 8, + NAME_IS_FRONT_FACE = 9, + NAME_SAMPLE_INDEX = 10, + // The following are added for D3D11 + NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR = 11, + NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR = 12, + NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR = 13, + NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR = 14, + NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR = 15, + NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR = 16, + NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR = 17, + NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR = 18, + NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR = 19, + NAME_FINAL_TRI_INSIDE_TESSFACTOR = 20, + NAME_FINAL_LINE_DETAIL_TESSFACTOR = 21, + NAME_FINAL_LINE_DENSITY_TESSFACTOR = 22, +} SPECIAL_NAME; + + +typedef enum { + INOUT_COMPONENT_UNKNOWN = 0, + INOUT_COMPONENT_UINT32 = 1, + INOUT_COMPONENT_SINT32 = 2, + INOUT_COMPONENT_FLOAT32 = 3 +} INOUT_COMPONENT_TYPE; + +typedef enum MIN_PRECISION { + D3D_MIN_PRECISION_DEFAULT = 0, + D3D_MIN_PRECISION_FLOAT_16 = 1, + D3D_MIN_PRECISION_FLOAT_2_8 = 2, + D3D_MIN_PRECISION_RESERVED = 3, + D3D_MIN_PRECISION_SINT_16 = 4, + D3D_MIN_PRECISION_UINT_16 = 5, + D3D_MIN_PRECISION_ANY_16 = 0xf0, + D3D_MIN_PRECISION_ANY_10 = 0xf1 +} MIN_PRECISION; + +typedef struct InOutSignature_TAG +{ + char SemanticName[MAX_REFLECT_STRING_LENGTH]; + uint32_t ui32SemanticIndex; + SPECIAL_NAME eSystemValueType; + INOUT_COMPONENT_TYPE eComponentType; + uint32_t ui32Register; + uint32_t ui32Mask; + uint32_t ui32ReadWriteMask; + + uint32_t ui32Stream; + MIN_PRECISION eMinPrec; + +} InOutSignature; + +typedef enum ResourceType_TAG +{ + RTYPE_CBUFFER,//0 + RTYPE_TBUFFER,//1 + RTYPE_TEXTURE,//2 + RTYPE_SAMPLER,//3 + RTYPE_UAV_RWTYPED,//4 + RTYPE_STRUCTURED,//5 + RTYPE_UAV_RWSTRUCTURED,//6 + RTYPE_BYTEADDRESS,//7 + RTYPE_UAV_RWBYTEADDRESS,//8 + RTYPE_UAV_APPEND_STRUCTURED,//9 + RTYPE_UAV_CONSUME_STRUCTURED,//10 + RTYPE_UAV_RWSTRUCTURED_WITH_COUNTER,//11 + RTYPE_COUNT, +} ResourceType; + +typedef enum ResourceGroup_TAG { + RGROUP_CBUFFER, + RGROUP_TEXTURE, + RGROUP_SAMPLER, + RGROUP_UAV, + RGROUP_COUNT, +} ResourceGroup; + +typedef enum REFLECT_RESOURCE_DIMENSION +{ + REFLECT_RESOURCE_DIMENSION_UNKNOWN = 0, + REFLECT_RESOURCE_DIMENSION_BUFFER = 1, + REFLECT_RESOURCE_DIMENSION_TEXTURE1D = 2, + REFLECT_RESOURCE_DIMENSION_TEXTURE1DARRAY = 3, + REFLECT_RESOURCE_DIMENSION_TEXTURE2D = 4, + REFLECT_RESOURCE_DIMENSION_TEXTURE2DARRAY = 5, + REFLECT_RESOURCE_DIMENSION_TEXTURE2DMS = 6, + REFLECT_RESOURCE_DIMENSION_TEXTURE2DMSARRAY = 7, + REFLECT_RESOURCE_DIMENSION_TEXTURE3D = 8, + REFLECT_RESOURCE_DIMENSION_TEXTURECUBE = 9, + REFLECT_RESOURCE_DIMENSION_TEXTURECUBEARRAY = 10, + REFLECT_RESOURCE_DIMENSION_BUFFEREX = 11, +} REFLECT_RESOURCE_DIMENSION; + +typedef struct ResourceBinding_TAG +{ + char Name[MAX_REFLECT_STRING_LENGTH]; + ResourceType eType; + uint32_t ui32BindPoint; + uint32_t ui32BindCount; + uint32_t ui32Flags; + REFLECT_RESOURCE_DIMENSION eDimension; + uint32_t ui32ReturnType; + uint32_t ui32NumSamples; +} ResourceBinding; + +typedef enum _SHADER_VARIABLE_TYPE { + SVT_VOID = 0, + SVT_BOOL = 1, + SVT_INT = 2, + SVT_FLOAT = 3, + SVT_STRING = 4, + SVT_TEXTURE = 5, + SVT_TEXTURE1D = 6, + SVT_TEXTURE2D = 7, + SVT_TEXTURE3D = 8, + SVT_TEXTURECUBE = 9, + SVT_SAMPLER = 10, + SVT_PIXELSHADER = 15, + SVT_VERTEXSHADER = 16, + SVT_UINT = 19, + SVT_UINT8 = 20, + SVT_GEOMETRYSHADER = 21, + SVT_RASTERIZER = 22, + SVT_DEPTHSTENCIL = 23, + SVT_BLEND = 24, + SVT_BUFFER = 25, + SVT_CBUFFER = 26, + SVT_TBUFFER = 27, + SVT_TEXTURE1DARRAY = 28, + SVT_TEXTURE2DARRAY = 29, + SVT_RENDERTARGETVIEW = 30, + SVT_DEPTHSTENCILVIEW = 31, + SVT_TEXTURE2DMS = 32, + SVT_TEXTURE2DMSARRAY = 33, + SVT_TEXTURECUBEARRAY = 34, + SVT_HULLSHADER = 35, + SVT_DOMAINSHADER = 36, + SVT_INTERFACE_POINTER = 37, + SVT_COMPUTESHADER = 38, + SVT_DOUBLE = 39, + SVT_RWTEXTURE1D = 40, + SVT_RWTEXTURE1DARRAY = 41, + SVT_RWTEXTURE2D = 42, + SVT_RWTEXTURE2DARRAY = 43, + SVT_RWTEXTURE3D = 44, + SVT_RWBUFFER = 45, + SVT_BYTEADDRESS_BUFFER = 46, + SVT_RWBYTEADDRESS_BUFFER = 47, + SVT_STRUCTURED_BUFFER = 48, + SVT_RWSTRUCTURED_BUFFER = 49, + SVT_APPEND_STRUCTURED_BUFFER = 50, + SVT_CONSUME_STRUCTURED_BUFFER = 51, + + SVT_FORCE_DWORD = 0x7fffffff +} SHADER_VARIABLE_TYPE; + +typedef enum _SHADER_VARIABLE_CLASS { + SVC_SCALAR = 0, + SVC_VECTOR = ( SVC_SCALAR + 1 ), + SVC_MATRIX_ROWS = ( SVC_VECTOR + 1 ), + SVC_MATRIX_COLUMNS = ( SVC_MATRIX_ROWS + 1 ), + SVC_OBJECT = ( SVC_MATRIX_COLUMNS + 1 ), + SVC_STRUCT = ( SVC_OBJECT + 1 ), + SVC_INTERFACE_CLASS = ( SVC_STRUCT + 1 ), + SVC_INTERFACE_POINTER = ( SVC_INTERFACE_CLASS + 1 ), + SVC_FORCE_DWORD = 0x7fffffff +} SHADER_VARIABLE_CLASS; + +typedef struct ShaderVarType_TAG { + SHADER_VARIABLE_CLASS Class; + SHADER_VARIABLE_TYPE Type; + uint32_t Rows; + uint32_t Columns; + uint32_t Elements; + uint32_t MemberCount; + uint32_t Offset; + char Name[MAX_REFLECT_STRING_LENGTH]; + + uint32_t ParentCount; + struct ShaderVarType_TAG * Parent; + //Includes all parent names. + char FullName[MAX_REFLECT_STRING_LENGTH]; + + struct ShaderVarType_TAG * Members; +} ShaderVarType; + +typedef struct ShaderVar_TAG +{ + char Name[MAX_REFLECT_STRING_LENGTH]; + int haveDefaultValue; + uint32_t* pui32DefaultValues; + //Offset/Size in bytes. + uint32_t ui32StartOffset; + uint32_t ui32Size; + + ShaderVarType sType; +} ShaderVar; + +typedef struct ConstantBuffer_TAG +{ + char Name[MAX_REFLECT_STRING_LENGTH]; + + uint32_t ui32NumVars; + ShaderVar asVars [MAX_SHADER_VARS]; + + uint32_t ui32TotalSizeInBytes; +} ConstantBuffer; + +typedef struct ClassType_TAG +{ + char Name[MAX_REFLECT_STRING_LENGTH]; + uint16_t ui16ID; + uint16_t ui16ConstBufStride; + uint16_t ui16Texture; + uint16_t ui16Sampler; +} ClassType; + +typedef struct ClassInstance_TAG +{ + char Name[MAX_REFLECT_STRING_LENGTH]; + uint16_t ui16ID; + uint16_t ui16ConstBuf; + uint16_t ui16ConstBufOffset; + uint16_t ui16Texture; + uint16_t ui16Sampler; +} ClassInstance; + +typedef enum TESSELLATOR_PARTITIONING +{ + TESSELLATOR_PARTITIONING_UNDEFINED = 0, + TESSELLATOR_PARTITIONING_INTEGER = 1, + TESSELLATOR_PARTITIONING_POW2 = 2, + TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3, + TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4 +} TESSELLATOR_PARTITIONING; + +typedef enum TESSELLATOR_OUTPUT_PRIMITIVE +{ + TESSELLATOR_OUTPUT_UNDEFINED = 0, + TESSELLATOR_OUTPUT_POINT = 1, + TESSELLATOR_OUTPUT_LINE = 2, + TESSELLATOR_OUTPUT_TRIANGLE_CW = 3, + TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4 +} TESSELLATOR_OUTPUT_PRIMITIVE; + +typedef struct ShaderInfo_TAG +{ + uint32_t ui32MajorVersion; + uint32_t ui32MinorVersion; + + uint32_t ui32NumInputSignatures; + InOutSignature* psInputSignatures; + + uint32_t ui32NumOutputSignatures; + InOutSignature* psOutputSignatures; + + uint32_t ui32NumResourceBindings; + ResourceBinding* psResourceBindings; + + uint32_t ui32NumConstantBuffers; + ConstantBuffer* psConstantBuffers; + ConstantBuffer* psThisPointerConstBuffer; + + uint32_t ui32NumClassTypes; + ClassType* psClassTypes; + + uint32_t ui32NumClassInstances; + ClassInstance* psClassInstances; + + //Func table ID to class name ID. + uint32_t aui32TableIDToTypeID[MAX_FUNCTION_TABLES]; + + uint32_t aui32ResourceMap[RGROUP_COUNT][MAX_RESOURCE_BINDINGS]; + + TESSELLATOR_PARTITIONING eTessPartitioning; + TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim; +} ShaderInfo; + +typedef enum INTERPOLATION_MODE +{ + INTERPOLATION_UNDEFINED = 0, + INTERPOLATION_CONSTANT = 1, + INTERPOLATION_LINEAR = 2, + INTERPOLATION_LINEAR_CENTROID = 3, + INTERPOLATION_LINEAR_NOPERSPECTIVE = 4, + INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID = 5, + INTERPOLATION_LINEAR_SAMPLE = 6, + INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE = 7, +} INTERPOLATION_MODE; + +//The shader stages (Vertex, Pixel et al) do not depend on each other +//in HLSL. GLSL is a different story. HLSLCrossCompiler requires +//that hull shaders must be compiled before domain shaders, and +//the pixel shader must be compiled before all of the others. +//Durring compiliation the GLSLCrossDependencyData struct will +//carry over any information needed about a different shader stage +//in order to construct valid GLSL shader combinations. + +//Using GLSLCrossDependencyData is optional. However some shader +//combinations may show link failures, or runtime errors. +typedef struct +{ + //dcl_tessellator_partitioning and dcl_tessellator_output_primitive appear in hull shader for D3D, + //but they appear on inputs inside domain shaders for GL. + //Hull shader must be compiled before domain so the + //ensure correct partitioning and primitive type information + //can be saved when compiling hull and passed to domain compiliation. + TESSELLATOR_PARTITIONING eTessPartitioning; + TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim; + + //Required if PixelInterpDependency is true + INTERPOLATION_MODE aePixelInputInterpolation[MAX_SHADER_VEC4_INPUT]; +} GLSLCrossDependencyData; + +typedef struct +{ + int shaderType; //One of the GL enums. + char* sourceCode; + ShaderInfo reflection; + GLLang GLSLLanguage; +} GLSLShader; + +/*HLSL constant buffers are treated as default-block unform arrays by default. This is done + to support versions of GLSL which lack ARB_uniform_buffer_object functionality. + Setting this flag causes each one to have its own uniform block. + Note: Currently the nth const buffer will be named UnformBufferN. This is likey to change to the original HLSL name in the future.*/ +static const unsigned int HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT = 0x1; + +static const unsigned int HLSLCC_FLAG_ORIGIN_UPPER_LEFT = 0x2; + +static const unsigned int HLSLCC_FLAG_PIXEL_CENTER_INTEGER = 0x4; + +static const unsigned int HLSLCC_FLAG_GLOBAL_CONSTS_NEVER_IN_UBO = 0x8; + +//GS enabled? +//Affects vertex shader (i.e. need to compile vertex shader again to use with/without GS). +//This flag is needed in order for the interfaces between stages to match when GS is in use. +//PS inputs VtxGeoOutput +//GS outputs VtxGeoOutput +//Vs outputs VtxOutput if GS enabled. VtxGeoOutput otherwise. +static const unsigned int HLSLCC_FLAG_GS_ENABLED = 0x10; + +static const unsigned int HLSLCC_FLAG_TESS_ENABLED = 0x20; + +//Either use this flag or glBindFragDataLocationIndexed. +//When set the first pixel shader output is the first input to blend +//equation, the others go to the second input. +static const unsigned int HLSLCC_FLAG_DUAL_SOURCE_BLENDING = 0x40; + +//If set, shader inputs and outputs are declared with their semantic name. +static const unsigned int HLSLCC_FLAG_INOUT_SEMANTIC_NAMES = 0x80; + +#ifdef __cplusplus +extern "C" { +#endif + +HLSLCC_API void HLSLCC_APIENTRY HLSLcc_SetMemoryFunctions( void* (*malloc_override)(size_t), + void* (*calloc_override)(size_t,size_t), + void (*free_override)(void *), + void* (*realloc_override)(void*,size_t)); + +HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromFile(const char* filename, + unsigned int flags, + GLLang language, + const GlExtensions *extensions, + GLSLCrossDependencyData* dependencies, + GLSLShader* result + ); + +HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromMem(const char* shader, + unsigned int flags, + GLLang language, + const GlExtensions *extensions, + GLSLCrossDependencyData* dependencies, + GLSLShader* result); + +HLSLCC_API void HLSLCC_APIENTRY FreeGLSLShader(GLSLShader*); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/build/tools/HLSLcc/May_2014/include/hlslcc.hpp b/build/tools/HLSLcc/May_2014/include/hlslcc.hpp new file mode 100644 index 0000000..fa4dd96 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/include/hlslcc.hpp @@ -0,0 +1,5 @@ + +extern "C" { +#include "hlslcc.h" +} + diff --git a/build/tools/HLSLcc/May_2014/include/pstdint.h b/build/tools/HLSLcc/May_2014/include/pstdint.h new file mode 100644 index 0000000..00fc1fc --- /dev/null +++ b/build/tools/HLSLcc/May_2014/include/pstdint.h @@ -0,0 +1,800 @@ +/* A portable stdint.h + **************************************************************************** + * BSD License: + **************************************************************************** + * + * Copyright (c) 2005-2011 Paul Hsieh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************** + * + * Version 0.1.12 + * + * The ANSI C standard committee, for the C99 standard, specified the + * inclusion of a new standard include file called stdint.h. This is + * a very useful and long desired include file which contains several + * very precise definitions for integer scalar types that is + * critically important for making portable several classes of + * applications including cryptography, hashing, variable length + * integer libraries and so on. But for most developers its likely + * useful just for programming sanity. + * + * The problem is that most compiler vendors have decided not to + * implement the C99 standard, and the next C++ language standard + * (which has a lot more mindshare these days) will be a long time in + * coming and its unknown whether or not it will include stdint.h or + * how much adoption it will have. Either way, it will be a long time + * before all compilers come with a stdint.h and it also does nothing + * for the extremely large number of compilers available today which + * do not include this file, or anything comparable to it. + * + * So that's what this file is all about. Its an attempt to build a + * single universal include file that works on as many platforms as + * possible to deliver what stdint.h is supposed to. A few things + * that should be noted about this file: + * + * 1) It is not guaranteed to be portable and/or present an identical + * interface on all platforms. The extreme variability of the + * ANSI C standard makes this an impossibility right from the + * very get go. Its really only meant to be useful for the vast + * majority of platforms that possess the capability of + * implementing usefully and precisely defined, standard sized + * integer scalars. Systems which are not intrinsically 2s + * complement may produce invalid constants. + * + * 2) There is an unavoidable use of non-reserved symbols. + * + * 3) Other standard include files are invoked. + * + * 4) This file may come in conflict with future platforms that do + * include stdint.h. The hope is that one or the other can be + * used with no real difference. + * + * 5) In the current verison, if your platform can't represent + * int32_t, int16_t and int8_t, it just dumps out with a compiler + * error. + * + * 6) 64 bit integers may or may not be defined. Test for their + * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. + * Note that this is different from the C99 specification which + * requires the existence of 64 bit support in the compiler. If + * this is not defined for your platform, yet it is capable of + * dealing with 64 bits then it is because this file has not yet + * been extended to cover all of your system's capabilities. + * + * 7) (u)intptr_t may or may not be defined. Test for its presence + * with the test: #ifdef PTRDIFF_MAX. If this is not defined + * for your platform, then it is because this file has not yet + * been extended to cover all of your system's capabilities, not + * because its optional. + * + * 8) The following might not been defined even if your platform is + * capable of defining it: + * + * WCHAR_MIN + * WCHAR_MAX + * (u)int64_t + * PTRDIFF_MIN + * PTRDIFF_MAX + * (u)intptr_t + * + * 9) The following have not been defined: + * + * WINT_MIN + * WINT_MAX + * + * 10) The criteria for defining (u)int_least(*)_t isn't clear, + * except for systems which don't have a type that precisely + * defined 8, 16, or 32 bit types (which this include file does + * not support anyways). Default definitions have been given. + * + * 11) The criteria for defining (u)int_fast(*)_t isn't something I + * would trust to any particular compiler vendor or the ANSI C + * committee. It is well known that "compatible systems" are + * commonly created that have very different performance + * characteristics from the systems they are compatible with, + * especially those whose vendors make both the compiler and the + * system. Default definitions have been given, but its strongly + * recommended that users never use these definitions for any + * reason (they do *NOT* deliver any serious guarantee of + * improved performance -- not in this file, nor any vendor's + * stdint.h). + * + * 12) The following macros: + * + * PRINTF_INTMAX_MODIFIER + * PRINTF_INT64_MODIFIER + * PRINTF_INT32_MODIFIER + * PRINTF_INT16_MODIFIER + * PRINTF_LEAST64_MODIFIER + * PRINTF_LEAST32_MODIFIER + * PRINTF_LEAST16_MODIFIER + * PRINTF_INTPTR_MODIFIER + * + * are strings which have been defined as the modifiers required + * for the "d", "u" and "x" printf formats to correctly output + * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, + * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. + * PRINTF_INTPTR_MODIFIER is not defined for some systems which + * provide their own stdint.h. PRINTF_INT64_MODIFIER is not + * defined if INT64_MAX is not defined. These are an extension + * beyond what C99 specifies must be in stdint.h. + * + * In addition, the following macros are defined: + * + * PRINTF_INTMAX_HEX_WIDTH + * PRINTF_INT64_HEX_WIDTH + * PRINTF_INT32_HEX_WIDTH + * PRINTF_INT16_HEX_WIDTH + * PRINTF_INT8_HEX_WIDTH + * PRINTF_INTMAX_DEC_WIDTH + * PRINTF_INT64_DEC_WIDTH + * PRINTF_INT32_DEC_WIDTH + * PRINTF_INT16_DEC_WIDTH + * PRINTF_INT8_DEC_WIDTH + * + * Which specifies the maximum number of characters required to + * print the number of that type in either hexadecimal or decimal. + * These are an extension beyond what C99 specifies must be in + * stdint.h. + * + * Compilers tested (all with 0 warnings at their highest respective + * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 + * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio + * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 + * + * This file should be considered a work in progress. Suggestions for + * improvements, especially those which increase coverage are strongly + * encouraged. + * + * Acknowledgements + * + * The following people have made significant contributions to the + * development and testing of this file: + * + * Chris Howie + * John Steele Scott + * Dave Thorup + * John Dill + * + */ + +#include +#include +#include + +/* + * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and + * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. + */ + +#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED) +#include +#define _PSTDINT_H_INCLUDED +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +# endif +# ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +# endif +# ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +# endif +# ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +# endif +# ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "20" +# endif +# ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +# endif +# ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +# endif +# ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif + +/* + * Something really weird is going on with Open Watcom. Just pull some of + * these duplicated definitions from Open Watcom's stdint.h file for now. + */ + +# if defined (__WATCOMC__) && __WATCOMC__ >= 1250 +# if !defined (INT64_C) +# define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) +# endif +# if !defined (UINT64_C) +# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) +# endif +# if !defined (INT32_C) +# define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) +# endif +# if !defined (UINT32_C) +# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) +# endif +# if !defined (INT16_C) +# define INT16_C(x) (x) +# endif +# if !defined (UINT16_C) +# define UINT16_C(x) (x) +# endif +# if !defined (INT8_C) +# define INT8_C(x) (x) +# endif +# if !defined (UINT8_C) +# define UINT8_C(x) (x) +# endif +# if !defined (UINT64_MAX) +# define UINT64_MAX 18446744073709551615ULL +# endif +# if !defined (INT64_MAX) +# define INT64_MAX 9223372036854775807LL +# endif +# if !defined (UINT32_MAX) +# define UINT32_MAX 4294967295UL +# endif +# if !defined (INT32_MAX) +# define INT32_MAX 2147483647L +# endif +# if !defined (INTMAX_MAX) +# define INTMAX_MAX INT64_MAX +# endif +# if !defined (INTMAX_MIN) +# define INTMAX_MIN INT64_MIN +# endif +# endif +#endif + +#ifndef _PSTDINT_H_INCLUDED +#define _PSTDINT_H_INCLUDED + +#ifndef SIZE_MAX +# define SIZE_MAX (~(size_t)0) +#endif + +/* + * Deduce the type assignments from limits.h under the assumption that + * integer sizes in bits are powers of 2, and follow the ANSI + * definitions. + */ + +#ifndef UINT8_MAX +# define UINT8_MAX 0xff +#endif +#ifndef uint8_t +# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) + typedef unsigned char uint8_t; +# define UINT8_C(v) ((uint8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef INT8_MAX +# define INT8_MAX 0x7f +#endif +#ifndef INT8_MIN +# define INT8_MIN INT8_C(0x80) +#endif +#ifndef int8_t +# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) + typedef signed char int8_t; +# define INT8_C(v) ((int8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef UINT16_MAX +# define UINT16_MAX 0xffff +#endif +#ifndef uint16_t +#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) + typedef unsigned int uint16_t; +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +# define UINT16_C(v) ((uint16_t) (v)) +#elif (USHRT_MAX == UINT16_MAX) + typedef unsigned short uint16_t; +# define UINT16_C(v) ((uint16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT16_MAX +# define INT16_MAX 0x7fff +#endif +#ifndef INT16_MIN +# define INT16_MIN INT16_C(0x8000) +#endif +#ifndef int16_t +#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) + typedef signed int int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +#elif (SHRT_MAX == INT16_MAX) + typedef signed short int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef UINT32_MAX +# define UINT32_MAX (0xffffffffUL) +#endif +#ifndef uint32_t +#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) + typedef unsigned long uint32_t; +# define UINT32_C(v) v ## UL +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (UINT_MAX == UINT32_MAX) + typedef unsigned int uint32_t; +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +# define UINT32_C(v) v ## U +#elif (USHRT_MAX == UINT32_MAX) + typedef unsigned short uint32_t; +# define UINT32_C(v) ((unsigned short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT32_MAX +# define INT32_MAX (0x7fffffffL) +#endif +#ifndef INT32_MIN +# define INT32_MIN INT32_C(0x80000000) +#endif +#ifndef int32_t +#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) + typedef signed long int32_t; +# define INT32_C(v) v ## L +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (INT_MAX == INT32_MAX) + typedef signed int int32_t; +# define INT32_C(v) v +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#elif (SHRT_MAX == INT32_MAX) + typedef signed short int32_t; +# define INT32_C(v) ((short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +/* + * The macro stdint_int64_defined is temporarily used to record + * whether or not 64 integer support is available. It must be + * defined for any 64 integer extensions for new platforms that are + * added. + */ + +#undef stdint_int64_defined +#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) +# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# endif +#endif + +#if !defined (stdint_int64_defined) +# if defined(__GNUC__) +# define stdint_int64_defined + __extension__ typedef long long int64_t; + __extension__ typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) +# define stdint_int64_defined + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# define UINT64_C(v) v ## UI64 +# define INT64_C(v) v ## I64 +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "I64" +# endif +# endif +#endif + +#if !defined (LONG_LONG_MAX) && defined (INT64_C) +# define LONG_LONG_MAX INT64_C (9223372036854775807) +#endif +#ifndef ULONG_LONG_MAX +# define ULONG_LONG_MAX UINT64_C (18446744073709551615) +#endif + +#if !defined (INT64_MAX) && defined (INT64_C) +# define INT64_MAX INT64_C (9223372036854775807) +#endif +#if !defined (INT64_MIN) && defined (INT64_C) +# define INT64_MIN INT64_C (-9223372036854775808) +#endif +#if !defined (UINT64_MAX) && defined (INT64_C) +# define UINT64_MAX UINT64_C (18446744073709551615) +#endif + +/* + * Width of hexadecimal for number field. + */ + +#ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +#endif +#ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +#endif +#ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +#endif +#ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +#endif + +#ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "20" +#endif +#ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +#endif +#ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +#endif +#ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +#endif + +/* + * Ok, lets not worry about 128 bit integers for now. Moore's law says + * we don't need to worry about that until about 2040 at which point + * we'll have bigger things to worry about. + */ + +#ifdef stdint_int64_defined + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; +# define INTMAX_MAX INT64_MAX +# define INTMAX_MIN INT64_MIN +# define UINTMAX_MAX UINT64_MAX +# define UINTMAX_C(v) UINT64_C(v) +# define INTMAX_C(v) INT64_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif +#else + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# define INTMAX_MAX INT32_MAX +# define UINTMAX_MAX UINT32_MAX +# define UINTMAX_C(v) UINT32_C(v) +# define INTMAX_C(v) INT32_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH +# endif +#endif + +/* + * Because this file currently only supports platforms which have + * precise powers of 2 as bit sizes for the default integers, the + * least definitions are all trivial. Its possible that a future + * version of this file could have different definitions. + */ + +#ifndef stdint_least_defined + typedef int8_t int_least8_t; + typedef uint8_t uint_least8_t; + typedef int16_t int_least16_t; + typedef uint16_t uint_least16_t; + typedef int32_t int_least32_t; + typedef uint32_t uint_least32_t; +# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER +# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER +# define UINT_LEAST8_MAX UINT8_MAX +# define INT_LEAST8_MAX INT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define INT_LEAST16_MAX INT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# ifdef stdint_int64_defined + typedef int64_t int_least64_t; + typedef uint64_t uint_least64_t; +# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER +# define UINT_LEAST64_MAX UINT64_MAX +# define INT_LEAST64_MAX INT64_MAX +# define INT_LEAST64_MIN INT64_MIN +# endif +#endif +#undef stdint_least_defined + +/* + * The ANSI C committee pretending to know or specify anything about + * performance is the epitome of misguided arrogance. The mandate of + * this file is to *ONLY* ever support that absolute minimum + * definition of the fast integer types, for compatibility purposes. + * No extensions, and no attempt to suggest what may or may not be a + * faster integer type will ever be made in this file. Developers are + * warned to stay away from these types when using this or any other + * stdint.h. + */ + +typedef int_least8_t int_fast8_t; +typedef uint_least8_t uint_fast8_t; +typedef int_least16_t int_fast16_t; +typedef uint_least16_t uint_fast16_t; +typedef int_least32_t int_fast32_t; +typedef uint_least32_t uint_fast32_t; +#define UINT_FAST8_MAX UINT_LEAST8_MAX +#define INT_FAST8_MAX INT_LEAST8_MAX +#define UINT_FAST16_MAX UINT_LEAST16_MAX +#define INT_FAST16_MAX INT_LEAST16_MAX +#define UINT_FAST32_MAX UINT_LEAST32_MAX +#define INT_FAST32_MAX INT_LEAST32_MAX +#define INT_FAST8_MIN INT_LEAST8_MIN +#define INT_FAST16_MIN INT_LEAST16_MIN +#define INT_FAST32_MIN INT_LEAST32_MIN +#ifdef stdint_int64_defined + typedef int_least64_t int_fast64_t; + typedef uint_least64_t uint_fast64_t; +# define UINT_FAST64_MAX UINT_LEAST64_MAX +# define INT_FAST64_MAX INT_LEAST64_MAX +# define INT_FAST64_MIN INT_LEAST64_MIN +#endif + +#undef stdint_int64_defined + +/* + * Whatever piecemeal, per compiler thing we can do about the wchar_t + * type limits. + */ + +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) +# include +# ifndef WCHAR_MIN +# define WCHAR_MIN 0 +# endif +# ifndef WCHAR_MAX +# define WCHAR_MAX ((wchar_t)-1) +# endif +#endif + +/* + * Whatever piecemeal, per compiler/platform thing we can do about the + * (u)intptr_t types and limits. + */ + +#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED) +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +#ifndef STDINT_H_UINTPTR_T_DEFINED +# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) +# define stdint_intptr_bits 64 +# elif defined (__WATCOMC__) || defined (__TURBOC__) +# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) +# define stdint_intptr_bits 16 +# else +# define stdint_intptr_bits 32 +# endif +# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) +# define stdint_intptr_bits 32 +# elif defined (__INTEL_COMPILER) +/* TODO -- what did Intel do about x86-64? */ +# endif + +# ifdef stdint_intptr_bits +# define stdint_intptr_glue3_i(a,b,c) a##b##c +# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) +# ifndef PRINTF_INTPTR_MODIFIER +# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) +# endif +# ifndef PTRDIFF_MAX +# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef PTRDIFF_MIN +# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef UINTPTR_MAX +# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MAX +# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MIN +# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef INTPTR_C +# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) +# endif +# ifndef UINTPTR_C +# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) +# endif + typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; + typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; +# else +/* TODO -- This following is likely wrong for some platforms, and does + nothing for the definition of uintptr_t. */ + typedef ptrdiff_t intptr_t; +# endif +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +/* + * Assumes sig_atomic_t is signed and we have a 2s complement machine. + */ + +#ifndef SIG_ATOMIC_MAX +# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) +#endif + +#endif + +#if defined (__TEST_PSTDINT_FOR_CORRECTNESS) + +/* + * Please compile with the maximum warning settings to make sure macros are not + * defined more than once. + */ + +#include +#include +#include + +#define glue3_aux(x,y,z) x ## y ## z +#define glue3(x,y,z) glue3_aux(x,y,z) + +#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,=) glue3(UINT,bits,_C) (0); +#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,=) glue3(INT,bits,_C) (0); + +#define DECL(us,bits) glue3(DECL,us,) (bits) + +#define TESTUMAX(bits) glue3(u,bits,=) glue3(~,u,bits); if (glue3(UINT,bits,_MAX) glue3(!=,u,bits)) printf ("Something wrong with UINT%d_MAX\n", bits) + +int main () { + DECL(I,8) + DECL(U,8) + DECL(I,16) + DECL(U,16) + DECL(I,32) + DECL(U,32) +#ifdef INT64_MAX + DECL(I,64) + DECL(U,64) +#endif + intmax_t imax = INTMAX_C(0); + uintmax_t umax = UINTMAX_C(0); + char str0[256], str1[256]; + + sprintf (str0, "%d %x\n", 0, ~0); + + sprintf (str1, "%d %x\n", i8, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i8 : %s\n", str1); + sprintf (str1, "%u %x\n", u8, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with u8 : %s\n", str1); + sprintf (str1, "%d %x\n", i16, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i16 : %s\n", str1); + sprintf (str1, "%u %x\n", u16, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with u16 : %s\n", str1); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i32 : %s\n", str1); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with u32 : %s\n", str1); +#ifdef INT64_MAX + sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i64 : %s\n", str1); +#endif + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with imax : %s\n", str1); + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with umax : %s\n", str1); + + TESTUMAX(8); + TESTUMAX(16); + TESTUMAX(32); +#ifdef INT64_MAX + TESTUMAX(64); +#endif + + return EXIT_SUCCESS; +} + +#endif diff --git a/build/tools/HLSLcc/May_2014/license.txt b/build/tools/HLSLcc/May_2014/license.txt new file mode 100644 index 0000000..e20caee --- /dev/null +++ b/build/tools/HLSLcc/May_2014/license.txt @@ -0,0 +1,52 @@ +Copyright (c) 2012 James Jones +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. + +This software makes use of the bstring library which is provided under the following license: + +Copyright (c) 2002-2008 Paul Hsieh +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of bstrlib nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/build/tools/HLSLcc/May_2014/mk/CMakeLists.txt b/build/tools/HLSLcc/May_2014/mk/CMakeLists.txt new file mode 100644 index 0000000..bceb17b --- /dev/null +++ b/build/tools/HLSLcc/May_2014/mk/CMakeLists.txt @@ -0,0 +1,117 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +PROJECT (HLSLCrossCompilerProj C CXX) + +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "Release") +ENDIF(NOT CMAKE_BUILD_TYPE) + +IF( ${CMAKE_BUILD_TYPE} STREQUAL Debug ) + # CMAKE_C_FLAGS_DEBUG will also be added to CMAKE_C_FLAGS + MESSAGE( "Debug build" ) + ADD_DEFINITIONS(-DDEBUG -D_DEBUG -D__DEBUG__) +ENDIF() + +IF( BUILD_SHARED_LIBS) + MESSAGE("Dynamic libs") + ADD_DEFINITIONS(-DHLSLCC_DYNLIB) +ENDIF( BUILD_SHARED_LIBS ) + +SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin" ) +SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "../lib" ) + +#INCLUDE(TestBigEndian) + +#TEST_BIG_ENDIAN(BIG_ENDIAN_SYSTEM) + +IF(BIG_ENDIAN_SYSTEM) + MESSAGE("SETTING Big endian") + ADD_DEFINITIONS(-D__BIG_ENDIAN__) +ELSE() + MESSAGE("SETTING Little endian") + ADD_DEFINITIONS(-D__LITTLE_ENDIAN__) +ENDIF() + +IF(MSVC) + OPTION(USE_MSVC_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON) + IF(USE_MSVC_FAST_FLOATINGPOINT) + ADD_DEFINITIONS(/fp:fast) + ENDIF(USE_MSVC_FAST_FLOATINGPOINT) +ENDIF(MSVC) + +IF(WIN32) + ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS /WX /W3 /arch:SSE2) +ENDIF() + +INCLUDE_DIRECTORIES( ../include ../src/cbstring/ ../src/ ) + +file(GLOB CBSTRING_CFILES ../src/cbstring/*.c) +file(GLOB CBSTRING_HFILES ../src/cbstring/*.h) +source_group("CBString Files" FILES ${CBSTRING_CFILES} ${CBSTRING_HFILES}) + +SET(libHLSLcc_SOURCES +../src/internal_includes/debug.h +../src/internal_includes/decode.h +../src/internal_includes/languages.h +../include/pstdint.h +../src/internal_includes/reflect.h +../src/internal_includes/structs.h +../include/hlslcc.h +../src/internal_includes/toGLSLDeclaration.h +../src/internal_includes/toGLSLInstruction.h +../src/internal_includes/toGLSLOperand.h +../src/internal_includes/tokens.h +../src/internal_includes/tokensDX9.h +../src/internal_includes/shaderLimits.h +../src/internal_includes/hlslcc_malloc.h +../src/internal_includes/hlslcc_malloc.c +${CBSTRING_HFILES} +../src/decode.c +../src/decodeDX9.c +../src/reflect.c +../src/toGLSL.c +../src/toGLSLInstruction.c +../src/toGLSLOperand.c +../src/toGLSLDeclaration.c +${CBSTRING_CFILES} +) +ADD_LIBRARY( libHLSLcc ${libHLSLcc_SOURCES} ) + + +INCLUDE_DIRECTORIES( ../offline/cjson/ ) + +file(GLOB CJSON_CFILES ../offline/cjson/*.c) +file(GLOB CJSON_HFILES ../offline/cjson/*.h) +source_group("cJSON Files" FILES ${CJSON_CFILES} ${CJSON_HFILES}) + +SET(HLSLcc_SOURCES +../offline/toGLSLStandalone.cpp +../offline/timer.h +../offline/timer.cpp +../offline/hash.h +../offline/serializeReflection.cpp +../offline/serializeReflection.h +${CJSON_CFILES} +${CJSON_HFILES} +) + +ADD_EXECUTABLE( HLSLcc ${HLSLcc_SOURCES} ) + +# Compile 32-bit binaries for linux +IF(CMAKE_HOST_UNIX) + +ADD_LIBRARY( libHLSLcc-i386 ${libHLSLcc_SOURCES} ) +ADD_EXECUTABLE( HLSLcc-i386 ${HLSLcc_SOURCES} ) +TARGET_LINK_LIBRARIES( HLSLcc-i386 libHLSLcc-i386) +SET_TARGET_PROPERTIES(libHLSLcc-i386 PROPERTIES COMPILE_FLAGS -m32 LINK_FLAGS -m32 ) +SET_TARGET_PROPERTIES(HLSLcc-i386 PROPERTIES COMPILE_FLAGS -m32 LINK_FLAGS -m32 ) +ENDIF() + +TARGET_LINK_LIBRARIES( HLSLcc libHLSLcc) + +# force variables that could be defined on the cmdline +# to be written to the cach + +SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING +"One of None Debug Release RelWithDebInfo MinSizeRel" FORCE ) + diff --git a/build/tools/HLSLcc/May_2014/offline/cjson/cJSON.c b/build/tools/HLSLcc/May_2014/offline/cjson/cJSON.c new file mode 100644 index 0000000..ac1c7c9 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/cjson/cJSON.c @@ -0,0 +1,567 @@ +/* + Copyright (c) 2009 Dave Gamble + + 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. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" + +static const char *ep; + +const char *cJSON_GetErrorPtr(void) {return ep;} + +static int cJSON_strcasecmp(const char *s1,const char *s2) +{ + if (!s1) return (s1==s2)?0:1;if (!s2) return 1; + for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; + return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); +} + +static void *(*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void *ptr) = free; + +static char* cJSON_strdup(const char* str) +{ + size_t len; + char* copy; + + len = strlen(str) + 1; + if (!(copy = (char*)cJSON_malloc(len))) return 0; + memcpy(copy,str,len); + return copy; +} + +void cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; + cJSON_free = (hooks->free_fn)?hooks->free_fn:free; +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(void) +{ + cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + if (node) memset(node,0,sizeof(cJSON)); + return node; +} + +/* Delete a cJSON structure. */ +void cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) + { + next=c->next; + if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); + if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); + if (c->string) cJSON_free(c->string); + cJSON_free(c); + c=next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +static const char *parse_number(cJSON *item,const char *num) +{ + double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; + + /* Could use sscanf for this? */ + if (*num=='-') sign=-1,num++; /* Has sign? */ + if (*num=='0') num++; /* is zero */ + if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ + if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ + if (*num=='e' || *num=='E') /* Exponent? */ + { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ + while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ + } + + n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble=n; + item->valueint=(int)n; + item->type=cJSON_Number; + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char *print_number(cJSON *item) +{ + char *str; + double d=item->valuedouble; + if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) + { + str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) sprintf(str,"%d",item->valueint); + } + else + { + str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) + { + if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); + else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); + else sprintf(str,"%f",d); + } + } + return str; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char *parse_string(cJSON *item,const char *str) +{ + const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; + if (*str!='\"') {ep=str;return 0;} /* not a string! */ + + while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ + + out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ + if (!out) return 0; + + ptr=str+1;ptr2=out; + while (*ptr!='\"' && *ptr) + { + if (*ptr!='\\') *ptr2++=*ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++='\b'; break; + case 'f': *ptr2++='\f'; break; + case 'n': *ptr2++='\n'; break; + case 'r': *ptr2++='\r'; break; + case 't': *ptr2++='\t'; break; + case 'u': /* transcode utf16 to utf8. */ + sscanf(ptr+1,"%4x",&uc);ptr+=4; /* get the unicode char. */ + + if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ + + if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ + { + if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ + sscanf(ptr+3,"%4x",&uc2);ptr+=6; + if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ + uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); + } + + len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; + + switch (len) { + case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 1: *--ptr2 =(uc | firstByteMark[len]); + } + ptr2+=len; + break; + default: *ptr2++=*ptr; break; + } + ptr++; + } + } + *ptr2=0; + if (*ptr=='\"') ptr++; + item->valuestring=out; + item->type=cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char *print_string_ptr(const char *str) +{ + const char *ptr;char *ptr2,*out;int len=0;unsigned char token; + + if (!str) return cJSON_strdup(""); + ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} + + out=(char*)cJSON_malloc(len+3); + if (!out) return 0; + + ptr2=out;ptr=str; + *ptr2++='\"'; + while (*ptr) + { + if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; + else + { + *ptr2++='\\'; + switch (token=*ptr++) + { + case '\\': *ptr2++='\\'; break; + case '\"': *ptr2++='\"'; break; + case '\b': *ptr2++='b'; break; + case '\f': *ptr2++='f'; break; + case '\n': *ptr2++='n'; break; + case '\r': *ptr2++='r'; break; + case '\t': *ptr2++='t'; break; + default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ + } + } + } + *ptr2++='\"';*ptr2++=0; + return out; +} +/* Invote print_string_ptr (which is useful) on an item. */ +static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item,const char *value); +static char *print_value(cJSON *item,int depth,int fmt); +static const char *parse_array(cJSON *item,const char *value); +static char *print_array(cJSON *item,int depth,int fmt); +static const char *parse_object(cJSON *item,const char *value); +static char *print_object(cJSON *item,int depth,int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} + +/* Parse an object - create a new root, and populate. */ +cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) +{ + const char *end=0; + cJSON *c=cJSON_New_Item(); + ep=0; + if (!c) return 0; /* memory fail */ + + end=parse_value(c,skip(value)); + if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} + if (return_parse_end) *return_parse_end=end; + return c; +} +/* Default options for cJSON_Parse */ +cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} + +/* Render a cJSON item/entity/structure to text. */ +char *cJSON_Print(cJSON *item) {return print_value(item,0,1);} +char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);} + +/* Parser core - when encountering text, process appropriately. */ +static const char *parse_value(cJSON *item,const char *value) +{ + if (!value) return 0; /* Fail on null. */ + if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } + if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } + if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } + if (*value=='\"') { return parse_string(item,value); } + if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } + if (*value=='[') { return parse_array(item,value); } + if (*value=='{') { return parse_object(item,value); } + + ep=value;return 0; /* failure. */ +} + +/* Render a value to text. */ +static char *print_value(cJSON *item,int depth,int fmt) +{ + char *out=0; + if (!item) return 0; + switch ((item->type)&255) + { + case cJSON_NULL: out=cJSON_strdup("null"); break; + case cJSON_False: out=cJSON_strdup("false");break; + case cJSON_True: out=cJSON_strdup("true"); break; + case cJSON_Number: out=print_number(item);break; + case cJSON_String: out=print_string(item);break; + case cJSON_Array: out=print_array(item,depth,fmt);break; + case cJSON_Object: out=print_object(item,depth,fmt);break; + } + return out; +} + +/* Build an array from input text. */ +static const char *parse_array(cJSON *item,const char *value) +{ + cJSON *child; + if (*value!='[') {ep=value;return 0;} /* not an array! */ + + item->type=cJSON_Array; + value=skip(value+1); + if (*value==']') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; /* memory fail */ + value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_value(child,skip(value+1))); + if (!value) return 0; /* memory fail */ + } + + if (*value==']') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an array to text */ +static char *print_array(cJSON *item,int depth,int fmt) +{ + char **entries; + char *out=0,*ptr,*ret;int len=5; + cJSON *child=item->child; + int numentries=0,i=0,fail=0; + + /* How many entries in the array? */ + while (child) numentries++,child=child->next; + /* Explicitly handle numentries==0 */ + if (!numentries) + { + out=(char*)cJSON_malloc(3); + if (out) strcpy(out,"[]"); + return out; + } + /* Allocate an array to hold the values for each */ + entries=(char**)cJSON_malloc(numentries*sizeof(char*)); + if (!entries) return 0; + memset(entries,0,numentries*sizeof(char*)); + /* Retrieve all the results: */ + child=item->child; + while (child && !fail) + { + ret=print_value(child,depth+1,fmt); + entries[i++]=ret; + if (ret) len+=(int)strlen(ret)+2+(fmt?1:0); else fail=1; + child=child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + /* If that fails, we fail. */ + if (!out) fail=1; + + /* Handle failure. */ + if (fail) + { + for (i=0;itype=cJSON_Object; + value=skip(value+1); + if (*value=='}') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; + value=skip(parse_string(child,skip(value))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_string(child,skip(value+1))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + } + + if (*value=='}') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char *print_object(cJSON *item,int depth,int fmt) +{ + char **entries=0,**names=0; + char *out=0,*ptr,*ret,*str;int len=7,i=0,j; + cJSON *child=item->child; + int numentries=0,fail=0; + /* Count the number of entries. */ + while (child) numentries++,child=child->next; + /* Explicitly handle empty object case */ + if (!numentries) + { + out=(char*)cJSON_malloc(fmt?depth+3:3); + if (!out) return 0; + ptr=out;*ptr++='{'; + if (fmt) {*ptr++='\n';for (i=0;ichild;depth++;if (fmt) len+=depth; + while (child) + { + names[i]=str=print_string_ptr(child->string); + entries[i++]=ret=print_value(child,depth,fmt); + if (str && ret) len+=(int)(strlen(ret)+strlen(str))+2+(fmt?2+depth:0); else fail=1; + child=child->next; + } + + /* Try to allocate the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + if (!out) fail=1; + + /* Handle failure */ + if (fail) + { + for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} +cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} +cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} +/* Utility for handling references. */ +static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} + +/* Add item to array/object. */ +void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} +void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} +void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} +void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} + +cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; + if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} +void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} +cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} +void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} + +/* Replace array/object items with new ones. */ +void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; + newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; + if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} +void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} + +/* Create basic types: */ +cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} +cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} +cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} +cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} +cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} +cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} +cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} +cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} + +/* Create Arrays: */ +cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} + +/* Duplication */ +cJSON *cJSON_Duplicate(cJSON *item,int recurse) +{ + cJSON *newitem,*cptr,*nptr=0,*newchild; + /* Bail on bad ptr */ + if (!item) return 0; + /* Create new item */ + newitem=cJSON_New_Item(); + if (!newitem) return 0; + /* Copy over all vars */ + newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; + if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} + if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} + /* If non-recursive, then we're done! */ + if (!recurse) return newitem; + /* Walk the ->next chain for the child. */ + cptr=item->child; + while (cptr) + { + newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) {cJSON_Delete(newitem);return 0;} + if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ + cptr=cptr->next; + } + return newitem; +} diff --git a/build/tools/HLSLcc/May_2014/offline/cjson/cJSON.h b/build/tools/HLSLcc/May_2014/offline/cjson/cJSON.h new file mode 100644 index 0000000..1aefe09 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/cjson/cJSON.h @@ -0,0 +1,141 @@ +/* + Copyright (c) 2009 Dave Gamble + + 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 cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON { + struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ +} cJSON; + +typedef struct cJSON_Hooks { + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +extern void cJSON_InitHooks(cJSON_Hooks* hooks); + + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ +extern char *cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +extern const char *cJSON_GetErrorPtr(void); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(void); +extern cJSON *cJSON_CreateTrue(void); +extern cJSON *cJSON_CreateFalse(void); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(void); +extern cJSON *cJSON_CreateObject(void); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(int *numbers,int count); +extern cJSON *cJSON_CreateFloatArray(float *numbers,int count); +extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count); +extern cJSON *cJSON_CreateStringArray(const char **strings,int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); +extern void cJSON_DeleteItemFromArray(cJSON *array,int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ + +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); + +/* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/build/tools/HLSLcc/May_2014/offline/hash.h b/build/tools/HLSLcc/May_2014/offline/hash.h new file mode 100644 index 0000000..eeb439e --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/hash.h @@ -0,0 +1,125 @@ +#ifndef HASH_H_ +#define HASH_H_ + +/* +-------------------------------------------------------------------- +mix -- mix 3 64-bit values reversibly. +mix() takes 48 machine instructions, but only 24 cycles on a superscalar + machine (like Intel's new MMX architecture). It requires 4 64-bit + registers for 4::2 parallelism. +All 1-bit deltas, all 2-bit deltas, all deltas composed of top bits of + (a,b,c), and all deltas of bottom bits were tested. All deltas were + tested both on random keys and on keys that were nearly all zero. + These deltas all cause every bit of c to change between 1/3 and 2/3 + of the time (well, only 113/400 to 287/400 of the time for some + 2-bit delta). These deltas all cause at least 80 bits to change + among (a,b,c) when the mix is run either forward or backward (yes it + is reversible). +This implies that a hash using mix64 has no funnels. There may be + characteristics with 3-bit deltas or bigger, I didn't test for + those. +-------------------------------------------------------------------- +*/ +#define mix64(a,b,c) \ +{ \ + a -= b; a -= c; a ^= (c>>43); \ + b -= c; b -= a; b ^= (a<<9); \ + c -= a; c -= b; c ^= (b>>8); \ + a -= b; a -= c; a ^= (c>>38); \ + b -= c; b -= a; b ^= (a<<23); \ + c -= a; c -= b; c ^= (b>>5); \ + a -= b; a -= c; a ^= (c>>35); \ + b -= c; b -= a; b ^= (a<<49); \ + c -= a; c -= b; c ^= (b>>11); \ + a -= b; a -= c; a ^= (c>>12); \ + b -= c; b -= a; b ^= (a<<18); \ + c -= a; c -= b; c ^= (b>>22); \ +} + +/* +-------------------------------------------------------------------- +hash64() -- hash a variable-length key into a 64-bit value + k : the key (the unaligned variable-length array of bytes) + len : the length of the key, counting by bytes + level : can be any 8-byte value +Returns a 64-bit value. Every bit of the key affects every bit of +the return value. No funnels. Every 1-bit and 2-bit delta achieves +avalanche. About 41+5len instructions. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 64 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (ub1 **)k, do it like this: + for (i=0, h=0; i= 24) + { + a += (k[0] +((uint64_t)k[ 1]<< 8)+((uint64_t)k[ 2]<<16)+((uint64_t)k[ 3]<<24) + +((uint64_t)k[4 ]<<32)+((uint64_t)k[ 5]<<40)+((uint64_t)k[ 6]<<48)+((uint64_t)k[ 7]<<56)); + b += (k[8] +((uint64_t)k[ 9]<< 8)+((uint64_t)k[10]<<16)+((uint64_t)k[11]<<24) + +((uint64_t)k[12]<<32)+((uint64_t)k[13]<<40)+((uint64_t)k[14]<<48)+((uint64_t)k[15]<<56)); + c += (k[16] +((uint64_t)k[17]<< 8)+((uint64_t)k[18]<<16)+((uint64_t)k[19]<<24) + +((uint64_t)k[20]<<32)+((uint64_t)k[21]<<40)+((uint64_t)k[22]<<48)+((uint64_t)k[23]<<56)); + mix64(a,b,c); + k += 24; len -= 24; + } + + /*------------------------------------- handle the last 23 bytes */ + c += length; + switch(len) /* all the case statements fall through */ + { + case 23: c+=((uint64_t)k[22]<<56); + case 22: c+=((uint64_t)k[21]<<48); + case 21: c+=((uint64_t)k[20]<<40); + case 20: c+=((uint64_t)k[19]<<32); + case 19: c+=((uint64_t)k[18]<<24); + case 18: c+=((uint64_t)k[17]<<16); + case 17: c+=((uint64_t)k[16]<<8); + /* the first byte of c is reserved for the length */ + case 16: b+=((uint64_t)k[15]<<56); + case 15: b+=((uint64_t)k[14]<<48); + case 14: b+=((uint64_t)k[13]<<40); + case 13: b+=((uint64_t)k[12]<<32); + case 12: b+=((uint64_t)k[11]<<24); + case 11: b+=((uint64_t)k[10]<<16); + case 10: b+=((uint64_t)k[ 9]<<8); + case 9: b+=((uint64_t)k[ 8]); + case 8: a+=((uint64_t)k[ 7]<<56); + case 7: a+=((uint64_t)k[ 6]<<48); + case 6: a+=((uint64_t)k[ 5]<<40); + case 5: a+=((uint64_t)k[ 4]<<32); + case 4: a+=((uint64_t)k[ 3]<<24); + case 3: a+=((uint64_t)k[ 2]<<16); + case 2: a+=((uint64_t)k[ 1]<<8); + case 1: a+=((uint64_t)k[ 0]); + /* case 0: nothing left to add */ + } + mix64(a,b,c); + /*-------------------------------------------- report the result */ + return c; +} + +#endif diff --git a/build/tools/HLSLcc/May_2014/offline/serializeReflection.cpp b/build/tools/HLSLcc/May_2014/offline/serializeReflection.cpp new file mode 100644 index 0000000..4f43337 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/serializeReflection.cpp @@ -0,0 +1,204 @@ +#include "serializeReflection.h" +#include "cJSON.h" +#include +#include + +void* jsonMalloc(size_t sz) +{ + return new char[sz]; +} +void jsonFree(void* ptr) +{ + char* charPtr = static_cast(ptr); + delete [] charPtr; +} + +static void AppendIntToString(std::string& str, uint32_t num) +{ + std::stringstream ss; + ss << num; + str += ss.str(); +} + +static void WriteInOutSignature(InOutSignature* psSignature, cJSON* obj) +{ + cJSON_AddItemToObject(obj, "SemanticName", cJSON_CreateString(psSignature->SemanticName)); + cJSON_AddItemToObject(obj, "ui32SemanticIndex", cJSON_CreateNumber(psSignature->ui32SemanticIndex)); + cJSON_AddItemToObject(obj, "eSystemValueType", cJSON_CreateNumber(psSignature->eSystemValueType)); + cJSON_AddItemToObject(obj, "eComponentType", cJSON_CreateNumber(psSignature->eComponentType)); + cJSON_AddItemToObject(obj, "ui32Register", cJSON_CreateNumber(psSignature->ui32Register)); + cJSON_AddItemToObject(obj, "ui32Mask", cJSON_CreateNumber(psSignature->ui32Mask)); + cJSON_AddItemToObject(obj, "ui32ReadWriteMask", cJSON_CreateNumber(psSignature->ui32ReadWriteMask)); +} + +static void WriteResourceBinding(ResourceBinding* psBinding, cJSON* obj) +{ + cJSON_AddItemToObject(obj, "Name", cJSON_CreateString(psBinding->Name)); + cJSON_AddItemToObject(obj, "eType", cJSON_CreateNumber(psBinding->eType)); + cJSON_AddItemToObject(obj, "ui32BindPoint", cJSON_CreateNumber(psBinding->ui32BindPoint)); + cJSON_AddItemToObject(obj, "ui32BindCount", cJSON_CreateNumber(psBinding->ui32BindCount)); + cJSON_AddItemToObject(obj, "ui32Flags", cJSON_CreateNumber(psBinding->ui32Flags)); + cJSON_AddItemToObject(obj, "eDimension", cJSON_CreateNumber(psBinding->eDimension)); + cJSON_AddItemToObject(obj, "ui32ReturnType", cJSON_CreateNumber(psBinding->ui32ReturnType)); + cJSON_AddItemToObject(obj, "ui32NumSamples", cJSON_CreateNumber(psBinding->ui32NumSamples)); +} + +static void WriteShaderVar(ShaderVar* psVar, cJSON* obj) +{ + cJSON_AddItemToObject(obj, "Name", cJSON_CreateString(psVar->Name)); + if(psVar->haveDefaultValue) + { + cJSON_AddItemToObject(obj, "aui32DefaultValues", cJSON_CreateIntArray((int*)psVar->pui32DefaultValues, psVar->ui32Size/4)); + } + cJSON_AddItemToObject(obj, "ui32StartOffset", cJSON_CreateNumber(psVar->ui32StartOffset)); + cJSON_AddItemToObject(obj, "ui32Size", cJSON_CreateNumber(psVar->ui32Size)); +} + +static void WriteConstantBuffer(ConstantBuffer* psCBuf, cJSON* obj) +{ + cJSON_AddItemToObject(obj, "Name", cJSON_CreateString(psCBuf->Name)); + cJSON_AddItemToObject(obj, "ui32NumVars", cJSON_CreateNumber(psCBuf->ui32NumVars)); + + for(uint32_t i = 0; i < psCBuf->ui32NumVars; ++i) + { + std::string name; + name += "var"; + AppendIntToString(name, i); + + cJSON* varObj = cJSON_CreateObject(); + cJSON_AddItemToObject(obj, name.c_str(), varObj); + + WriteShaderVar(&psCBuf->asVars[i], varObj); + } + + cJSON_AddItemToObject(obj, "ui32TotalSizeInBytes", cJSON_CreateNumber(psCBuf->ui32TotalSizeInBytes)); +} + +static void WriteClassType(ClassType* psClassType, cJSON* obj) +{ + cJSON_AddItemToObject(obj, "Name", cJSON_CreateString(psClassType->Name)); + cJSON_AddItemToObject(obj, "ui16ID", cJSON_CreateNumber(psClassType->ui16ID)); + cJSON_AddItemToObject(obj, "ui16ConstBufStride", cJSON_CreateNumber(psClassType->ui16ConstBufStride)); + cJSON_AddItemToObject(obj, "ui16Texture", cJSON_CreateNumber(psClassType->ui16Texture)); + cJSON_AddItemToObject(obj, "ui16Sampler", cJSON_CreateNumber(psClassType->ui16Sampler)); +} + +static void WriteClassInstance(ClassInstance* psClassInst, cJSON* obj) +{ + cJSON_AddItemToObject(obj, "Name", cJSON_CreateString(psClassInst->Name)); + cJSON_AddItemToObject(obj, "ui16ID", cJSON_CreateNumber(psClassInst->ui16ID)); + cJSON_AddItemToObject(obj, "ui16ConstBuf", cJSON_CreateNumber(psClassInst->ui16ConstBuf)); + cJSON_AddItemToObject(obj, "ui16ConstBufOffset", cJSON_CreateNumber(psClassInst->ui16ConstBufOffset)); + cJSON_AddItemToObject(obj, "ui16Texture", cJSON_CreateNumber(psClassInst->ui16Texture)); + cJSON_AddItemToObject(obj, "ui16Sampler", cJSON_CreateNumber(psClassInst->ui16Sampler)); +} + +const char* SerializeReflection(ShaderInfo* psReflection) +{ + cJSON* root; + + cJSON_Hooks hooks; + hooks.malloc_fn = jsonMalloc; + hooks.free_fn = jsonFree; + cJSON_InitHooks(&hooks); + + root=cJSON_CreateObject(); + cJSON_AddItemToObject(root, "ui32MajorVersion", cJSON_CreateNumber(psReflection->ui32MajorVersion)); + cJSON_AddItemToObject(root, "ui32MinorVersion", cJSON_CreateNumber(psReflection->ui32MinorVersion)); + + cJSON_AddItemToObject(root, "ui32NumInputSignatures", cJSON_CreateNumber(psReflection->ui32NumInputSignatures)); + + for(uint32_t i = 0; i < psReflection->ui32NumInputSignatures; ++i) + { + std::string name; + name += "input"; + AppendIntToString(name, i); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddItemToObject(root, name.c_str(), obj); + + WriteInOutSignature(psReflection->psInputSignatures+i, obj); + } + + cJSON_AddItemToObject(root, "ui32NumOutputSignatures", cJSON_CreateNumber(psReflection->ui32NumOutputSignatures)); + + for(uint32_t i = 0; i < psReflection->ui32NumOutputSignatures; ++i) + { + std::string name; + name += "output"; + AppendIntToString(name, i); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddItemToObject(root, name.c_str(), obj); + + WriteInOutSignature(psReflection->psOutputSignatures+i, obj); + } + + cJSON_AddItemToObject(root, "ui32NumResourceBindings", cJSON_CreateNumber(psReflection->ui32NumResourceBindings)); + + for(uint32_t i = 0; i < psReflection->ui32NumResourceBindings; ++i) + { + std::string name; + name += "resource"; + AppendIntToString(name, i); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddItemToObject(root, name.c_str(), obj); + + WriteResourceBinding(psReflection->psResourceBindings+i, obj); + } + + cJSON_AddItemToObject(root, "ui32NumConstantBuffers", cJSON_CreateNumber(psReflection->ui32NumConstantBuffers)); + + for(uint32_t i = 0; i < psReflection->ui32NumConstantBuffers; ++i) + { + std::string name; + name += "cbuf"; + AppendIntToString(name, i); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddItemToObject(root, name.c_str(), obj); + + WriteConstantBuffer(psReflection->psConstantBuffers+i, obj); + } + + //psThisPointerConstBuffer is a cache. Don't need to write this out. + //It just points to the $ThisPointer cbuffer within the psConstantBuffers array. + + for(uint32_t i = 0; i < psReflection->ui32NumClassTypes; ++i) + { + std::string name; + name += "classType"; + AppendIntToString(name, i); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddItemToObject(root, name.c_str(), obj); + + WriteClassType(psReflection->psClassTypes+i, obj); + } + + for(uint32_t i = 0; i < psReflection->ui32NumClassInstances; ++i) + { + std::string name; + name += "classInst"; + AppendIntToString(name, i); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddItemToObject(root, name.c_str(), obj); + + WriteClassInstance(psReflection->psClassInstances+i, obj); + } + + //psReflection->aui32TableIDToTypeID + //psReflection->aui32ConstBufferBindpointRemap + + cJSON_AddItemToObject(root, "eTessPartitioning", cJSON_CreateNumber(psReflection->eTessPartitioning)); + cJSON_AddItemToObject(root, "eTessOutPrim", cJSON_CreateNumber(psReflection->eTessOutPrim)); + + + const char* jsonString = cJSON_Print(root); + + cJSON_Delete(root); + + return jsonString; +} diff --git a/build/tools/HLSLcc/May_2014/offline/serializeReflection.h b/build/tools/HLSLcc/May_2014/offline/serializeReflection.h new file mode 100644 index 0000000..495e5b8 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/serializeReflection.h @@ -0,0 +1,8 @@ +#ifndef SERIALIZE_REFLECTION_H_ +#define SERIALIZE_REFLECTION_H_ + +#include "hlslcc.h" + +const char* SerializeReflection(ShaderInfo* psReflection); + +#endif diff --git a/build/tools/HLSLcc/May_2014/offline/timer.cpp b/build/tools/HLSLcc/May_2014/offline/timer.cpp new file mode 100644 index 0000000..ac7858b --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/timer.cpp @@ -0,0 +1,37 @@ +#include "timer.h" + +void InitTimer(Timer_t* psTimer) +{ +#if defined(_WIN32) + QueryPerformanceFrequency(&psTimer->frequency); +#endif +} + +void ResetTimer(Timer_t* psTimer) +{ +#if defined(_WIN32) + QueryPerformanceCounter(&psTimer->startCount); +#else + gettimeofday(&psTimer->startCount, 0); +#endif +} + +/* Returns time in micro seconds */ +double ReadTimer(Timer_t* psTimer) +{ + double startTimeInMicroSec, endTimeInMicroSec; + +#if defined(_WIN32) + const double freq = (1000000.0 / psTimer->frequency.QuadPart); + QueryPerformanceCounter(&psTimer->endCount); + startTimeInMicroSec = psTimer->startCount.QuadPart * freq; + endTimeInMicroSec = psTimer->endCount.QuadPart * freq; +#else + gettimeofday(&psTimer->endCount, 0); + startTimeInMicroSec = (psTimer->startCount.tv_sec * 1000000.0) + psTimer->startCount.tv_usec; + endTimeInMicroSec = (psTimer->endCount.tv_sec * 1000000.0) + psTimer->endCount.tv_usec; +#endif + + return endTimeInMicroSec - startTimeInMicroSec; +} + diff --git a/build/tools/HLSLcc/May_2014/offline/timer.h b/build/tools/HLSLcc/May_2014/offline/timer.h new file mode 100644 index 0000000..05d6b0f --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/timer.h @@ -0,0 +1,26 @@ +#ifndef TIMER_H +#define TIMER_H + +#ifdef _WIN32 +#include +#else +#include +#endif + +typedef struct +{ +#ifdef _WIN32 + LARGE_INTEGER frequency; + LARGE_INTEGER startCount; + LARGE_INTEGER endCount; +#else + struct timeval startCount; + struct timeval endCount; +#endif +} Timer_t; + +void InitTimer(Timer_t* psTimer); +void ResetTimer(Timer_t* psTimer); +double ReadTimer(Timer_t* psTimer); + +#endif diff --git a/build/tools/HLSLcc/May_2014/offline/toGLSLStandalone.cpp b/build/tools/HLSLcc/May_2014/offline/toGLSLStandalone.cpp new file mode 100644 index 0000000..4cdb2a6 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/offline/toGLSLStandalone.cpp @@ -0,0 +1,677 @@ + +#include "hlslcc.hpp" +#include "stdlib.h" +#include "stdio.h" +#include +#include +#include "hash.h" +#include "serializeReflection.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "timer.h" + +#if defined(_WIN32) +#define VALIDATE_OUTPUT +#endif + +#if defined(VALIDATE_OUTPUT) +#if defined(_WIN32) +#include +#include + + #pragma comment(lib, "opengl32.lib") + + typedef char GLcharARB; /* native character */ + typedef unsigned int GLhandleARB; /* shader object handle */ +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 + typedef void (WINAPI * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); + typedef GLhandleARB (WINAPI * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); + typedef void (WINAPI * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); + typedef void (WINAPI * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); + typedef void (WINAPI * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); + typedef void (WINAPI * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); + typedef GLhandleARB (WINAPI * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); + typedef void (WINAPI * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); + typedef void (WINAPI * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); + typedef void (WINAPI * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); + typedef void (WINAPI * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLcharARB* infoLog); + + static PFNGLDELETEOBJECTARBPROC glDeleteObjectARB; + static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB; + static PFNGLSHADERSOURCEARBPROC glShaderSourceARB; + static PFNGLCOMPILESHADERARBPROC glCompileShaderARB; + static PFNGLGETINFOLOGARBPROC glGetInfoLogARB; + static PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; + static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB; + static PFNGLATTACHOBJECTARBPROC glAttachObjectARB; + static PFNGLLINKPROGRAMARBPROC glLinkProgramARB; + static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB; + static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; + +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#define ERROR_INVALID_PROFILE_ARB 0x2096 + +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 + +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); +static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; + +void InitOpenGL() +{ + HGLRC rc; + + // setup minimal required GL + HWND wnd = CreateWindowA( + "STATIC", + "GL", + WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + 0, 0, 16, 16, + NULL, NULL, + GetModuleHandle(NULL), NULL ); + HDC dc = GetDC( wnd ); + + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, + PFD_TYPE_RGBA, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 16, 0, + 0, PFD_MAIN_PLANE, 0, 0, 0, 0 + }; + + int fmt = ChoosePixelFormat( dc, &pfd ); + SetPixelFormat( dc, fmt, &pfd ); + + rc = wglCreateContext( dc ); + wglMakeCurrent( dc, rc ); + + wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + + if(wglCreateContextAttribsARB) + { + const int OpenGLContextAttribs [] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + #if defined(_DEBUG) + //WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | WGL_CONTEXT_DEBUG_BIT_ARB, + #else + //WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + #endif + //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0, 0 + }; + + const HGLRC OpenGLContext = wglCreateContextAttribsARB( dc, 0, OpenGLContextAttribs ); + + wglMakeCurrent(dc, OpenGLContext); + + wglDeleteContext(rc); + + rc = OpenGLContext; + } + + glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)wglGetProcAddress("glDeleteObjectARB"); + glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB"); + glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB"); + glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB"); + glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB"); + glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB"); + glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB"); + glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB"); + glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB"); + glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog"); +} +#endif + +int TryCompileShader(GLenum eGLSLShaderType, const char* inFilename, char* shader, double* pCompileTime) +{ + GLint iCompileStatus; + GLuint hShader; + Timer_t timer; + + InitTimer(&timer); + + InitOpenGL(); + + hShader = glCreateShaderObjectARB(eGLSLShaderType); + glShaderSourceARB(hShader, 1, (const char **)&shader, NULL); + + ResetTimer(&timer); + glCompileShaderARB(hShader); + *pCompileTime = ReadTimer(&timer); + + /* Check it compiled OK */ + glGetObjectParameterivARB (hShader, GL_OBJECT_COMPILE_STATUS_ARB, &iCompileStatus); + + if (iCompileStatus != GL_TRUE) + { + FILE* errorFile; + GLint iInfoLogLength = 0; + char* pszInfoLog; + std::string filename; + + filename += inFilename; + + glGetObjectParameterivARB (hShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &iInfoLogLength); + + pszInfoLog = new char[iInfoLogLength]; + + printf("Error: Failed to compile GLSL shader\n"); + + glGetInfoLogARB (hShader, iInfoLogLength, NULL, pszInfoLog); + + printf(pszInfoLog); + + filename += "_compileErrors.txt"; + + //Dump to file + errorFile = fopen(filename.c_str(), "w"); + fprintf(errorFile, shader); + fprintf(errorFile, pszInfoLog); + fclose(errorFile); + + delete [] pszInfoLog; + + return 0; + } + + return 1; +} +#endif + +int fileExists(const char* path) +{ + FILE* shaderFile; + shaderFile = fopen(path, "rb"); + + if(shaderFile) + { + fclose(shaderFile); + return 1; + } + return 0; +} + +GLLang LanguageFromString(const char* str) +{ + if(strcmp(str, "es100")==0) + { + return LANG_ES_100; + } + if(strcmp(str, "es300")==0) + { + return LANG_ES_300; + } + if(strcmp(str, "es310")==0) + { + return LANG_ES_310; + } + if(strcmp(str, "120")==0) + { + return LANG_120; + } + if(strcmp(str, "130")==0) + { + return LANG_130; + } + if(strcmp(str, "140")==0) + { + return LANG_140; + } + if(strcmp(str, "150")==0) + { + return LANG_150; + } + if(strcmp(str, "330")==0) + { + return LANG_330; + } + if(strcmp(str, "400")==0) + { + return LANG_400; + } + if(strcmp(str, "410")==0) + { + return LANG_410; + } + if(strcmp(str, "420")==0) + { + return LANG_420; + } + if(strcmp(str, "430")==0) + { + return LANG_430; + } + if(strcmp(str, "440")==0) + { + return LANG_440; + } + return LANG_DEFAULT; +} + +#define MAX_PATH_CHARS 256 + +typedef struct +{ + GLLang language; + + int flags; + + const char* shaderFile; + char* outputShaderFile; + + int numLinkShaders; + char linkIn[5][MAX_PATH_CHARS]; + char linkOut[5][MAX_PATH_CHARS]; + + char* reflectPath; + + char cacheKey[MAX_PATH_CHARS]; +} Options; + +void InitOptions(Options* psOptions) +{ + psOptions->language = LANG_DEFAULT; + psOptions->flags = 0; + psOptions->numLinkShaders = 0; + psOptions->reflectPath = NULL; + + psOptions->shaderFile = NULL; + + psOptions->linkIn[0][0] = 0; + psOptions->linkIn[1][0] = 0; + psOptions->linkIn[2][0] = 0; + psOptions->linkIn[3][0] = 0; + psOptions->linkIn[4][0] = 0; + + psOptions->linkOut[0][0] = 0; + psOptions->linkOut[1][0] = 0; + psOptions->linkOut[2][0] = 0; + psOptions->linkOut[3][0] = 0; + psOptions->linkOut[4][0] = 0; +} + +void PrintHelp() +{ + printf("Command line options:\n"); + + printf("\t-lang=X \t GLSL language to use. e.g. es100 or 140.\n"); + printf("\t-flags=X \t The integer value of the HLSLCC_FLAGS to used.\n"); + printf("\t-reflect=X \t File to write reflection JSON to.\n"); + printf("\t-in=X \t Shader file to compile.\n"); + printf("\t-out=X \t File to write the compiled shader from -in to.\n"); + + printf("\t-linkin=X Semicolon-separated shader list. Max one per stage. Pixel shader should be given first. Hull (if present) should come before domain.\n"); + printf("\t-linkout=X Semicolon-separated list of output files to write the compilition result of -linkin shaders to.\n"); + + printf("\t-hashout=[dir/]out-file-name \t Output file name is a hash of 'out-file-name', put in the directory 'dir'.\n"); + printf("\t-hashlinkout=X Semicolon-separated list of output files to write the compilition result of -linkin shaders to. The basepath is a hash of all the file names given.\n"); + printf("\n"); +} + +int GetOptions(int argc, char** argv, Options* psOptions) +{ + int i; + int fullShaderChain = -1; + int hashOut = 0; + + InitOptions(psOptions); + + for(i=1; ireflectPath = option + strlen("-reflect="); + } + + option = strstr(argv[i],"-lang="); + if(option != NULL) + { + psOptions->language = LanguageFromString((&option[strlen("-lang=")])); + } + + option = strstr(argv[i],"-flags="); + if(option != NULL) + { + psOptions->flags = atol(&option[strlen("-flags=")]); + } + + option = strstr(argv[i],"-in="); + if(option != NULL) + { + fullShaderChain = 0; + psOptions->shaderFile = option + strlen("-in="); + if(!fileExists(psOptions->shaderFile)) + { + printf("Invalid path: %s\n", psOptions->shaderFile); + return 0; + } + } + + option = strstr(argv[i],"-out="); + if(option != NULL) + { + fullShaderChain = 0; + psOptions->outputShaderFile = option + strlen("-out="); + } + + option = strstr(argv[i],"-hashout"); + if(option != NULL) + { + fullShaderChain = 0; + psOptions->outputShaderFile = option + strlen("-hashout="); + + char* dir; + int64_t length; + + uint64_t hash = hash64((const uint8_t*)psOptions->outputShaderFile, (uint32_t)strlen(psOptions->outputShaderFile), 0); + + uint32_t high = (uint32_t)( hash >> 32 ); + uint32_t low = (uint32_t)( hash & 0x00000000FFFFFFFF ); + + dir = strrchr(psOptions->outputShaderFile, '\\'); + + if(!dir) + { + dir = strrchr(psOptions->outputShaderFile, '//'); + } + + if(!dir) + { + length = 0; + } + else + { + length = (dir-psOptions->outputShaderFile) + 1; + } + + for(i=0; i< length;++i) + { + psOptions->cacheKey[i] = psOptions->outputShaderFile[i]; + } + + //sprintf(psOptions->cacheKey, "%x%x", high, low); + sprintf(&psOptions->cacheKey[i], "%010llX", hash); + + psOptions->outputShaderFile = psOptions->cacheKey; + } + + //Semicolon-separated list of shader files to compile + //Any dependencies between these shaders will be handled + //so that they can be linked together into a monolithic program. + //If using separate_shader_objects with GLSL 430 or later then -linkin + //is only needed for hull and domain tessellation shaders - not doing + //so risks incorrect layout qualifiers in domain shaders. + option = strstr(argv[i],"-linkin="); + if(option != NULL) + { + const char* cter; + int shaderIndex = 0; + int writeIndex = 0; + + cter = option + strlen("-linkin="); + + while(cter[0] != '\0') + { + if(cter[0] == ';') + { + psOptions->linkIn[shaderIndex][writeIndex] = '\0'; + shaderIndex++; + writeIndex = 0; + cter++; + } + + if(shaderIndex < 5 && writeIndex < MAX_PATH_CHARS) + { + psOptions->linkIn[shaderIndex][writeIndex++] = cter[0]; + } + + cter++; + } + + psOptions->linkIn[shaderIndex][writeIndex] = '\0'; + + psOptions->numLinkShaders = shaderIndex+1; + + fullShaderChain = 1; + } + + option = strstr(argv[i],"-linkout="); + if(option != NULL) + { + const char* cter; + int shaderIndex = 0; + int writeIndex = 0; + + cter = option + strlen("-linkout="); + + while(cter[0] != '\0') + { + if(cter[0] == ';') + { + psOptions->linkOut[shaderIndex][writeIndex] = '\0'; + shaderIndex++; + writeIndex = 0; + cter++; + } + + if(shaderIndex < 5 && writeIndex < MAX_PATH_CHARS) + { + psOptions->linkOut[shaderIndex][writeIndex++] = cter[0]; + } + + cter++; + } + + psOptions->linkOut[shaderIndex][writeIndex] = '\0'; + } + + option = strstr(argv[i],"-hashlinkout="); + if(option != NULL) + { + const char* cter; + const char* fullList; + int shaderIndex = 0; + int writeIndex = 0; + + char files[5][MAX_PATH_CHARS]; + + fullList = option + strlen("-hashlinkout="); + cter = fullList; + + while(cter[0] != '\0') + { + if(cter[0] == ';') + { + files[shaderIndex][writeIndex] = '\0'; + shaderIndex++; + writeIndex = 0; + cter++; + } + + if(shaderIndex < 5 && writeIndex < MAX_PATH_CHARS) + { + files[shaderIndex][writeIndex++] = cter[0]; + } + + cter++; + } + + files[shaderIndex][writeIndex] = '\0'; + + + uint64_t hash = hash64((const uint8_t*)fullList, (uint32_t)strlen(fullList), 0); + + uint32_t high = (uint32_t)( hash >> 32 ); + uint32_t low = (uint32_t)( hash & 0x00000000FFFFFFFF ); + + for(int i=0; i < shaderIndex+1; ++i) + { + char dir[MAX_PATH_CHARS]; + char fullDir[MAX_PATH_CHARS]; //includes hash + + char* separatorPtr = strrchr(&files[i][0], '\\'); + + if(!separatorPtr) + { + separatorPtr = strrchr(&files[i][0], '//'); + } + + char* file = separatorPtr + 1; + + size_t k = 0; + const size_t dirChars = (size_t)(separatorPtr-&files[i][0]); + for(; k < dirChars; ++k) + { + dir[k] = files[i][k]; + } + + dir[k] = '\0'; + + sprintf(&fullDir[0], "%s//%010llX", dir, hash); + +#if defined(_WIN32) + _mkdir(fullDir); +#else + mkdir(fullDir, 0777); +#endif + + //outdir/hash/fileA...fileB + sprintf(&psOptions->linkOut[i][0], "%s//%s", fullDir, file); + } + } + } + + return 1; +} + +void *malloc_hook(size_t size) +{ + return malloc(size); +} +void *calloc_hook(size_t num,size_t size) +{ + return calloc(num,size); +} +void *realloc_hook(void *p,size_t size) +{ + return realloc(p,size); +} +void free_hook(void *p) +{ + free(p); +} + +int Run(const char* srcPath, const char* destPath, GLLang language, int flags, const char* reflectPath, GLSLCrossDependencyData* dependencies) +{ + FILE* outputFile; + GLSLShader result; + Timer_t timer; + int compiledOK = 0; + double crossCompileTime = 0; + double glslCompileTime = 0; + + HLSLcc_SetMemoryFunctions(malloc_hook,calloc_hook,free_hook,realloc_hook); + + InitTimer(&timer); + + ResetTimer(&timer); + GlExtensions ext; + ext.ARB_explicit_attrib_location = 0; + ext.ARB_explicit_uniform_location = 0; + ext.ARB_shading_language_420pack = 0; + compiledOK = TranslateHLSLFromFile(srcPath, flags, language, &ext , dependencies, &result); + crossCompileTime = ReadTimer(&timer); + + if(compiledOK) + { + //printf("cc time: %.2f us\n", crossCompileTime); + + if(destPath) + { + //Dump to file + outputFile = fopen(destPath, "w"); + fprintf(outputFile, result.sourceCode); + fclose(outputFile); + } + + if(reflectPath) + { + const char* jsonString = SerializeReflection(&result.reflection); + outputFile = fopen(reflectPath, "w"); + fprintf(outputFile, jsonString); + fclose(outputFile); + } + +#if defined(VALIDATE_OUTPUT) + compiledOK = TryCompileShader(result.shaderType, destPath ? destPath : "", result.sourceCode, &glslCompileTime); + + if(compiledOK) + { + //printf("glsl time: %.2f us\n", glslCompileTime); + } +#endif + + FreeGLSLShader(&result); + } + + return compiledOK; +} + +int main(int argc, char** argv) +{ + Options options; + int i; + + if(!GetOptions(argc, argv, &options)) + { + return 1; + } + + if(options.shaderFile) + { + if(!Run(options.shaderFile, options.outputShaderFile, options.language, options.flags, options.reflectPath, NULL)) + { + return 1; + } + } + + GLSLCrossDependencyData depends; + for(i=0; i +#include +#include "bsafe.h" + +static int bsafeShouldExit = 1; + +#if 0 +char * strcpy (char *dst, const char *src); +char * strcat (char *dst, const char *src); + +char * strcpy (char *dst, const char *src) { + dst = dst; + src = src; + fprintf (stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n"); + if (bsafeShouldExit) exit (-1); + return NULL; +} + +char * strcat (char *dst, const char *src) { + dst = dst; + src = src; + fprintf (stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n"); + if (bsafeShouldExit) exit (-1); + return NULL; +} + +#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310)) +char * (gets) (char * buf) { + buf = buf; + fprintf (stderr, "bsafe error: gets() is not safe, use bgets.\n"); + if (bsafeShouldExit) exit (-1); + return NULL; +} +#endif + +char * (strncpy) (char *dst, const char *src, size_t n) { + dst = dst; + src = src; + n = n; + fprintf (stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n"); + if (bsafeShouldExit) exit (-1); + return NULL; +} + +char * (strncat) (char *dst, const char *src, size_t n) { + dst = dst; + src = src; + n = n; + fprintf (stderr, "bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor cstr2tbstr, btrunc then bstrcat instead.\n"); + if (bsafeShouldExit) exit (-1); + return NULL; +} + +char * (strtok) (char *s1, const char *s2) { + s1 = s1; + s2 = s2; + fprintf (stderr, "bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n"); + if (bsafeShouldExit) exit (-1); + return NULL; +} + +char * (strdup) (const char *s) { + s = s; + fprintf (stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n"); + if (bsafeShouldExit) exit (-1); + return NULL; +} + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/bsafe.h b/build/tools/HLSLcc/May_2014/src/cbstring/bsafe.h new file mode 100644 index 0000000..eb41ec2 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/bsafe.h @@ -0,0 +1,43 @@ +/* + * This source file is part of the bstring string library. This code was + * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause + * BSD open source license or GPL v2.0. Refer to the accompanying documentation + * for details on usage and license. + */ + +/* + * bsafe.h + * + * This is an optional module that can be used to help enforce a safety + * standard based on pervasive usage of bstrlib. This file is not necessarily + * portable, however, it has been tested to work correctly with Intel's C/C++ + * compiler, WATCOM C/C++ v11.x and Microsoft Visual C++. + */ + +#ifndef BSTRLIB_BSAFE_INCLUDE +#define BSTRLIB_BSAFE_INCLUDE + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310)) +/* This is caught in the linker, so its not necessary for gcc. */ +extern char * (gets) (char * buf); +#endif + +extern char * (strncpy) (char *dst, const char *src, size_t n); +extern char * (strncat) (char *dst, const char *src, size_t n); +extern char * (strtok) (char *s1, const char *s2); +extern char * (strdup) (const char *s); + +#undef strcpy +#undef strcat +#define strcpy(a,b) bsafe_strcpy(a,b) +#define strcat(a,b) bsafe_strcat(a,b) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/bstraux.c b/build/tools/HLSLcc/May_2014/src/cbstring/bstraux.c new file mode 100644 index 0000000..975932c --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/bstraux.c @@ -0,0 +1,1133 @@ +/* + * This source file is part of the bstring string library. This code was + * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause + * BSD open source license or GPL v2.0. Refer to the accompanying documentation + * for details on usage and license. + */ + +/* + * bstraux.c + * + * This file is not necessarily part of the core bstring library itself, but + * is just an auxilliary module which includes miscellaneous or trivial + * functions. + */ + +#include +#include +#include +#include +#include +#include "bstrlib.h" +#include "bstraux.h" + +/* bstring bTail (bstring b, int n) + * + * Return with a string of the last n characters of b. + */ +bstring bTail (bstring b, int n) { + if (b == NULL || n < 0 || (b->mlen < b->slen && b->mlen > 0)) return NULL; + if (n >= b->slen) return bstrcpy (b); + return bmidstr (b, b->slen - n, n); +} + +/* bstring bHead (bstring b, int n) + * + * Return with a string of the first n characters of b. + */ +bstring bHead (bstring b, int n) { + if (b == NULL || n < 0 || (b->mlen < b->slen && b->mlen > 0)) return NULL; + if (n >= b->slen) return bstrcpy (b); + return bmidstr (b, 0, n); +} + +/* int bFill (bstring a, char c, int len) + * + * Fill a given bstring with the character in parameter c, for a length n. + */ +int bFill (bstring b, char c, int len) { + if (b == NULL || len < 0 || (b->mlen < b->slen && b->mlen > 0)) return -__LINE__; + b->slen = 0; + return bsetstr (b, len, NULL, c); +} + +/* int bReplicate (bstring b, int n) + * + * Replicate the contents of b end to end n times and replace it in b. + */ +int bReplicate (bstring b, int n) { + return bpattern (b, n * b->slen); +} + +/* int bReverse (bstring b) + * + * Reverse the contents of b in place. + */ +int bReverse (bstring b) { +int i, n, m; +unsigned char t; + + if (b == NULL || b->slen < 0 || b->mlen < b->slen) return -__LINE__; + n = b->slen; + if (2 <= n) { + m = ((unsigned)n) >> 1; + n--; + for (i=0; i < m; i++) { + t = b->data[n - i]; + b->data[n - i] = b->data[i]; + b->data[i] = t; + } + } + return 0; +} + +/* int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill) + * + * Insert a repeated sequence of a given character into the string at + * position pos for a length len. + */ +int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill) { + if (b == NULL || b->slen < 0 || b->mlen < b->slen || pos < 0 || len <= 0) return -__LINE__; + + if (pos > b->slen + && 0 > bsetstr (b, pos, NULL, fill)) return -__LINE__; + + if (0 > balloc (b, b->slen + len)) return -__LINE__; + if (pos < b->slen) memmove (b->data + pos + len, b->data + pos, b->slen - pos); + memset (b->data + pos, c, len); + b->slen += len; + b->data[b->slen] = (unsigned char) '\0'; + return BSTR_OK; +} + +/* int bJustifyLeft (bstring b, int space) + * + * Left justify a string. + */ +int bJustifyLeft (bstring b, int space) { +int j, i, s, t; +unsigned char c = (unsigned char) space; + + if (b == NULL || b->slen < 0 || b->mlen < b->slen) return -__LINE__; + if (space != (int) c) return BSTR_OK; + + for (s=j=i=0; i < b->slen; i++) { + t = s; + s = c != (b->data[j] = b->data[i]); + j += (t|s); + } + if (j > 0 && b->data[j-1] == c) j--; + + b->data[j] = (unsigned char) '\0'; + b->slen = j; + return BSTR_OK; +} + +/* int bJustifyRight (bstring b, int width, int space) + * + * Right justify a string to within a given width. + */ +int bJustifyRight (bstring b, int width, int space) { +int ret; + if (width <= 0) return -__LINE__; + if (0 > (ret = bJustifyLeft (b, space))) return ret; + if (b->slen <= width) + return bInsertChrs (b, 0, width - b->slen, (unsigned char) space, (unsigned char) space); + return BSTR_OK; +} + +/* int bJustifyCenter (bstring b, int width, int space) + * + * Center a string's non-white space characters to within a given width by + * inserting whitespaces at the beginning. + */ +int bJustifyCenter (bstring b, int width, int space) { +int ret; + if (width <= 0) return -__LINE__; + if (0 > (ret = bJustifyLeft (b, space))) return ret; + if (b->slen <= width) + return bInsertChrs (b, 0, (width - b->slen + 1) >> 1, (unsigned char) space, (unsigned char) space); + return BSTR_OK; +} + +/* int bJustifyMargin (bstring b, int width, int space) + * + * Stretch a string to flush against left and right margins by evenly + * distributing additional white space between words. If the line is too + * long to be margin justified, it is left justified. + */ +int bJustifyMargin (bstring b, int width, int space) { +struct bstrList * sl; +int i, l, c; + + if (b == NULL || b->slen < 0 || b->mlen == 0 || b->mlen < b->slen) return -__LINE__; + if (NULL == (sl = bsplit (b, (unsigned char) space))) return -__LINE__; + for (l=c=i=0; i < sl->qty; i++) { + if (sl->entry[i]->slen > 0) { + c ++; + l += sl->entry[i]->slen; + } + } + + if (l + c >= width || c < 2) { + bstrListDestroy (sl); + return bJustifyLeft (b, space); + } + + b->slen = 0; + for (i=0; i < sl->qty; i++) { + if (sl->entry[i]->slen > 0) { + if (b->slen > 0) { + int s = (width - l + (c / 2)) / c; + bInsertChrs (b, b->slen, s, (unsigned char) space, (unsigned char) space); + l += s; + } + bconcat (b, sl->entry[i]); + c--; + if (c <= 0) break; + } + } + + bstrListDestroy (sl); + return BSTR_OK; +} + +static size_t readNothing (void *buff, size_t elsize, size_t nelem, void *parm) { + buff = buff; + elsize = elsize; + nelem = nelem; + parm = parm; + return 0; /* Immediately indicate EOF. */ +} + +/* struct bStream * bsFromBstr (const_bstring b); + * + * Create a bStream whose contents are a copy of the bstring passed in. + * This allows the use of all the bStream APIs with bstrings. + */ +struct bStream * bsFromBstr (const_bstring b) { +struct bStream * s = bsopen ((bNread) readNothing, NULL); + bsunread (s, b); /* Push the bstring data into the empty bStream. */ + return s; +} + +static size_t readRef (void *buff, size_t elsize, size_t nelem, void *parm) { +struct tagbstring * t = (struct tagbstring *) parm; +size_t tsz = elsize * nelem; + + if (tsz > (size_t) t->slen) tsz = (size_t) t->slen; + if (tsz > 0) { + memcpy (buff, t->data, tsz); + t->slen -= (int) tsz; + t->data += tsz; + return tsz / elsize; + } + return 0; +} + +/* The "by reference" version of the above function. This function puts + * a number of restrictions on the call site (the passed in struct + * tagbstring *will* be modified by this function, and the source data + * must remain alive and constant for the lifetime of the bStream). + * Hence it is not presented as an extern. + */ +static struct bStream * bsFromBstrRef (struct tagbstring * t) { + if (!t) return NULL; + return bsopen ((bNread) readRef, t); +} + +/* char * bStr2NetStr (const_bstring b) + * + * Convert a bstring to a netstring. See + * http://cr.yp.to/proto/netstrings.txt for a description of netstrings. + * Note: 1) The value returned should be freed with a call to bcstrfree() at + * the point when it will no longer be referenced to avoid a memory + * leak. + * 2) If the returned value is non-NULL, then it also '\0' terminated + * in the character position one past the "," terminator. + */ +char * bStr2NetStr (const_bstring b) { +char strnum[sizeof (b->slen) * 3 + 1]; +bstring s; +unsigned char * buff; + + if (b == NULL || b->data == NULL || b->slen < 0) return NULL; + sprintf (strnum, "%d:", b->slen); + if (NULL == (s = bfromcstr (strnum)) + || bconcat (s, b) == BSTR_ERR || bconchar (s, (char) ',') == BSTR_ERR) { + bdestroy (s); + return NULL; + } + buff = s->data; + bcstrfree ((char *) s); + return (char *) buff; +} + +/* bstring bNetStr2Bstr (const char * buf) + * + * Convert a netstring to a bstring. See + * http://cr.yp.to/proto/netstrings.txt for a description of netstrings. + * Note that the terminating "," *must* be present, however a following '\0' + * is *not* required. + */ +bstring bNetStr2Bstr (const char * buff) { +int i, x; +bstring b; + if (buff == NULL) return NULL; + x = 0; + for (i=0; buff[i] != ':'; i++) { + unsigned int v = buff[i] - '0'; + if (v > 9 || x > ((INT_MAX - (signed int)v) / 10)) return NULL; + x = (x * 10) + v; + } + + /* This thing has to be properly terminated */ + if (buff[i + 1 + x] != ',') return NULL; + + if (NULL == (b = bfromcstr (""))) return NULL; + if (balloc (b, x + 1) != BSTR_OK) { + bdestroy (b); + return NULL; + } + memcpy (b->data, buff + i + 1, x); + b->data[x] = (unsigned char) '\0'; + b->slen = x; + return b; +} + +static char b64ETable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* bstring bBase64Encode (const_bstring b) + * + * Generate a base64 encoding. See: RFC1341 + */ +bstring bBase64Encode (const_bstring b) { +int i, c0, c1, c2, c3; +bstring out; + + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + + out = bfromcstr (""); + for (i=0; i + 2 < b->slen; i += 3) { + if (i && ((i % 57) == 0)) { + if (bconchar (out, (char) '\015') < 0 || bconchar (out, (char) '\012') < 0) { + bdestroy (out); + return NULL; + } + } + c0 = b->data[i] >> 2; + c1 = ((b->data[i] << 4) | + (b->data[i+1] >> 4)) & 0x3F; + c2 = ((b->data[i+1] << 2) | + (b->data[i+2] >> 6)) & 0x3F; + c3 = b->data[i+2] & 0x3F; + if (bconchar (out, b64ETable[c0]) < 0 || + bconchar (out, b64ETable[c1]) < 0 || + bconchar (out, b64ETable[c2]) < 0 || + bconchar (out, b64ETable[c3]) < 0) { + bdestroy (out); + return NULL; + } + } + + if (i && ((i % 57) == 0)) { + if (bconchar (out, (char) '\015') < 0 || bconchar (out, (char) '\012') < 0) { + bdestroy (out); + return NULL; + } + } + + switch (i + 2 - b->slen) { + case 0: c0 = b->data[i] >> 2; + c1 = ((b->data[i] << 4) | + (b->data[i+1] >> 4)) & 0x3F; + c2 = (b->data[i+1] << 2) & 0x3F; + if (bconchar (out, b64ETable[c0]) < 0 || + bconchar (out, b64ETable[c1]) < 0 || + bconchar (out, b64ETable[c2]) < 0 || + bconchar (out, (char) '=') < 0) { + bdestroy (out); + return NULL; + } + break; + case 1: c0 = b->data[i] >> 2; + c1 = (b->data[i] << 4) & 0x3F; + if (bconchar (out, b64ETable[c0]) < 0 || + bconchar (out, b64ETable[c1]) < 0 || + bconchar (out, (char) '=') < 0 || + bconchar (out, (char) '=') < 0) { + bdestroy (out); + return NULL; + } + break; + case 2: break; + } + + return out; +} + +#define B64_PAD (-2) +#define B64_ERR (-1) + +static int base64DecodeSymbol (unsigned char alpha) { + if ((alpha >= 'A') && (alpha <= 'Z')) return (int)(alpha - 'A'); + else if ((alpha >= 'a') && (alpha <= 'z')) + return 26 + (int)(alpha - 'a'); + else if ((alpha >= '0') && (alpha <= '9')) + return 52 + (int)(alpha - '0'); + else if (alpha == '+') return 62; + else if (alpha == '/') return 63; + else if (alpha == '=') return B64_PAD; + else return B64_ERR; +} + +/* bstring bBase64DecodeEx (const_bstring b, int * boolTruncError) + * + * Decode a base64 block of data. All MIME headers are assumed to have been + * removed. See: RFC1341 + */ +bstring bBase64DecodeEx (const_bstring b, int * boolTruncError) { +int i, v; +unsigned char c0, c1, c2; +bstring out; + + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + if (boolTruncError) *boolTruncError = 0; + out = bfromcstr (""); + i = 0; + for (;;) { + do { + if (i >= b->slen) return out; + if (b->data[i] == '=') { /* Bad "too early" truncation */ + if (boolTruncError) { + *boolTruncError = 1; + return out; + } + bdestroy (out); + return NULL; + } + v = base64DecodeSymbol (b->data[i]); + i++; + } while (v < 0); + c0 = (unsigned char) (v << 2); + do { + if (i >= b->slen || b->data[i] == '=') { /* Bad "too early" truncation */ + if (boolTruncError) { + *boolTruncError = 1; + return out; + } + bdestroy (out); + return NULL; + } + v = base64DecodeSymbol (b->data[i]); + i++; + } while (v < 0); + c0 |= (unsigned char) (v >> 4); + c1 = (unsigned char) (v << 4); + do { + if (i >= b->slen) { + if (boolTruncError) { + *boolTruncError = 1; + return out; + } + bdestroy (out); + return NULL; + } + if (b->data[i] == '=') { + i++; + if (i >= b->slen || b->data[i] != '=' || bconchar (out, c0) < 0) { + if (boolTruncError) { + *boolTruncError = 1; + return out; + } + bdestroy (out); /* Missing "=" at the end. */ + return NULL; + } + return out; + } + v = base64DecodeSymbol (b->data[i]); + i++; + } while (v < 0); + c1 |= (unsigned char) (v >> 2); + c2 = (unsigned char) (v << 6); + do { + if (i >= b->slen) { + if (boolTruncError) { + *boolTruncError = 1; + return out; + } + bdestroy (out); + return NULL; + } + if (b->data[i] == '=') { + if (bconchar (out, c0) < 0 || bconchar (out, c1) < 0) { + if (boolTruncError) { + *boolTruncError = 1; + return out; + } + bdestroy (out); + return NULL; + } + if (boolTruncError) *boolTruncError = 0; + return out; + } + v = base64DecodeSymbol (b->data[i]); + i++; + } while (v < 0); + c2 |= (unsigned char) (v); + if (bconchar (out, c0) < 0 || + bconchar (out, c1) < 0 || + bconchar (out, c2) < 0) { + if (boolTruncError) { + *boolTruncError = -1; + return out; + } + bdestroy (out); + return NULL; + } + } +} + +#define UU_DECODE_BYTE(b) (((b) == (signed int)'`') ? 0 : (b) - (signed int)' ') + +struct bUuInOut { + bstring src, dst; + int * badlines; +}; + +#define UU_MAX_LINELEN 45 + +static int bUuDecLine (void * parm, int ofs, int len) { +struct bUuInOut * io = (struct bUuInOut *) parm; +bstring s = io->src; +bstring t = io->dst; +int i, llen, otlen, ret, c0, c1, c2, c3, d0, d1, d2, d3; + + if (len == 0) return 0; + llen = UU_DECODE_BYTE (s->data[ofs]); + ret = 0; + + otlen = t->slen; + + if (((unsigned) llen) > UU_MAX_LINELEN) { ret = -__LINE__; + goto bl; + } + + llen += t->slen; + + for (i=1; i < s->slen && t->slen < llen;i += 4) { + unsigned char outoctet[3]; + c0 = UU_DECODE_BYTE (d0 = (int) bchare (s, i+ofs+0, ' ' - 1)); + c1 = UU_DECODE_BYTE (d1 = (int) bchare (s, i+ofs+1, ' ' - 1)); + c2 = UU_DECODE_BYTE (d2 = (int) bchare (s, i+ofs+2, ' ' - 1)); + c3 = UU_DECODE_BYTE (d3 = (int) bchare (s, i+ofs+3, ' ' - 1)); + + if (((unsigned) (c0|c1) >= 0x40)) { if (!ret) ret = -__LINE__; + if (d0 > 0x60 || (d0 < (' ' - 1) && !isspace (d0)) || + d1 > 0x60 || (d1 < (' ' - 1) && !isspace (d1))) { + t->slen = otlen; + goto bl; + } + c0 = c1 = 0; + } + outoctet[0] = (unsigned char) ((c0 << 2) | ((unsigned) c1 >> 4)); + if (t->slen+1 >= llen) { + if (0 > bconchar (t, (char) outoctet[0])) return -__LINE__; + break; + } + if ((unsigned) c2 >= 0x40) { if (!ret) ret = -__LINE__; + if (d2 > 0x60 || (d2 < (' ' - 1) && !isspace (d2))) { + t->slen = otlen; + goto bl; + } + c2 = 0; + } + outoctet[1] = (unsigned char) ((c1 << 4) | ((unsigned) c2 >> 2)); + if (t->slen+2 >= llen) { + if (0 > bcatblk (t, outoctet, 2)) return -__LINE__; + break; + } + if ((unsigned) c3 >= 0x40) { if (!ret) ret = -__LINE__; + if (d3 > 0x60 || (d3 < (' ' - 1) && !isspace (d3))) { + t->slen = otlen; + goto bl; + } + c3 = 0; + } + outoctet[2] = (unsigned char) ((c2 << 6) | ((unsigned) c3)); + if (0 > bcatblk (t, outoctet, 3)) return -__LINE__; + } + if (t->slen < llen) { if (0 == ret) ret = -__LINE__; + t->slen = otlen; + } + bl:; + if (ret && io->badlines) { + (*io->badlines)++; + return 0; + } + return ret; +} + +/* bstring bUuDecodeEx (const_bstring src, int * badlines) + * + * Performs a UUDecode of a block of data. If there are errors in the + * decoding, they are counted up and returned in "badlines", if badlines is + * not NULL. It is assumed that the "begin" and "end" lines have already + * been stripped off. The potential security problem of writing the + * filename in the begin line is something that is beyond the scope of a + * portable library. + */ + +#ifdef _MSC_VER +#pragma warning(disable:4204) +#endif + +bstring bUuDecodeEx (const_bstring src, int * badlines) { +struct tagbstring t; +struct bStream * s; +struct bStream * d; +bstring b; + + if (!src) return NULL; + t = *src; /* Short lifetime alias to header of src */ + s = bsFromBstrRef (&t); /* t is undefined after this */ + if (!s) return NULL; + d = bsUuDecode (s, badlines); + b = bfromcstralloc (256, ""); + if (NULL == b || 0 > bsread (b, d, INT_MAX)) { + bdestroy (b); + bsclose (d); + bsclose (s); + return NULL; + } + return b; +} + +struct bsUuCtx { + struct bUuInOut io; + struct bStream * sInp; +}; + +static size_t bsUuDecodePart (void *buff, size_t elsize, size_t nelem, void *parm) { +static struct tagbstring eol = bsStatic ("\r\n"); +struct bsUuCtx * luuCtx = (struct bsUuCtx *) parm; +size_t tsz; +int l, lret; + + if (NULL == buff || NULL == parm) return 0; + tsz = elsize * nelem; + + CheckInternalBuffer:; + /* If internal buffer has sufficient data, just output it */ + if (((size_t) luuCtx->io.dst->slen) > tsz) { + memcpy (buff, luuCtx->io.dst->data, tsz); + bdelete (luuCtx->io.dst, 0, (int) tsz); + return nelem; + } + + DecodeMore:; + if (0 <= (l = binchr (luuCtx->io.src, 0, &eol))) { + int ol = 0; + struct tagbstring t; + bstring s = luuCtx->io.src; + luuCtx->io.src = &t; + + do { + if (l > ol) { + bmid2tbstr (t, s, ol, l - ol); + lret = bUuDecLine (&luuCtx->io, 0, t.slen); + if (0 > lret) { + luuCtx->io.src = s; + goto Done; + } + } + ol = l + 1; + if (((size_t) luuCtx->io.dst->slen) > tsz) break; + l = binchr (s, ol, &eol); + } while (BSTR_ERR != l); + bdelete (s, 0, ol); + luuCtx->io.src = s; + goto CheckInternalBuffer; + } + + if (BSTR_ERR != bsreada (luuCtx->io.src, luuCtx->sInp, bsbufflength (luuCtx->sInp, BSTR_BS_BUFF_LENGTH_GET))) { + goto DecodeMore; + } + + bUuDecLine (&luuCtx->io, 0, luuCtx->io.src->slen); + + Done:; + /* Output any lingering data that has been translated */ + if (((size_t) luuCtx->io.dst->slen) > 0) { + if (((size_t) luuCtx->io.dst->slen) > tsz) goto CheckInternalBuffer; + memcpy (buff, luuCtx->io.dst->data, luuCtx->io.dst->slen); + tsz = luuCtx->io.dst->slen / elsize; + luuCtx->io.dst->slen = 0; + if (tsz > 0) return tsz; + } + + /* Deallocate once EOF becomes triggered */ + bdestroy (luuCtx->io.dst); + bdestroy (luuCtx->io.src); + free (luuCtx); + return 0; +} + +/* bStream * bsUuDecode (struct bStream * sInp, int * badlines) + * + * Creates a bStream which performs the UUDecode of an an input stream. If + * there are errors in the decoding, they are counted up and returned in + * "badlines", if badlines is not NULL. It is assumed that the "begin" and + * "end" lines have already been stripped off. The potential security + * problem of writing the filename in the begin line is something that is + * beyond the scope of a portable library. + */ + +struct bStream * bsUuDecode (struct bStream * sInp, int * badlines) { +struct bsUuCtx * luuCtx = (struct bsUuCtx *) malloc (sizeof (struct bsUuCtx)); +struct bStream * sOut; + + if (NULL == luuCtx) return NULL; + + luuCtx->io.src = bfromcstr (""); + luuCtx->io.dst = bfromcstr (""); + if (NULL == luuCtx->io.dst || NULL == luuCtx->io.src) { + CleanUpFailureToAllocate:; + bdestroy (luuCtx->io.dst); + bdestroy (luuCtx->io.src); + free (luuCtx); + return NULL; + } + luuCtx->io.badlines = badlines; + if (badlines) *badlines = 0; + + luuCtx->sInp = sInp; + + sOut = bsopen ((bNread) bsUuDecodePart, luuCtx); + if (NULL == sOut) goto CleanUpFailureToAllocate; + return sOut; +} + +#define UU_ENCODE_BYTE(b) (char) (((b) == 0) ? '`' : ((b) + ' ')) + +/* bstring bUuEncode (const_bstring src) + * + * Performs a UUEncode of a block of data. The "begin" and "end" lines are + * not appended. + */ +bstring bUuEncode (const_bstring src) { +bstring out; +int i, j, jm; +unsigned int c0, c1, c2; + if (src == NULL || src->slen < 0 || src->data == NULL) return NULL; + if ((out = bfromcstr ("")) == NULL) return NULL; + for (i=0; i < src->slen; i += UU_MAX_LINELEN) { + if ((jm = i + UU_MAX_LINELEN) > src->slen) jm = src->slen; + if (bconchar (out, UU_ENCODE_BYTE (jm - i)) < 0) { + bstrFree (out); + break; + } + for (j = i; j < jm; j += 3) { + c0 = (unsigned int) bchar (src, j ); + c1 = (unsigned int) bchar (src, j + 1); + c2 = (unsigned int) bchar (src, j + 2); + if (bconchar (out, UU_ENCODE_BYTE ( (c0 & 0xFC) >> 2)) < 0 || + bconchar (out, UU_ENCODE_BYTE (((c0 & 0x03) << 4) | ((c1 & 0xF0) >> 4))) < 0 || + bconchar (out, UU_ENCODE_BYTE (((c1 & 0x0F) << 2) | ((c2 & 0xC0) >> 6))) < 0 || + bconchar (out, UU_ENCODE_BYTE ( (c2 & 0x3F))) < 0) { + bstrFree (out); + goto End; + } + } + if (bconchar (out, (char) '\r') < 0 || bconchar (out, (char) '\n') < 0) { + bstrFree (out); + break; + } + } + End:; + return out; +} + +/* bstring bYEncode (const_bstring src) + * + * Performs a YEncode of a block of data. No header or tail info is + * appended. See: http://www.yenc.org/whatis.htm and + * http://www.yenc.org/yenc-draft.1.3.txt + */ +bstring bYEncode (const_bstring src) { +int i; +bstring out; +unsigned char c; + + if (src == NULL || src->slen < 0 || src->data == NULL) return NULL; + if ((out = bfromcstr ("")) == NULL) return NULL; + for (i=0; i < src->slen; i++) { + c = (unsigned char)(src->data[i] + 42); + if (c == '=' || c == '\0' || c == '\r' || c == '\n') { + if (0 > bconchar (out, (char) '=')) { + bdestroy (out); + return NULL; + } + c += (unsigned char) 64; + } + if (0 > bconchar (out, c)) { + bdestroy (out); + return NULL; + } + } + return out; +} + +/* bstring bYDecode (const_bstring src) + * + * Performs a YDecode of a block of data. See: + * http://www.yenc.org/whatis.htm and http://www.yenc.org/yenc-draft.1.3.txt + */ +#define MAX_OB_LEN (64) + +bstring bYDecode (const_bstring src) { +int i; +bstring out; +unsigned char c; +unsigned char octetbuff[MAX_OB_LEN]; +int obl; + + if (src == NULL || src->slen < 0 || src->data == NULL) return NULL; + if ((out = bfromcstr ("")) == NULL) return NULL; + + obl = 0; + + for (i=0; i < src->slen; i++) { + if ('=' == (c = src->data[i])) { /* The = escape mode */ + i++; + if (i >= src->slen) { + bdestroy (out); + return NULL; + } + c = (unsigned char) (src->data[i] - 64); + } else { + if ('\0' == c) { + bdestroy (out); + return NULL; + } + + /* Extraneous CR/LFs are to be ignored. */ + if (c == '\r' || c == '\n') continue; + } + + octetbuff[obl] = (unsigned char) ((int) c - 42); + obl++; + + if (obl >= MAX_OB_LEN) { + if (0 > bcatblk (out, octetbuff, obl)) { + bdestroy (out); + return NULL; + } + obl = 0; + } + } + + if (0 > bcatblk (out, octetbuff, obl)) { + bdestroy (out); + out = NULL; + } + return out; +} + +/* bstring bStrfTime (const char * fmt, const struct tm * timeptr) + * + * Takes a format string that is compatible with strftime and a struct tm + * pointer, formats the time according to the format string and outputs + * the bstring as a result. Note that if there is an early generation of a + * '\0' character, the bstring will be truncated to this end point. + */ +bstring bStrfTime (const char * fmt, const struct tm * timeptr) { +#if defined (__TURBOC__) && !defined (__BORLANDC__) +static struct tagbstring ns = bsStatic ("bStrfTime Not supported"); + fmt = fmt; + timeptr = timeptr; + return &ns; +#else +bstring buff; +int n; +size_t r; + + if (fmt == NULL) return NULL; + + /* Since the length is not determinable beforehand, a search is + performed using the truncating "strftime" call on increasing + potential sizes for the output result. */ + + if ((n = (int) (2*strlen (fmt))) < 16) n = 16; + buff = bfromcstralloc (n+2, ""); + + for (;;) { + if (BSTR_OK != balloc (buff, n + 2)) { + bdestroy (buff); + return NULL; + } + + r = strftime ((char *) buff->data, n + 1, fmt, timeptr); + + if (r > 0) { + buff->slen = (int) r; + break; + } + + n += n; + } + + return buff; +#endif +} + +/* int bSetCstrChar (bstring a, int pos, char c) + * + * Sets the character at position pos to the character c in the bstring a. + * If the character c is NUL ('\0') then the string is truncated at this + * point. Note: this does not enable any other '\0' character in the bstring + * as terminator indicator for the string. pos must be in the position + * between 0 and b->slen inclusive, otherwise BSTR_ERR will be returned. + */ +int bSetCstrChar (bstring b, int pos, char c) { + if (NULL == b || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen) + return BSTR_ERR; + if (pos < 0 || pos > b->slen) return BSTR_ERR; + + if (pos == b->slen) { + if ('\0' != c) return bconchar (b, c); + return 0; + } + + b->data[pos] = (unsigned char) c; + if ('\0' == c) b->slen = pos; + + return 0; +} + +/* int bSetChar (bstring b, int pos, char c) + * + * Sets the character at position pos to the character c in the bstring a. + * The string is not truncated if the character c is NUL ('\0'). pos must + * be in the position between 0 and b->slen inclusive, otherwise BSTR_ERR + * will be returned. + */ +int bSetChar (bstring b, int pos, char c) { + if (NULL == b || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen) + return BSTR_ERR; + if (pos < 0 || pos > b->slen) return BSTR_ERR; + + if (pos == b->slen) { + return bconchar (b, c); + } + + b->data[pos] = (unsigned char) c; + return 0; +} + +#define INIT_SECURE_INPUT_LENGTH (256) + +/* bstring bSecureInput (int maxlen, int termchar, + * bNgetc vgetchar, void * vgcCtx) + * + * Read input from an abstracted input interface, for a length of at most + * maxlen characters. If maxlen <= 0, then there is no length limit put + * on the input. The result is terminated early if vgetchar() return EOF + * or the user specified value termchar. + * + */ +bstring bSecureInput (int maxlen, int termchar, bNgetc vgetchar, void * vgcCtx) { +int i, m, c; +bstring b, t; + + if (!vgetchar) return NULL; + + b = bfromcstralloc (INIT_SECURE_INPUT_LENGTH, ""); + if ((c = UCHAR_MAX + 1) == termchar) c++; + + for (i=0; ; i++) { + if (termchar == c || (maxlen > 0 && i >= maxlen)) c = EOF; + else c = vgetchar (vgcCtx); + + if (EOF == c) break; + + if (i+1 >= b->mlen) { + + /* Double size, but deal with unusual case of numeric + overflows */ + + if ((m = b->mlen << 1) <= b->mlen && + (m = b->mlen + 1024) <= b->mlen && + (m = b->mlen + 16) <= b->mlen && + (m = b->mlen + 1) <= b->mlen) t = NULL; + else t = bfromcstralloc (m, ""); + + if (t) memcpy (t->data, b->data, i); + bSecureDestroy (b); /* Cleanse previous buffer */ + b = t; + if (!b) return b; + } + + b->data[i] = (unsigned char) c; + } + + b->slen = i; + b->data[i] = (unsigned char) '\0'; + return b; +} + +#define BWS_BUFF_SZ (1024) + +struct bwriteStream { + bstring buff; /* Buffer for underwrites */ + void * parm; /* The stream handle for core stream */ + bNwrite writeFn; /* fwrite work-a-like fnptr for core stream */ + int isEOF; /* track stream's EOF state */ + int minBuffSz; +}; + +/* struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm) + * + * Wrap a given open stream (described by a fwrite work-a-like function + * pointer and stream handle) into an open bwriteStream suitable for write + * streaming functions. + */ +struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm) { +struct bwriteStream * ws; + + if (NULL == writeFn) return NULL; + ws = (struct bwriteStream *) malloc (sizeof (struct bwriteStream)); + if (ws) { + if (NULL == (ws->buff = bfromcstr (""))) { + free (ws); + ws = NULL; + } else { + ws->parm = parm; + ws->writeFn = writeFn; + ws->isEOF = 0; + ws->minBuffSz = BWS_BUFF_SZ; + } + } + return ws; +} + +#define internal_bwswriteout(ws,b) { \ + if ((b)->slen > 0) { \ + if (1 != (ws->writeFn ((b)->data, (b)->slen, 1, ws->parm))) { \ + ws->isEOF = 1; \ + return BSTR_ERR; \ + } \ + } \ +} + +/* int bwsWriteFlush (struct bwriteStream * ws) + * + * Force any pending data to be written to the core stream. + */ +int bwsWriteFlush (struct bwriteStream * ws) { + if (NULL == ws || ws->isEOF || 0 >= ws->minBuffSz || + NULL == ws->writeFn || NULL == ws->buff) return BSTR_ERR; + internal_bwswriteout (ws, ws->buff); + ws->buff->slen = 0; + return 0; +} + +/* int bwsWriteBstr (struct bwriteStream * ws, const_bstring b) + * + * Send a bstring to a bwriteStream. If the stream is at EOF BSTR_ERR is + * returned. Note that there is no deterministic way to determine the exact + * cut off point where the core stream stopped accepting data. + */ +int bwsWriteBstr (struct bwriteStream * ws, const_bstring b) { +struct tagbstring t; +int l; + + if (NULL == ws || NULL == b || NULL == ws->buff || + ws->isEOF || 0 >= ws->minBuffSz || NULL == ws->writeFn) + return BSTR_ERR; + + /* Buffer prepacking optimization */ + if (b->slen > 0 && ws->buff->mlen - ws->buff->slen > b->slen) { + static struct tagbstring empty = bsStatic (""); + if (0 > bconcat (ws->buff, b)) return BSTR_ERR; + return bwsWriteBstr (ws, &empty); + } + + if (0 > (l = ws->minBuffSz - ws->buff->slen)) { + internal_bwswriteout (ws, ws->buff); + ws->buff->slen = 0; + l = ws->minBuffSz; + } + + if (b->slen < l) return bconcat (ws->buff, b); + + if (0 > bcatblk (ws->buff, b->data, l)) return BSTR_ERR; + internal_bwswriteout (ws, ws->buff); + ws->buff->slen = 0; + + bmid2tbstr (t, (bstring) b, l, b->slen); + + if (t.slen >= ws->minBuffSz) { + internal_bwswriteout (ws, &t); + return 0; + } + + return bassign (ws->buff, &t); +} + +/* int bwsWriteBlk (struct bwriteStream * ws, void * blk, int len) + * + * Send a block of data a bwriteStream. If the stream is at EOF BSTR_ERR is + * returned. + */ +int bwsWriteBlk (struct bwriteStream * ws, void * blk, int len) { +struct tagbstring t; + if (NULL == blk || len < 0) return BSTR_ERR; + blk2tbstr (t, blk, len); + return bwsWriteBstr (ws, &t); +} + +/* int bwsIsEOF (const struct bwriteStream * ws) + * + * Returns 0 if the stream is currently writable, 1 if the core stream has + * responded by not accepting the previous attempted write. + */ +int bwsIsEOF (const struct bwriteStream * ws) { + if (NULL == ws || NULL == ws->buff || 0 > ws->minBuffSz || + NULL == ws->writeFn) return BSTR_ERR; + return ws->isEOF; +} + +/* int bwsBuffLength (struct bwriteStream * ws, int sz) + * + * Set the length of the buffer used by the bwsStream. If sz is zero, the + * length is not set. This function returns with the previous length. + */ +int bwsBuffLength (struct bwriteStream * ws, int sz) { +int oldSz; + if (ws == NULL || sz < 0) return BSTR_ERR; + oldSz = ws->minBuffSz; + if (sz > 0) ws->minBuffSz = sz; + return oldSz; +} + +/* void * bwsClose (struct bwriteStream * s) + * + * Close the bwriteStream, and return the handle to the stream that was + * originally used to open the given stream. Note that even if the stream + * is at EOF it still needs to be closed with a call to bwsClose. + */ +void * bwsClose (struct bwriteStream * ws) { +void * parm; + if (NULL == ws || NULL == ws->buff || 0 >= ws->minBuffSz || + NULL == ws->writeFn) return NULL; + bwsWriteFlush (ws); + parm = ws->parm; + ws->parm = NULL; + ws->minBuffSz = -1; + ws->writeFn = NULL; + bstrFree (ws->buff); + free (ws); + return parm; +} + diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/bstraux.h b/build/tools/HLSLcc/May_2014/src/cbstring/bstraux.h new file mode 100644 index 0000000..17d4ea7 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/bstraux.h @@ -0,0 +1,112 @@ +/* + * This source file is part of the bstring string library. This code was + * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause + * BSD open source license or GPL v2.0. Refer to the accompanying documentation + * for details on usage and license. + */ + +/* + * bstraux.h + * + * This file is not a necessary part of the core bstring library itself, but + * is just an auxilliary module which includes miscellaneous or trivial + * functions. + */ + +#ifndef BSTRAUX_INCLUDE +#define BSTRAUX_INCLUDE + +#include +#include "bstrlib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Safety mechanisms */ +#define bstrDeclare(b) bstring (b) = NULL; +#define bstrFree(b) {if ((b) != NULL && (b)->slen >= 0 && (b)->mlen >= (b)->slen) { bdestroy (b); (b) = NULL; }} + +/* Backward compatibilty with previous versions of Bstrlib */ +#define bAssign(a,b) ((bassign)((a), (b))) +#define bSubs(b,pos,len,a,c) ((breplace)((b),(pos),(len),(a),(unsigned char)(c))) +#define bStrchr(b,c) ((bstrchr)((b), (c))) +#define bStrchrFast(b,c) ((bstrchr)((b), (c))) +#define bCatCstr(b,s) ((bcatcstr)((b), (s))) +#define bCatBlk(b,s,len) ((bcatblk)((b),(s),(len))) +#define bCatStatic(b,s) bCatBlk ((b), ("" s ""), sizeof (s) - 1) +#define bTrunc(b,n) ((btrunc)((b), (n))) +#define bReplaceAll(b,find,repl,pos) ((bfindreplace)((b),(find),(repl),(pos))) +#define bUppercase(b) ((btoupper)(b)) +#define bLowercase(b) ((btolower)(b)) +#define bCaselessCmp(a,b) ((bstricmp)((a), (b))) +#define bCaselessNCmp(a,b,n) ((bstrnicmp)((a), (b), (n))) +#define bBase64Decode(b) (bBase64DecodeEx ((b), NULL)) +#define bUuDecode(b) (bUuDecodeEx ((b), NULL)) + +/* Unusual functions */ +extern struct bStream * bsFromBstr (const_bstring b); +extern bstring bTail (bstring b, int n); +extern bstring bHead (bstring b, int n); +extern int bSetCstrChar (bstring a, int pos, char c); +extern int bSetChar (bstring b, int pos, char c); +extern int bFill (bstring a, char c, int len); +extern int bReplicate (bstring b, int n); +extern int bReverse (bstring b); +extern int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill); +extern bstring bStrfTime (const char * fmt, const struct tm * timeptr); +#define bAscTime(t) (bStrfTime ("%c\n", (t))) +#define bCTime(t) ((t) ? bAscTime (localtime (t)) : NULL) + +/* Spacing formatting */ +extern int bJustifyLeft (bstring b, int space); +extern int bJustifyRight (bstring b, int width, int space); +extern int bJustifyMargin (bstring b, int width, int space); +extern int bJustifyCenter (bstring b, int width, int space); + +/* Esoteric standards specific functions */ +extern char * bStr2NetStr (const_bstring b); +extern bstring bNetStr2Bstr (const char * buf); +extern bstring bBase64Encode (const_bstring b); +extern bstring bBase64DecodeEx (const_bstring b, int * boolTruncError); +extern struct bStream * bsUuDecode (struct bStream * sInp, int * badlines); +extern bstring bUuDecodeEx (const_bstring src, int * badlines); +extern bstring bUuEncode (const_bstring src); +extern bstring bYEncode (const_bstring src); +extern bstring bYDecode (const_bstring src); + +/* Writable stream */ +typedef int (* bNwrite) (const void * buf, size_t elsize, size_t nelem, void * parm); + +struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm); +int bwsWriteBstr (struct bwriteStream * stream, const_bstring b); +int bwsWriteBlk (struct bwriteStream * stream, void * blk, int len); +int bwsWriteFlush (struct bwriteStream * stream); +int bwsIsEOF (const struct bwriteStream * stream); +int bwsBuffLength (struct bwriteStream * stream, int sz); +void * bwsClose (struct bwriteStream * stream); + +/* Security functions */ +#define bSecureDestroy(b) { \ +bstring bstr__tmp = (b); \ + if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) { \ + (void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen); \ + bdestroy (bstr__tmp); \ + } \ +} +#define bSecureWriteProtect(t) { \ + if ((t).mlen >= 0) { \ + if ((t).mlen > (t).slen)) { \ + (void) memset ((t).data + (t).slen, 0, (size_t) (t).mlen - (t).slen); \ + } \ + (t).mlen = -1; \ + } \ +} +extern bstring bSecureInput (int maxlen, int termchar, + bNgetc vgetchar, void * vgcCtx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.c b/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.c new file mode 100644 index 0000000..f7f57de --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.c @@ -0,0 +1,2975 @@ +/* + * This source file is part of the bstring string library. This code was + * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause + * BSD open source license or GPL v2.0. Refer to the accompanying documentation + * for details on usage and license. + */ + +/* + * bstrlib.c + * + * This file is the core module for implementing the bstring functions. + */ + +#include +#include +#include +#include +#include +#include +#include "bstrlib.h" +#include "../internal_includes/hlslcc_malloc.h" + +/* Optionally include a mechanism for debugging memory */ + +#if defined(MEMORY_DEBUG) || defined(BSTRLIB_MEMORY_DEBUG) +#include "memdbg.h" +#endif + +#ifndef bstr__alloc +#define bstr__alloc(x) malloc (x) +#endif + +#ifndef bstr__free +#define bstr__free(p) free (p) +#endif + +#ifndef bstr__realloc +#define bstr__realloc(p,x) realloc ((p), (x)) +#endif + +#ifndef bstr__memcpy +#define bstr__memcpy(d,s,l) memcpy ((d), (s), (l)) +#endif + +#ifndef bstr__memmove +#define bstr__memmove(d,s,l) memmove ((d), (s), (l)) +#endif + +#ifndef bstr__memset +#define bstr__memset(d,c,l) memset ((d), (c), (l)) +#endif + +#ifndef bstr__memcmp +#define bstr__memcmp(d,c,l) memcmp ((d), (c), (l)) +#endif + +#ifndef bstr__memchr +#define bstr__memchr(s,c,l) memchr ((s), (c), (l)) +#endif + +/* Just a length safe wrapper for memmove. */ + +#define bBlockCopy(D,S,L) { if ((L) > 0) bstr__memmove ((D),(S),(L)); } + +/* Compute the snapped size for a given requested size. By snapping to powers + of 2 like this, repeated reallocations are avoided. */ +static int snapUpSize (int i) { + if (i < 8) { + i = 8; + } else { + unsigned int j; + j = (unsigned int) i; + + j |= (j >> 1); + j |= (j >> 2); + j |= (j >> 4); + j |= (j >> 8); /* Ok, since int >= 16 bits */ +#if (UINT_MAX != 0xffff) + j |= (j >> 16); /* For 32 bit int systems */ +#if (UINT_MAX > 0xffffffffUL) + j |= (j >> 32); /* For 64 bit int systems */ +#endif +#endif + /* Least power of two greater than i */ + j++; + if ((int) j >= i) i = (int) j; + } + return i; +} + +/* int balloc (bstring b, int len) + * + * Increase the size of the memory backing the bstring b to at least len. + */ +int balloc (bstring b, int olen) { + int len; + if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen <= 0 || + b->mlen < b->slen || olen <= 0) { + return BSTR_ERR; + } + + if (olen >= b->mlen) { + unsigned char * x; + + if ((len = snapUpSize (olen)) <= b->mlen) return BSTR_OK; + + /* Assume probability of a non-moving realloc is 0.125 */ + if (7 * b->mlen < 8 * b->slen) { + + /* If slen is close to mlen in size then use realloc to reduce + the memory defragmentation */ + + reallocStrategy:; + + x = (unsigned char *) bstr__realloc (b->data, (size_t) len); + if (x == NULL) { + + /* Since we failed, try allocating the tighest possible + allocation */ + + if (NULL == (x = (unsigned char *) bstr__realloc (b->data, (size_t) (len = olen)))) { + return BSTR_ERR; + } + } + } else { + + /* If slen is not close to mlen then avoid the penalty of copying + the extra bytes that are allocated, but not considered part of + the string */ + + if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len))) { + + /* Perhaps there is no available memory for the two + allocations to be in memory at once */ + + goto reallocStrategy; + + } else { + if (b->slen) bstr__memcpy ((char *) x, (char *) b->data, (size_t) b->slen); + bstr__free (b->data); + } + } + b->data = x; + b->mlen = len; + b->data[b->slen] = (unsigned char) '\0'; + } + + return BSTR_OK; +} + +/* int ballocmin (bstring b, int len) + * + * Set the size of the memory backing the bstring b to len or b->slen+1, + * whichever is larger. Note that repeated use of this function can degrade + * performance. + */ +int ballocmin (bstring b, int len) { + unsigned char * s; + + if (b == NULL || b->data == NULL || (b->slen+1) < 0 || b->mlen <= 0 || + b->mlen < b->slen || len <= 0) { + return BSTR_ERR; + } + + if (len < b->slen + 1) len = b->slen + 1; + + if (len != b->mlen) { + s = (unsigned char *) bstr__realloc (b->data, (size_t) len); + if (NULL == s) return BSTR_ERR; + s[b->slen] = (unsigned char) '\0'; + b->data = s; + b->mlen = len; + } + + return BSTR_OK; +} + +/* bstring bfromcstr (const char * str) + * + * Create a bstring which contains the contents of the '\0' terminated char * + * buffer str. + */ +bstring bfromcstr (const char * str) { +bstring b; +int i; +size_t j; + + if (str == NULL) return NULL; + j = (strlen) (str); + i = snapUpSize ((int) (j + (2 - (j != 0)))); + if (i <= (int) j) return NULL; + + b = (bstring) bstr__alloc (sizeof (struct tagbstring)); + if (NULL == b) return NULL; + b->slen = (int) j; + if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) { + bstr__free (b); + return NULL; + } + + bstr__memcpy (b->data, str, j+1); + return b; +} + +/* bstring bfromcstralloc (int mlen, const char * str) + * + * Create a bstring which contains the contents of the '\0' terminated char * + * buffer str. The memory buffer backing the string is at least len + * characters in length. + */ +bstring bfromcstralloc (int mlen, const char * str) { +bstring b; +int i; +size_t j; + + if (str == NULL) return NULL; + j = (strlen) (str); + i = snapUpSize ((int) (j + (2 - (j != 0)))); + if (i <= (int) j) return NULL; + + b = (bstring) bstr__alloc (sizeof (struct tagbstring)); + if (b == NULL) return NULL; + b->slen = (int) j; + if (i < mlen) i = mlen; + + if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) { + bstr__free (b); + return NULL; + } + + bstr__memcpy (b->data, str, j+1); + return b; +} + +/* bstring blk2bstr (const void * blk, int len) + * + * Create a bstring which contains the content of the block blk of length + * len. + */ +bstring blk2bstr (const void * blk, int len) { +bstring b; +int i; + + if (blk == NULL || len < 0) return NULL; + b = (bstring) bstr__alloc (sizeof (struct tagbstring)); + if (b == NULL) return NULL; + b->slen = len; + + i = len + (2 - (len != 0)); + i = snapUpSize (i); + + b->mlen = i; + + b->data = (unsigned char *) bstr__alloc ((size_t) b->mlen); + if (b->data == NULL) { + bstr__free (b); + return NULL; + } + + if (len > 0) bstr__memcpy (b->data, blk, (size_t) len); + b->data[len] = (unsigned char) '\0'; + + return b; +} + +/* char * bstr2cstr (const_bstring s, char z) + * + * Create a '\0' terminated char * buffer which is equal to the contents of + * the bstring s, except that any contained '\0' characters are converted + * to the character in z. This returned value should be freed with a + * bcstrfree () call, by the calling application. + */ +char * bstr2cstr (const_bstring b, char z) { +int i, l; +char * r; + + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + l = b->slen; + r = (char *) bstr__alloc ((size_t) (l + 1)); + if (r == NULL) return r; + + for (i=0; i < l; i ++) { + r[i] = (char) ((b->data[i] == '\0') ? z : (char) (b->data[i])); + } + + r[l] = (unsigned char) '\0'; + + return r; +} + +/* int bcstrfree (char * s) + * + * Frees a C-string generated by bstr2cstr (). This is normally unnecessary + * since it just wraps a call to bstr__free (), however, if bstr__alloc () + * and bstr__free () have been redefined as a macros within the bstrlib + * module (via defining them in memdbg.h after defining + * BSTRLIB_MEMORY_DEBUG) with some difference in behaviour from the std + * library functions, then this allows a correct way of freeing the memory + * that allows higher level code to be independent from these macro + * redefinitions. + */ +int bcstrfree (char * s) { + if (s) { + bstr__free (s); + return BSTR_OK; + } + return BSTR_ERR; +} + +/* int bconcat (bstring b0, const_bstring b1) + * + * Concatenate the bstring b1 to the bstring b0. + */ +int bconcat (bstring b0, const_bstring b1) { +int len, d; +bstring aux = (bstring) b1; + + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL) return BSTR_ERR; + + d = b0->slen; + len = b1->slen; + if ((d | (b0->mlen - d) | len | (d + len)) < 0) return BSTR_ERR; + + if (b0->mlen <= d + len + 1) { + ptrdiff_t pd = b1->data - b0->data; + if (0 <= pd && pd < b0->mlen) { + if (NULL == (aux = bstrcpy (b1))) return BSTR_ERR; + } + if (balloc (b0, d + len + 1) != BSTR_OK) { + if (aux != b1) bdestroy (aux); + return BSTR_ERR; + } + } + + bBlockCopy (&b0->data[d], &aux->data[0], (size_t) len); + b0->data[d + len] = (unsigned char) '\0'; + b0->slen = d + len; + if (aux != b1) bdestroy (aux); + return BSTR_OK; +} + +/* int bconchar (bstring b, char c) +/ * + * Concatenate the single character c to the bstring b. + */ +int bconchar (bstring b, char c) { +int d; + + if (b == NULL) return BSTR_ERR; + d = b->slen; + if ((d | (b->mlen - d)) < 0 || balloc (b, d + 2) != BSTR_OK) return BSTR_ERR; + b->data[d] = (unsigned char) c; + b->data[d + 1] = (unsigned char) '\0'; + b->slen++; + return BSTR_OK; +} + +/* int bcatcstr (bstring b, const char * s) + * + * Concatenate a char * string to a bstring. + */ +int bcatcstr (bstring b, const char * s) { +char * d; +int i, l; + + if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen + || b->mlen <= 0 || s == NULL) return BSTR_ERR; + + /* Optimistically concatenate directly */ + l = b->mlen - b->slen; + d = (char *) &b->data[b->slen]; + for (i=0; i < l; i++) { + if ((*d++ = *s++) == '\0') { + b->slen += i; + return BSTR_OK; + } + } + b->slen += i; + + /* Need to explicitely resize and concatenate tail */ + return bcatblk (b, (const void *) s, (int) strlen (s)); +} + +/* int bcatblk (bstring b, const void * s, int len) + * + * Concatenate a fixed length buffer to a bstring. + */ +int bcatblk (bstring b, const void * s, int len) { +int nl; + + if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen + || b->mlen <= 0 || s == NULL || len < 0) return BSTR_ERR; + + if (0 > (nl = b->slen + len)) return BSTR_ERR; /* Overflow? */ + if (b->mlen <= nl && 0 > balloc (b, nl + 1)) return BSTR_ERR; + + bBlockCopy (&b->data[b->slen], s, (size_t) len); + b->slen = nl; + b->data[nl] = (unsigned char) '\0'; + return BSTR_OK; +} + +/* bstring bstrcpy (const_bstring b) + * + * Create a copy of the bstring b. + */ +bstring bstrcpy (const_bstring b) { +bstring b0; +int i,j; + + /* Attempted to copy an invalid string? */ + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + + b0 = (bstring) bstr__alloc (sizeof (struct tagbstring)); + if (b0 == NULL) { + /* Unable to allocate memory for string header */ + return NULL; + } + + i = b->slen; + j = snapUpSize (i + 1); + + b0->data = (unsigned char *) bstr__alloc (j); + if (b0->data == NULL) { + j = i + 1; + b0->data = (unsigned char *) bstr__alloc (j); + if (b0->data == NULL) { + /* Unable to allocate memory for string data */ + bstr__free (b0); + return NULL; + } + } + + b0->mlen = j; + b0->slen = i; + + if (i) bstr__memcpy ((char *) b0->data, (char *) b->data, i); + b0->data[b0->slen] = (unsigned char) '\0'; + + return b0; +} + +/* int bassign (bstring a, const_bstring b) + * + * Overwrite the string a with the contents of string b. + */ +int bassign (bstring a, const_bstring b) { + if (b == NULL || b->data == NULL || b->slen < 0) + return BSTR_ERR; + if (b->slen != 0) { + if (balloc (a, b->slen) != BSTR_OK) return BSTR_ERR; + bstr__memmove (a->data, b->data, b->slen); + } else { + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0) + return BSTR_ERR; + } + a->data[b->slen] = (unsigned char) '\0'; + a->slen = b->slen; + return BSTR_OK; +} + +/* int bassignmidstr (bstring a, const_bstring b, int left, int len) + * + * Overwrite the string a with the middle of contents of string b + * starting from position left and running for a length len. left and + * len are clamped to the ends of b as with the function bmidstr. + */ +int bassignmidstr (bstring a, const_bstring b, int left, int len) { + if (b == NULL || b->data == NULL || b->slen < 0) + return BSTR_ERR; + + if (left < 0) { + len += left; + left = 0; + } + + if (len > b->slen - left) len = b->slen - left; + + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0) + return BSTR_ERR; + + if (len > 0) { + if (balloc (a, len) != BSTR_OK) return BSTR_ERR; + bstr__memmove (a->data, b->data + left, len); + a->slen = len; + } else { + a->slen = 0; + } + a->data[a->slen] = (unsigned char) '\0'; + return BSTR_OK; +} + +/* int bassigncstr (bstring a, const char * str) + * + * Overwrite the string a with the contents of char * string str. Note that + * the bstring a must be a well defined and writable bstring. If an error + * occurs BSTR_ERR is returned however a may be partially overwritten. + */ +int bassigncstr (bstring a, const char * str) { +int i; +size_t len; + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0 || NULL == str) + return BSTR_ERR; + + for (i=0; i < a->mlen; i++) { + if ('\0' == (a->data[i] = str[i])) { + a->slen = i; + return BSTR_OK; + } + } + + a->slen = i; + len = strlen (str + i); + if (len > INT_MAX || i + len + 1 > INT_MAX || + 0 > balloc (a, (int) (i + len + 1))) return BSTR_ERR; + bBlockCopy (a->data + i, str + i, (size_t) len + 1); + a->slen += (int) len; + return BSTR_OK; +} + +/* int bassignblk (bstring a, const void * s, int len) + * + * Overwrite the string a with the contents of the block (s, len). Note that + * the bstring a must be a well defined and writable bstring. If an error + * occurs BSTR_ERR is returned and a is not overwritten. + */ +int bassignblk (bstring a, const void * s, int len) { + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0 || NULL == s || len + 1 < 1) + return BSTR_ERR; + if (len + 1 > a->mlen && 0 > balloc (a, len + 1)) return BSTR_ERR; + bBlockCopy (a->data, s, (size_t) len); + a->data[len] = (unsigned char) '\0'; + a->slen = len; + return BSTR_OK; +} + +/* int btrunc (bstring b, int n) + * + * Truncate the bstring to at most n characters. + */ +int btrunc (bstring b, int n) { + if (n < 0 || b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return BSTR_ERR; + if (b->slen > n) { + b->slen = n; + b->data[n] = (unsigned char) '\0'; + } + return BSTR_OK; +} + +#define upcase(c) (toupper ((unsigned char) c)) +#define downcase(c) (tolower ((unsigned char) c)) +#define wspace(c) (isspace ((unsigned char) c)) + +/* int btoupper (bstring b) + * + * Convert contents of bstring to upper case. + */ +int btoupper (bstring b) { +int i, len; + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return BSTR_ERR; + for (i=0, len = b->slen; i < len; i++) { + b->data[i] = (unsigned char) upcase (b->data[i]); + } + return BSTR_OK; +} + +/* int btolower (bstring b) + * + * Convert contents of bstring to lower case. + */ +int btolower (bstring b) { +int i, len; + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return BSTR_ERR; + for (i=0, len = b->slen; i < len; i++) { + b->data[i] = (unsigned char) downcase (b->data[i]); + } + return BSTR_OK; +} + +/* int bstricmp (const_bstring b0, const_bstring b1) + * + * Compare two strings without differentiating between case. The return + * value is the difference of the values of the characters where the two + * strings first differ after lower case transformation, otherwise 0 is + * returned indicating that the strings are equal. If the lengths are + * different, then a difference from 0 is given, but if the first extra + * character is '\0', then it is taken to be the value UCHAR_MAX+1. + */ +int bstricmp (const_bstring b0, const_bstring b1) { +int i, v, n; + + if (bdata (b0) == NULL || b0->slen < 0 || + bdata (b1) == NULL || b1->slen < 0) return SHRT_MIN; + if ((n = b0->slen) > b1->slen) n = b1->slen; + else if (b0->slen == b1->slen && b0->data == b1->data) return BSTR_OK; + + for (i = 0; i < n; i ++) { + v = (char) downcase (b0->data[i]) + - (char) downcase (b1->data[i]); + if (0 != v) return v; + } + + if (b0->slen > n) { + v = (char) downcase (b0->data[n]); + if (v) return v; + return UCHAR_MAX + 1; + } + if (b1->slen > n) { + v = - (char) downcase (b1->data[n]); + if (v) return v; + return - (int) (UCHAR_MAX + 1); + } + return BSTR_OK; +} + +/* int bstrnicmp (const_bstring b0, const_bstring b1, int n) + * + * Compare two strings without differentiating between case for at most n + * characters. If the position where the two strings first differ is + * before the nth position, the return value is the difference of the values + * of the characters, otherwise 0 is returned. If the lengths are different + * and less than n characters, then a difference from 0 is given, but if the + * first extra character is '\0', then it is taken to be the value + * UCHAR_MAX+1. + */ +int bstrnicmp (const_bstring b0, const_bstring b1, int n) { +int i, v, m; + + if (bdata (b0) == NULL || b0->slen < 0 || + bdata (b1) == NULL || b1->slen < 0 || n < 0) return SHRT_MIN; + m = n; + if (m > b0->slen) m = b0->slen; + if (m > b1->slen) m = b1->slen; + + if (b0->data != b1->data) { + for (i = 0; i < m; i ++) { + v = (char) downcase (b0->data[i]); + v -= (char) downcase (b1->data[i]); + if (v != 0) return b0->data[i] - b1->data[i]; + } + } + + if (n == m || b0->slen == b1->slen) return BSTR_OK; + + if (b0->slen > m) { + v = (char) downcase (b0->data[m]); + if (v) return v; + return UCHAR_MAX + 1; + } + + v = - (char) downcase (b1->data[m]); + if (v) return v; + return - (int) (UCHAR_MAX + 1); +} + +/* int biseqcaseless (const_bstring b0, const_bstring b1) + * + * Compare two strings for equality without differentiating between case. + * If the strings differ other than in case, 0 is returned, if the strings + * are the same, 1 is returned, if there is an error, -1 is returned. If + * the length of the strings are different, this function is O(1). '\0' + * termination characters are not treated in any special way. + */ +int biseqcaseless (const_bstring b0, const_bstring b1) { +int i, n; + + if (bdata (b0) == NULL || b0->slen < 0 || + bdata (b1) == NULL || b1->slen < 0) return BSTR_ERR; + if (b0->slen != b1->slen) return BSTR_OK; + if (b0->data == b1->data || b0->slen == 0) return 1; + for (i=0, n=b0->slen; i < n; i++) { + if (b0->data[i] != b1->data[i]) { + unsigned char c = (unsigned char) downcase (b0->data[i]); + if (c != (unsigned char) downcase (b1->data[i])) return 0; + } + } + return 1; +} + +/* int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len) + * + * Compare beginning of string b0 with a block of memory of length len + * without differentiating between case for equality. If the beginning of b0 + * differs from the memory block other than in case (or if b0 is too short), + * 0 is returned, if the strings are the same, 1 is returned, if there is an + * error, -1 is returned. '\0' characters are not treated in any special + * way. + */ +int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len) { +int i; + + if (bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0) + return BSTR_ERR; + if (b0->slen < len) return BSTR_OK; + if (b0->data == (const unsigned char *) blk || len == 0) return 1; + + for (i = 0; i < len; i ++) { + if (b0->data[i] != ((const unsigned char *) blk)[i]) { + if (downcase (b0->data[i]) != + downcase (((const unsigned char *) blk)[i])) return 0; + } + } + return 1; +} + +/* + * int bltrimws (bstring b) + * + * Delete whitespace contiguous from the left end of the string. + */ +int bltrimws (bstring b) { +int i, len; + + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return BSTR_ERR; + + for (len = b->slen, i = 0; i < len; i++) { + if (!wspace (b->data[i])) { + return bdelete (b, 0, i); + } + } + + b->data[0] = (unsigned char) '\0'; + b->slen = 0; + return BSTR_OK; +} + +/* + * int brtrimws (bstring b) + * + * Delete whitespace contiguous from the right end of the string. + */ +int brtrimws (bstring b) { +int i; + + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return BSTR_ERR; + + for (i = b->slen - 1; i >= 0; i--) { + if (!wspace (b->data[i])) { + if (b->mlen > i) b->data[i+1] = (unsigned char) '\0'; + b->slen = i + 1; + return BSTR_OK; + } + } + + b->data[0] = (unsigned char) '\0'; + b->slen = 0; + return BSTR_OK; +} + +/* + * int btrimws (bstring b) + * + * Delete whitespace contiguous from both ends of the string. + */ +int btrimws (bstring b) { +int i, j; + + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return BSTR_ERR; + + for (i = b->slen - 1; i >= 0; i--) { + if (!wspace (b->data[i])) { + if (b->mlen > i) b->data[i+1] = (unsigned char) '\0'; + b->slen = i + 1; + for (j = 0; wspace (b->data[j]); j++) {} + return bdelete (b, 0, j); + } + } + + b->data[0] = (unsigned char) '\0'; + b->slen = 0; + return BSTR_OK; +} + +/* int biseq (const_bstring b0, const_bstring b1) + * + * Compare the string b0 and b1. If the strings differ, 0 is returned, if + * the strings are the same, 1 is returned, if there is an error, -1 is + * returned. If the length of the strings are different, this function is + * O(1). '\0' termination characters are not treated in any special way. + */ +int biseq (const_bstring b0, const_bstring b1) { + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || + b0->slen < 0 || b1->slen < 0) return BSTR_ERR; + if (b0->slen != b1->slen) return BSTR_OK; + if (b0->data == b1->data || b0->slen == 0) return 1; + return !bstr__memcmp (b0->data, b1->data, b0->slen); +} + +/* int bisstemeqblk (const_bstring b0, const void * blk, int len) + * + * Compare beginning of string b0 with a block of memory of length len for + * equality. If the beginning of b0 differs from the memory block (or if b0 + * is too short), 0 is returned, if the strings are the same, 1 is returned, + * if there is an error, -1 is returned. '\0' characters are not treated in + * any special way. + */ +int bisstemeqblk (const_bstring b0, const void * blk, int len) { +int i; + + if (bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0) + return BSTR_ERR; + if (b0->slen < len) return BSTR_OK; + if (b0->data == (const unsigned char *) blk || len == 0) return 1; + + for (i = 0; i < len; i ++) { + if (b0->data[i] != ((const unsigned char *) blk)[i]) return BSTR_OK; + } + return 1; +} + +/* int biseqcstr (const_bstring b, const char *s) + * + * Compare the bstring b and char * string s. The C string s must be '\0' + * terminated at exactly the length of the bstring b, and the contents + * between the two must be identical with the bstring b with no '\0' + * characters for the two contents to be considered equal. This is + * equivalent to the condition that their current contents will be always be + * equal when comparing them in the same format after converting one or the + * other. If the strings are equal 1 is returned, if they are unequal 0 is + * returned and if there is a detectable error BSTR_ERR is returned. + */ +int biseqcstr (const_bstring b, const char * s) { +int i; + if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return BSTR_ERR; + for (i=0; i < b->slen; i++) { + if (s[i] == '\0' || b->data[i] != (unsigned char) s[i]) return BSTR_OK; + } + return s[i] == '\0'; +} + +/* int biseqcstrcaseless (const_bstring b, const char *s) + * + * Compare the bstring b and char * string s. The C string s must be '\0' + * terminated at exactly the length of the bstring b, and the contents + * between the two must be identical except for case with the bstring b with + * no '\0' characters for the two contents to be considered equal. This is + * equivalent to the condition that their current contents will be always be + * equal ignoring case when comparing them in the same format after + * converting one or the other. If the strings are equal, except for case, + * 1 is returned, if they are unequal regardless of case 0 is returned and + * if there is a detectable error BSTR_ERR is returned. + */ +int biseqcstrcaseless (const_bstring b, const char * s) { +int i; + if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return BSTR_ERR; + for (i=0; i < b->slen; i++) { + if (s[i] == '\0' || + (b->data[i] != (unsigned char) s[i] && + downcase (b->data[i]) != (unsigned char) downcase (s[i]))) + return BSTR_OK; + } + return s[i] == '\0'; +} + +/* int bstrcmp (const_bstring b0, const_bstring b1) + * + * Compare the string b0 and b1. If there is an error, SHRT_MIN is returned, + * otherwise a value less than or greater than zero, indicating that the + * string pointed to by b0 is lexicographically less than or greater than + * the string pointed to by b1 is returned. If the the string lengths are + * unequal but the characters up until the length of the shorter are equal + * then a value less than, or greater than zero, indicating that the string + * pointed to by b0 is shorter or longer than the string pointed to by b1 is + * returned. 0 is returned if and only if the two strings are the same. If + * the length of the strings are different, this function is O(n). Like its + * standard C library counter part strcmp, the comparison does not proceed + * past any '\0' termination characters encountered. + */ +int bstrcmp (const_bstring b0, const_bstring b1) { +int i, v, n; + + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || + b0->slen < 0 || b1->slen < 0) return SHRT_MIN; + n = b0->slen; if (n > b1->slen) n = b1->slen; + if (b0->slen == b1->slen && (b0->data == b1->data || b0->slen == 0)) + return BSTR_OK; + + for (i = 0; i < n; i ++) { + v = ((char) b0->data[i]) - ((char) b1->data[i]); + if (v != 0) return v; + if (b0->data[i] == (unsigned char) '\0') return BSTR_OK; + } + + if (b0->slen > n) return 1; + if (b1->slen > n) return -1; + return BSTR_OK; +} + +/* int bstrncmp (const_bstring b0, const_bstring b1, int n) + * + * Compare the string b0 and b1 for at most n characters. If there is an + * error, SHRT_MIN is returned, otherwise a value is returned as if b0 and + * b1 were first truncated to at most n characters then bstrcmp was called + * with these new strings are paremeters. If the length of the strings are + * different, this function is O(n). Like its standard C library counter + * part strcmp, the comparison does not proceed past any '\0' termination + * characters encountered. + */ +int bstrncmp (const_bstring b0, const_bstring b1, int n) { +int i, v, m; + + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || + b0->slen < 0 || b1->slen < 0) return SHRT_MIN; + m = n; + if (m > b0->slen) m = b0->slen; + if (m > b1->slen) m = b1->slen; + + if (b0->data != b1->data) { + for (i = 0; i < m; i ++) { + v = ((char) b0->data[i]) - ((char) b1->data[i]); + if (v != 0) return v; + if (b0->data[i] == (unsigned char) '\0') return BSTR_OK; + } + } + + if (n == m || b0->slen == b1->slen) return BSTR_OK; + + if (b0->slen > m) return 1; + return -1; +} + +/* bstring bmidstr (const_bstring b, int left, int len) + * + * Create a bstring which is the substring of b starting from position left + * and running for a length len (clamped by the end of the bstring b.) If + * b is detectably invalid, then NULL is returned. The section described + * by (left, len) is clamped to the boundaries of b. + */ +bstring bmidstr (const_bstring b, int left, int len) { + + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + + if (left < 0) { + len += left; + left = 0; + } + + if (len > b->slen - left) len = b->slen - left; + + if (len <= 0) return bfromcstr (""); + return blk2bstr (b->data + left, len); +} + +/* int bdelete (bstring b, int pos, int len) + * + * Removes characters from pos to pos+len-1 inclusive and shifts the tail of + * the bstring starting from pos+len to pos. len must be positive for this + * call to have any effect. The section of the string described by (pos, + * len) is clamped to boundaries of the bstring b. + */ +int bdelete (bstring b, int pos, int len) { + /* Clamp to left side of bstring */ + if (pos < 0) { + len += pos; + pos = 0; + } + + if (len < 0 || b == NULL || b->data == NULL || b->slen < 0 || + b->mlen < b->slen || b->mlen <= 0) + return BSTR_ERR; + if (len > 0 && pos < b->slen) { + if (pos + len >= b->slen) { + b->slen = pos; + } else { + bBlockCopy ((char *) (b->data + pos), + (char *) (b->data + pos + len), + b->slen - (pos+len)); + b->slen -= len; + } + b->data[b->slen] = (unsigned char) '\0'; + } + return BSTR_OK; +} + +/* int bdestroy (bstring b) + * + * Free up the bstring. Note that if b is detectably invalid or not writable + * then no action is performed and BSTR_ERR is returned. Like a freed memory + * allocation, dereferences, writes or any other action on b after it has + * been bdestroyed is undefined. + */ +int bdestroy (bstring b) { + if (b == NULL || b->slen < 0 || b->mlen <= 0 || b->mlen < b->slen || + b->data == NULL) + return BSTR_ERR; + + bstr__free (b->data); + + /* In case there is any stale usage, there is one more chance to + notice this error. */ + + b->slen = -1; + b->mlen = -__LINE__; + b->data = NULL; + + bstr__free (b); + return BSTR_OK; +} + +/* int binstr (const_bstring b1, int pos, const_bstring b2) + * + * Search for the bstring b2 in b1 starting from position pos, and searching + * forward. If it is found then return with the first position where it is + * found, otherwise return BSTR_ERR. Note that this is just a brute force + * string searcher that does not attempt clever things like the Boyer-Moore + * search algorithm. Because of this there are many degenerate cases where + * this can take much longer than it needs to. + */ +int binstr (const_bstring b1, int pos, const_bstring b2) { +int j, ii, ll, lf; +unsigned char * d0; +unsigned char c0; +register unsigned char * d1; +register unsigned char c1; +register int i; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR; + if (b1->slen == pos) return (b2->slen == 0)?pos:BSTR_ERR; + if (b1->slen < pos || pos < 0) return BSTR_ERR; + if (b2->slen == 0) return pos; + + /* No space to find such a string? */ + if ((lf = b1->slen - b2->slen + 1) <= pos) return BSTR_ERR; + + /* An obvious alias case */ + if (b1->data == b2->data && pos == 0) return 0; + + i = pos; + + d0 = b2->data; + d1 = b1->data; + ll = b2->slen; + + /* Peel off the b2->slen == 1 case */ + c0 = d0[0]; + if (1 == ll) { + for (;i < lf; i++) if (c0 == d1[i]) return i; + return BSTR_ERR; + } + + c1 = c0; + j = 0; + lf = b1->slen - 1; + + ii = -1; + if (i < lf) do { + /* Unrolled current character test */ + if (c1 != d1[i]) { + if (c1 != d1[1+i]) { + i += 2; + continue; + } + i++; + } + + /* Take note if this is the start of a potential match */ + if (0 == j) ii = i; + + /* Shift the test character down by one */ + j++; + i++; + + /* If this isn't past the last character continue */ + if (j < ll) { + c1 = d0[j]; + continue; + } + + N0:; + + /* If no characters mismatched, then we matched */ + if (i == ii+j) return ii; + + /* Shift back to the beginning */ + i -= j; + j = 0; + c1 = c0; + } while (i < lf); + + /* Deal with last case if unrolling caused a misalignment */ + if (i == lf && ll == j+1 && c1 == d1[i]) goto N0; + + return BSTR_ERR; +} + +/* int binstrr (const_bstring b1, int pos, const_bstring b2) + * + * Search for the bstring b2 in b1 starting from position pos, and searching + * backward. If it is found then return with the first position where it is + * found, otherwise return BSTR_ERR. Note that this is just a brute force + * string searcher that does not attempt clever things like the Boyer-Moore + * search algorithm. Because of this there are many degenerate cases where + * this can take much longer than it needs to. + */ +int binstrr (const_bstring b1, int pos, const_bstring b2) { +int j, i, l; +unsigned char * d0, * d1; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR; + if (b1->slen == pos && b2->slen == 0) return pos; + if (b1->slen < pos || pos < 0) return BSTR_ERR; + if (b2->slen == 0) return pos; + + /* Obvious alias case */ + if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return 0; + + i = pos; + if ((l = b1->slen - b2->slen) < 0) return BSTR_ERR; + + /* If no space to find such a string then snap back */ + if (l + 1 <= i) i = l; + j = 0; + + d0 = b2->data; + d1 = b1->data; + l = b2->slen; + + for (;;) { + if (d0[j] == d1[i + j]) { + j ++; + if (j >= l) return i; + } else { + i --; + if (i < 0) break; + j=0; + } + } + + return BSTR_ERR; +} + +/* int binstrcaseless (const_bstring b1, int pos, const_bstring b2) + * + * Search for the bstring b2 in b1 starting from position pos, and searching + * forward but without regard to case. If it is found then return with the + * first position where it is found, otherwise return BSTR_ERR. Note that + * this is just a brute force string searcher that does not attempt clever + * things like the Boyer-Moore search algorithm. Because of this there are + * many degenerate cases where this can take much longer than it needs to. + */ +int binstrcaseless (const_bstring b1, int pos, const_bstring b2) { +int j, i, l, ll; +unsigned char * d0, * d1; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR; + if (b1->slen == pos) return (b2->slen == 0)?pos:BSTR_ERR; + if (b1->slen < pos || pos < 0) return BSTR_ERR; + if (b2->slen == 0) return pos; + + l = b1->slen - b2->slen + 1; + + /* No space to find such a string? */ + if (l <= pos) return BSTR_ERR; + + /* An obvious alias case */ + if (b1->data == b2->data && pos == 0) return BSTR_OK; + + i = pos; + j = 0; + + d0 = b2->data; + d1 = b1->data; + ll = b2->slen; + + for (;;) { + if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) { + j ++; + if (j >= ll) return i; + } else { + i ++; + if (i >= l) break; + j=0; + } + } + + return BSTR_ERR; +} + +/* int binstrrcaseless (const_bstring b1, int pos, const_bstring b2) + * + * Search for the bstring b2 in b1 starting from position pos, and searching + * backward but without regard to case. If it is found then return with the + * first position where it is found, otherwise return BSTR_ERR. Note that + * this is just a brute force string searcher that does not attempt clever + * things like the Boyer-Moore search algorithm. Because of this there are + * many degenerate cases where this can take much longer than it needs to. + */ +int binstrrcaseless (const_bstring b1, int pos, const_bstring b2) { +int j, i, l; +unsigned char * d0, * d1; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR; + if (b1->slen == pos && b2->slen == 0) return pos; + if (b1->slen < pos || pos < 0) return BSTR_ERR; + if (b2->slen == 0) return pos; + + /* Obvious alias case */ + if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return BSTR_OK; + + i = pos; + if ((l = b1->slen - b2->slen) < 0) return BSTR_ERR; + + /* If no space to find such a string then snap back */ + if (l + 1 <= i) i = l; + j = 0; + + d0 = b2->data; + d1 = b1->data; + l = b2->slen; + + for (;;) { + if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) { + j ++; + if (j >= l) return i; + } else { + i --; + if (i < 0) break; + j=0; + } + } + + return BSTR_ERR; +} + + +/* int bstrchrp (const_bstring b, int c, int pos) + * + * Search for the character c in b forwards from the position pos + * (inclusive). + */ +int bstrchrp (const_bstring b, int c, int pos) { +unsigned char * p; + + if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return BSTR_ERR; + p = (unsigned char *) bstr__memchr ((b->data + pos), (unsigned char) c, (b->slen - pos)); + if (p) return (int) (p - b->data); + return BSTR_ERR; +} + +/* int bstrrchrp (const_bstring b, int c, int pos) + * + * Search for the character c in b backwards from the position pos in string + * (inclusive). + */ +int bstrrchrp (const_bstring b, int c, int pos) { +int i; + + if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return BSTR_ERR; + for (i=pos; i >= 0; i--) { + if (b->data[i] == (unsigned char) c) return i; + } + return BSTR_ERR; +} + +#if !defined (BSTRLIB_AGGRESSIVE_MEMORY_FOR_SPEED_TRADEOFF) +#define LONG_LOG_BITS_QTY (3) +#define LONG_BITS_QTY (1 << LONG_LOG_BITS_QTY) +#define LONG_TYPE unsigned char + +#define CFCLEN ((1 << CHAR_BIT) / LONG_BITS_QTY) +struct charField { LONG_TYPE content[CFCLEN]; }; +#define testInCharField(cf,c) ((cf)->content[(c) >> LONG_LOG_BITS_QTY] & (((long)1) << ((c) & (LONG_BITS_QTY-1)))) +#define setInCharField(cf,idx) { \ + unsigned int c = (unsigned int) (idx); \ + (cf)->content[c >> LONG_LOG_BITS_QTY] |= (LONG_TYPE) (1ul << (c & (LONG_BITS_QTY-1))); \ +} + +#else + +#define CFCLEN (1 << CHAR_BIT) +struct charField { unsigned char content[CFCLEN]; }; +#define testInCharField(cf,c) ((cf)->content[(unsigned char) (c)]) +#define setInCharField(cf,idx) (cf)->content[(unsigned int) (idx)] = ~0 + +#endif + +/* Convert a bstring to charField */ +static int buildCharField (struct charField * cf, const_bstring b) { +int i; + if (b == NULL || b->data == NULL || b->slen <= 0) return BSTR_ERR; + memset ((void *) cf->content, 0, sizeof (struct charField)); + for (i=0; i < b->slen; i++) { + setInCharField (cf, b->data[i]); + } + return BSTR_OK; +} + +static void invertCharField (struct charField * cf) { +int i; + for (i=0; i < CFCLEN; i++) cf->content[i] = ~cf->content[i]; +} + +/* Inner engine for binchr */ +static int binchrCF (const unsigned char * data, int len, int pos, const struct charField * cf) { +int i; + for (i=pos; i < len; i++) { + unsigned char c = (unsigned char) data[i]; + if (testInCharField (cf, c)) return i; + } + return BSTR_ERR; +} + +/* int binchr (const_bstring b0, int pos, const_bstring b1); + * + * Search for the first position in b0 starting from pos or after, in which + * one of the characters in b1 is found and return it. If such a position + * does not exist in b0, then BSTR_ERR is returned. + */ +int binchr (const_bstring b0, int pos, const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || + b0->slen <= pos) return BSTR_ERR; + if (1 == b1->slen) return bstrchrp (b0, b1->data[0], pos); + if (0 > buildCharField (&chrs, b1)) return BSTR_ERR; + return binchrCF (b0->data, b0->slen, pos, &chrs); +} + +/* Inner engine for binchrr */ +static int binchrrCF (const unsigned char * data, int pos, const struct charField * cf) { +int i; + for (i=pos; i >= 0; i--) { + unsigned int c = (unsigned int) data[i]; + if (testInCharField (cf, c)) return i; + } + return BSTR_ERR; +} + +/* int binchrr (const_bstring b0, int pos, const_bstring b1); + * + * Search for the last position in b0 no greater than pos, in which one of + * the characters in b1 is found and return it. If such a position does not + * exist in b0, then BSTR_ERR is returned. + */ +int binchrr (const_bstring b0, int pos, const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || b1 == NULL || + b0->slen < pos) return BSTR_ERR; + if (pos == b0->slen) pos--; + if (1 == b1->slen) return bstrrchrp (b0, b1->data[0], pos); + if (0 > buildCharField (&chrs, b1)) return BSTR_ERR; + return binchrrCF (b0->data, pos, &chrs); +} + +/* int bninchr (const_bstring b0, int pos, const_bstring b1); + * + * Search for the first position in b0 starting from pos or after, in which + * none of the characters in b1 is found and return it. If such a position + * does not exist in b0, then BSTR_ERR is returned. + */ +int bninchr (const_bstring b0, int pos, const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || + b0->slen <= pos) return BSTR_ERR; + if (buildCharField (&chrs, b1) < 0) return BSTR_ERR; + invertCharField (&chrs); + return binchrCF (b0->data, b0->slen, pos, &chrs); +} + +/* int bninchrr (const_bstring b0, int pos, const_bstring b1); + * + * Search for the last position in b0 no greater than pos, in which none of + * the characters in b1 is found and return it. If such a position does not + * exist in b0, then BSTR_ERR is returned. + */ +int bninchrr (const_bstring b0, int pos, const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || + b0->slen < pos) return BSTR_ERR; + if (pos == b0->slen) pos--; + if (buildCharField (&chrs, b1) < 0) return BSTR_ERR; + invertCharField (&chrs); + return binchrrCF (b0->data, pos, &chrs); +} + +/* int bsetstr (bstring b0, int pos, bstring b1, unsigned char fill) + * + * Overwrite the string b0 starting at position pos with the string b1. If + * the position pos is past the end of b0, then the character "fill" is + * appended as necessary to make up the gap between the end of b0 and pos. + * If b1 is NULL, it behaves as if it were a 0-length string. + */ +int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill) { +int d, newlen; +ptrdiff_t pd; +bstring aux = (bstring) b1; + + if (pos < 0 || b0 == NULL || b0->slen < 0 || NULL == b0->data || + b0->mlen < b0->slen || b0->mlen <= 0) return BSTR_ERR; + if (b1 != NULL && (b1->slen < 0 || b1->data == NULL)) return BSTR_ERR; + + d = pos; + + /* Aliasing case */ + if (NULL != aux) { + if ((pd = (ptrdiff_t) (b1->data - b0->data)) >= 0 && pd < (ptrdiff_t) b0->mlen) { + if (NULL == (aux = bstrcpy (b1))) return BSTR_ERR; + } + d += aux->slen; + } + + /* Increase memory size if necessary */ + if (balloc (b0, d + 1) != BSTR_OK) { + if (aux != b1) bdestroy (aux); + return BSTR_ERR; + } + + newlen = b0->slen; + + /* Fill in "fill" character as necessary */ + if (pos > newlen) { + bstr__memset (b0->data + b0->slen, (int) fill, (size_t) (pos - b0->slen)); + newlen = pos; + } + + /* Copy b1 to position pos in b0. */ + if (aux != NULL) { + bBlockCopy ((char *) (b0->data + pos), (char *) aux->data, aux->slen); + if (aux != b1) bdestroy (aux); + } + + /* Indicate the potentially increased size of b0 */ + if (d > newlen) newlen = d; + + b0->slen = newlen; + b0->data[newlen] = (unsigned char) '\0'; + + return BSTR_OK; +} + +/* int binsert (bstring b1, int pos, bstring b2, unsigned char fill) + * + * Inserts the string b2 into b1 at position pos. If the position pos is + * past the end of b1, then the character "fill" is appended as necessary to + * make up the gap between the end of b1 and pos. Unlike bsetstr, binsert + * does not allow b2 to be NULL. + */ +int binsert (bstring b1, int pos, const_bstring b2, unsigned char fill) { +int d, l; +ptrdiff_t pd; +bstring aux = (bstring) b2; + + if (pos < 0 || b1 == NULL || b2 == NULL || b1->slen < 0 || + b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return BSTR_ERR; + + /* Aliasing case */ + if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->mlen) { + if (NULL == (aux = bstrcpy (b2))) return BSTR_ERR; + } + + /* Compute the two possible end pointers */ + d = b1->slen + aux->slen; + l = pos + aux->slen; + if ((d|l) < 0) return BSTR_ERR; + + if (l > d) { + /* Inserting past the end of the string */ + if (balloc (b1, l + 1) != BSTR_OK) { + if (aux != b2) bdestroy (aux); + return BSTR_ERR; + } + bstr__memset (b1->data + b1->slen, (int) fill, (size_t) (pos - b1->slen)); + b1->slen = l; + } else { + /* Inserting in the middle of the string */ + if (balloc (b1, d + 1) != BSTR_OK) { + if (aux != b2) bdestroy (aux); + return BSTR_ERR; + } + bBlockCopy (b1->data + l, b1->data + pos, d - l); + b1->slen = d; + } + bBlockCopy (b1->data + pos, aux->data, aux->slen); + b1->data[b1->slen] = (unsigned char) '\0'; + if (aux != b2) bdestroy (aux); + return BSTR_OK; +} + +/* int breplace (bstring b1, int pos, int len, bstring b2, + * unsigned char fill) + * + * Replace a section of a string from pos for a length len with the string b2. + * fill is used is pos > b1->slen. + */ +int breplace (bstring b1, int pos, int len, const_bstring b2, + unsigned char fill) { +int pl, ret; +ptrdiff_t pd; +bstring aux = (bstring) b2; + + if (pos < 0 || len < 0 || (pl = pos + len) < 0 || b1 == NULL || + b2 == NULL || b1->data == NULL || b2->data == NULL || + b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen || + b1->mlen <= 0) return BSTR_ERR; + + /* Straddles the end? */ + if (pl >= b1->slen) { + if ((ret = bsetstr (b1, pos, b2, fill)) < 0) return ret; + if (pos + b2->slen < b1->slen) { + b1->slen = pos + b2->slen; + b1->data[b1->slen] = (unsigned char) '\0'; + } + return ret; + } + + /* Aliasing case */ + if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->slen) { + if (NULL == (aux = bstrcpy (b2))) return BSTR_ERR; + } + + if (aux->slen > len) { + if (balloc (b1, b1->slen + aux->slen - len) != BSTR_OK) { + if (aux != b2) bdestroy (aux); + return BSTR_ERR; + } + } + + if (aux->slen != len) bstr__memmove (b1->data + pos + aux->slen, b1->data + pos + len, b1->slen - (pos + len)); + bstr__memcpy (b1->data + pos, aux->data, aux->slen); + b1->slen += aux->slen - len; + b1->data[b1->slen] = (unsigned char) '\0'; + if (aux != b2) bdestroy (aux); + return BSTR_OK; +} + +/* + * findreplaceengine is used to implement bfindreplace and + * bfindreplacecaseless. It works by breaking the three cases of + * expansion, reduction and replacement, and solving each of these + * in the most efficient way possible. + */ + +typedef int (*instr_fnptr) (const_bstring s1, int pos, const_bstring s2); + +#define INITIAL_STATIC_FIND_INDEX_COUNT 32 + +static int findreplaceengine (bstring b, const_bstring find, const_bstring repl, int pos, instr_fnptr instr) { +int i, ret, slen, mlen, delta, acc; +int * d; +int static_d[INITIAL_STATIC_FIND_INDEX_COUNT+1]; /* This +1 is unnecessary, but it shuts up LINT. */ +ptrdiff_t pd; +bstring auxf = (bstring) find; +bstring auxr = (bstring) repl; + + if (b == NULL || b->data == NULL || find == NULL || + find->data == NULL || repl == NULL || repl->data == NULL || + pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen || + b->mlen <= 0 || b->slen < 0 || repl->slen < 0) return BSTR_ERR; + if (pos > b->slen - find->slen) return BSTR_OK; + + /* Alias with find string */ + pd = (ptrdiff_t) (find->data - b->data); + if ((ptrdiff_t) (pos - find->slen) < pd && pd < (ptrdiff_t) b->slen) { + if (NULL == (auxf = bstrcpy (find))) return BSTR_ERR; + } + + /* Alias with repl string */ + pd = (ptrdiff_t) (repl->data - b->data); + if ((ptrdiff_t) (pos - repl->slen) < pd && pd < (ptrdiff_t) b->slen) { + if (NULL == (auxr = bstrcpy (repl))) { + if (auxf != find) bdestroy (auxf); + return BSTR_ERR; + } + } + + delta = auxf->slen - auxr->slen; + + /* in-place replacement since find and replace strings are of equal + length */ + if (delta == 0) { + while ((pos = instr (b, pos, auxf)) >= 0) { + bstr__memcpy (b->data + pos, auxr->data, auxr->slen); + pos += auxf->slen; + } + if (auxf != find) bdestroy (auxf); + if (auxr != repl) bdestroy (auxr); + return BSTR_OK; + } + + /* shrinking replacement since auxf->slen > auxr->slen */ + if (delta > 0) { + acc = 0; + + while ((i = instr (b, pos, auxf)) >= 0) { + if (acc && i > pos) + bstr__memmove (b->data + pos - acc, b->data + pos, i - pos); + if (auxr->slen) + bstr__memcpy (b->data + i - acc, auxr->data, auxr->slen); + acc += delta; + pos = i + auxf->slen; + } + + if (acc) { + i = b->slen; + if (i > pos) + bstr__memmove (b->data + pos - acc, b->data + pos, i - pos); + b->slen -= acc; + b->data[b->slen] = (unsigned char) '\0'; + } + + if (auxf != find) bdestroy (auxf); + if (auxr != repl) bdestroy (auxr); + return BSTR_OK; + } + + /* expanding replacement since find->slen < repl->slen. Its a lot + more complicated. This works by first finding all the matches and + storing them to a growable array, then doing at most one resize of + the destination bstring and then performing the direct memory transfers + of the string segment pieces to form the final result. The growable + array of matches uses a deferred doubling reallocing strategy. What + this means is that it starts as a reasonably fixed sized auto array in + the hopes that many if not most cases will never need to grow this + array. But it switches as soon as the bounds of the array will be + exceeded. An extra find result is always appended to this array that + corresponds to the end of the destination string, so slen is checked + against mlen - 1 rather than mlen before resizing. + */ + + mlen = INITIAL_STATIC_FIND_INDEX_COUNT; + d = (int *) static_d; /* Avoid malloc for trivial/initial cases */ + acc = slen = 0; + + while ((pos = instr (b, pos, auxf)) >= 0) { + if (slen >= mlen - 1) { + int sl, *t; + + mlen += mlen; + sl = sizeof (int *) * mlen; + if (static_d == d) d = NULL; /* static_d cannot be realloced */ + if (mlen <= 0 || sl < mlen || NULL == (t = (int *) bstr__realloc (d, sl))) { + ret = BSTR_ERR; + goto done; + } + if (NULL == d) bstr__memcpy (t, static_d, sizeof (static_d)); + d = t; + } + d[slen] = pos; + slen++; + acc -= delta; + pos += auxf->slen; + if (pos < 0 || acc < 0) { + ret = BSTR_ERR; + goto done; + } + } + + /* slen <= INITIAL_STATIC_INDEX_COUNT-1 or mlen-1 here. */ + d[slen] = b->slen; + + if (BSTR_OK == (ret = balloc (b, b->slen + acc + 1))) { + b->slen += acc; + for (i = slen-1; i >= 0; i--) { + int s, l; + s = d[i] + auxf->slen; + l = d[i+1] - s; /* d[slen] may be accessed here. */ + if (l) { + bstr__memmove (b->data + s + acc, b->data + s, l); + } + if (auxr->slen) { + bstr__memmove (b->data + s + acc - auxr->slen, + auxr->data, auxr->slen); + } + acc += delta; + } + b->data[b->slen] = (unsigned char) '\0'; + } + + done:; + if (static_d == d) d = NULL; + bstr__free (d); + if (auxf != find) bdestroy (auxf); + if (auxr != repl) bdestroy (auxr); + return ret; +} + +/* int bfindreplace (bstring b, const_bstring find, const_bstring repl, + * int pos) + * + * Replace all occurrences of a find string with a replace string after a + * given point in a bstring. + */ +int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos) { + return findreplaceengine (b, find, repl, pos, binstr); +} + +/* int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, + * int pos) + * + * Replace all occurrences of a find string, ignoring case, with a replace + * string after a given point in a bstring. + */ +int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos) { + return findreplaceengine (b, find, repl, pos, binstrcaseless); +} + +/* int binsertch (bstring b, int pos, int len, unsigned char fill) + * + * Inserts the character fill repeatedly into b at position pos for a + * length len. If the position pos is past the end of b, then the + * character "fill" is appended as necessary to make up the gap between the + * end of b and the position pos + len. + */ +int binsertch (bstring b, int pos, int len, unsigned char fill) { +int d, l, i; + + if (pos < 0 || b == NULL || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || len < 0) return BSTR_ERR; + + /* Compute the two possible end pointers */ + d = b->slen + len; + l = pos + len; + if ((d|l) < 0) return BSTR_ERR; + + if (l > d) { + /* Inserting past the end of the string */ + if (balloc (b, l + 1) != BSTR_OK) return BSTR_ERR; + pos = b->slen; + b->slen = l; + } else { + /* Inserting in the middle of the string */ + if (balloc (b, d + 1) != BSTR_OK) return BSTR_ERR; + for (i = d - 1; i >= l; i--) { + b->data[i] = b->data[i - len]; + } + b->slen = d; + } + + for (i=pos; i < l; i++) b->data[i] = fill; + b->data[b->slen] = (unsigned char) '\0'; + return BSTR_OK; +} + +/* int bpattern (bstring b, int len) + * + * Replicate the bstring, b in place, end to end repeatedly until it + * surpasses len characters, then chop the result to exactly len characters. + * This function operates in-place. The function will return with BSTR_ERR + * if b is NULL or of length 0, otherwise BSTR_OK is returned. + */ +int bpattern (bstring b, int len) { +int i, d; + + d = blength (b); + if (d <= 0 || len < 0 || balloc (b, len + 1) != BSTR_OK) return BSTR_ERR; + if (len > 0) { + if (d == 1) return bsetstr (b, len, NULL, b->data[0]); + for (i = d; i < len; i++) b->data[i] = b->data[i - d]; + } + b->data[len] = (unsigned char) '\0'; + b->slen = len; + return BSTR_OK; +} + +#define BS_BUFF_SZ (1024) + +/* int breada (bstring b, bNread readPtr, void * parm) + * + * Use a finite buffer fread-like function readPtr to concatenate to the + * bstring b the entire contents of file-like source data in a roughly + * efficient way. + */ +int breada (bstring b, bNread readPtr, void * parm) { +int i, l, n; + + if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || readPtr == NULL) return BSTR_ERR; + + i = b->slen; + for (n=i+16; ; n += ((n < BS_BUFF_SZ) ? n : BS_BUFF_SZ)) { + if (BSTR_OK != balloc (b, n + 1)) return BSTR_ERR; + l = (int) readPtr ((void *) (b->data + i), 1, n - i, parm); + i += l; + b->slen = i; + if (i < n) break; + } + + b->data[i] = (unsigned char) '\0'; + return BSTR_OK; +} + +/* bstring bread (bNread readPtr, void * parm) + * + * Use a finite buffer fread-like function readPtr to create a bstring + * filled with the entire contents of file-like source data in a roughly + * efficient way. + */ +bstring bread (bNread readPtr, void * parm) { +bstring buff; + + if (0 > breada (buff = bfromcstr (""), readPtr, parm)) { + bdestroy (buff); + return NULL; + } + return buff; +} + +/* int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator) + * + * Use an fgetc-like single character stream reading function (getcPtr) to + * obtain a sequence of characters which are concatenated to the end of the + * bstring b. The stream read is terminated by the passed in terminator + * parameter. + * + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * function returns with a partial result in b. If there is an empty partial + * result, 1 is returned. If no characters are read, or there is some other + * detectable error, BSTR_ERR is returned. + */ +int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator) { +int c, d, e; + + if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || getcPtr == NULL) return BSTR_ERR; + d = 0; + e = b->mlen - 2; + + while ((c = getcPtr (parm)) >= 0) { + if (d > e) { + b->slen = d; + if (balloc (b, d + 2) != BSTR_OK) return BSTR_ERR; + e = b->mlen - 2; + } + b->data[d] = (unsigned char) c; + d++; + if (c == terminator) break; + } + + b->data[d] = (unsigned char) '\0'; + b->slen = d; + + return d == 0 && c < 0; +} + +/* int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator) + * + * Use an fgetc-like single character stream reading function (getcPtr) to + * obtain a sequence of characters which are concatenated to the end of the + * bstring b. The stream read is terminated by the passed in terminator + * parameter. + * + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * function returns with a partial result concatentated to b. If there is + * an empty partial result, 1 is returned. If no characters are read, or + * there is some other detectable error, BSTR_ERR is returned. + */ +int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator) { +int c, d, e; + + if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || getcPtr == NULL) return BSTR_ERR; + d = b->slen; + e = b->mlen - 2; + + while ((c = getcPtr (parm)) >= 0) { + if (d > e) { + b->slen = d; + if (balloc (b, d + 2) != BSTR_OK) return BSTR_ERR; + e = b->mlen - 2; + } + b->data[d] = (unsigned char) c; + d++; + if (c == terminator) break; + } + + b->data[d] = (unsigned char) '\0'; + b->slen = d; + + return d == 0 && c < 0; +} + +/* bstring bgets (bNgetc getcPtr, void * parm, char terminator) + * + * Use an fgetc-like single character stream reading function (getcPtr) to + * obtain a sequence of characters which are concatenated into a bstring. + * The stream read is terminated by the passed in terminator function. + * + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * result obtained thus far is returned. If no characters are read, or + * there is some other detectable error, NULL is returned. + */ +bstring bgets (bNgetc getcPtr, void * parm, char terminator) { +bstring buff; + + if (0 > bgetsa (buff = bfromcstr (""), getcPtr, parm, terminator) || 0 >= buff->slen) { + bdestroy (buff); + buff = NULL; + } + return buff; +} + +struct bStream { + bstring buff; /* Buffer for over-reads */ + void * parm; /* The stream handle for core stream */ + bNread readFnPtr; /* fread compatible fnptr for core stream */ + int isEOF; /* track file's EOF state */ + int maxBuffSz; +}; + +/* struct bStream * bsopen (bNread readPtr, void * parm) + * + * Wrap a given open stream (described by a fread compatible function + * pointer and stream handle) into an open bStream suitable for the bstring + * library streaming functions. + */ +struct bStream * bsopen (bNread readPtr, void * parm) { +struct bStream * s; + + if (readPtr == NULL) return NULL; + s = (struct bStream *) bstr__alloc (sizeof (struct bStream)); + if (s == NULL) return NULL; + s->parm = parm; + s->buff = bfromcstr (""); + s->readFnPtr = readPtr; + s->maxBuffSz = BS_BUFF_SZ; + s->isEOF = 0; + return s; +} + +/* int bsbufflength (struct bStream * s, int sz) + * + * Set the length of the buffer used by the bStream. If sz is zero, the + * length is not set. This function returns with the previous length. + */ +int bsbufflength (struct bStream * s, int sz) { +int oldSz; + if (s == NULL || sz < 0) return BSTR_ERR; + oldSz = s->maxBuffSz; + if (sz > 0) s->maxBuffSz = sz; + return oldSz; +} + +int bseof (const struct bStream * s) { + if (s == NULL || s->readFnPtr == NULL) return BSTR_ERR; + return s->isEOF && (s->buff->slen == 0); +} + +/* void * bsclose (struct bStream * s) + * + * Close the bStream, and return the handle to the stream that was originally + * used to open the given stream. + */ +void * bsclose (struct bStream * s) { +void * parm; + if (s == NULL) return NULL; + s->readFnPtr = NULL; + if (s->buff) bdestroy (s->buff); + s->buff = NULL; + parm = s->parm; + s->parm = NULL; + s->isEOF = 1; + bstr__free (s); + return parm; +} + +/* int bsreadlna (bstring r, struct bStream * s, char terminator) + * + * Read a bstring terminated by the terminator character or the end of the + * stream from the bStream (s) and return it into the parameter r. This + * function may read additional characters from the core stream that are not + * returned, but will be retained for subsequent read operations. + */ +int bsreadlna (bstring r, struct bStream * s, char terminator) { +int i, l, ret, rlo; +char * b; +struct tagbstring x; + + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 || + r->slen < 0 || r->mlen < r->slen) return BSTR_ERR; + l = s->buff->slen; + if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR; + b = (char *) s->buff->data; + x.data = (unsigned char *) b; + + /* First check if the current buffer holds the terminator */ + b[l] = terminator; /* Set sentinel */ + for (i=0; b[i] != terminator; i++) ; + if (i < l) { + x.slen = i + 1; + ret = bconcat (r, &x); + s->buff->slen = l; + if (BSTR_OK == ret) bdelete (s->buff, 0, i + 1); + return BSTR_OK; + } + + rlo = r->slen; + + /* If not then just concatenate the entire buffer to the output */ + x.slen = l; + if (BSTR_OK != bconcat (r, &x)) return BSTR_ERR; + + /* Perform direct in-place reads into the destination to allow for + the minimum of data-copies */ + for (;;) { + if (BSTR_OK != balloc (r, r->slen + s->maxBuffSz + 1)) return BSTR_ERR; + b = (char *) (r->data + r->slen); + l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm); + if (l <= 0) { + r->data[r->slen] = (unsigned char) '\0'; + s->buff->slen = 0; + s->isEOF = 1; + /* If nothing was read return with an error message */ + return BSTR_ERR & -(r->slen == rlo); + } + b[l] = terminator; /* Set sentinel */ + for (i=0; b[i] != terminator; i++) ; + if (i < l) break; + r->slen += l; + } + + /* Terminator found, push over-read back to buffer */ + i++; + r->slen += i; + s->buff->slen = l - i; + bstr__memcpy (s->buff->data, b + i, l - i); + r->data[r->slen] = (unsigned char) '\0'; + return BSTR_OK; +} + +/* int bsreadlnsa (bstring r, struct bStream * s, bstring term) + * + * Read a bstring terminated by any character in the term string or the end + * of the stream from the bStream (s) and return it into the parameter r. + * This function may read additional characters from the core stream that + * are not returned, but will be retained for subsequent read operations. + */ +int bsreadlnsa (bstring r, struct bStream * s, const_bstring term) { +int i, l, ret, rlo; +unsigned char * b; +struct tagbstring x; +struct charField cf; + + if (s == NULL || s->buff == NULL || r == NULL || term == NULL || + term->data == NULL || r->mlen <= 0 || r->slen < 0 || + r->mlen < r->slen) return BSTR_ERR; + if (term->slen == 1) return bsreadlna (r, s, term->data[0]); + if (term->slen < 1 || buildCharField (&cf, term)) return BSTR_ERR; + + l = s->buff->slen; + if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR; + b = (unsigned char *) s->buff->data; + x.data = b; + + /* First check if the current buffer holds the terminator */ + b[l] = term->data[0]; /* Set sentinel */ + for (i=0; !testInCharField (&cf, b[i]); i++) ; + if (i < l) { + x.slen = i + 1; + ret = bconcat (r, &x); + s->buff->slen = l; + if (BSTR_OK == ret) bdelete (s->buff, 0, i + 1); + return BSTR_OK; + } + + rlo = r->slen; + + /* If not then just concatenate the entire buffer to the output */ + x.slen = l; + if (BSTR_OK != bconcat (r, &x)) return BSTR_ERR; + + /* Perform direct in-place reads into the destination to allow for + the minimum of data-copies */ + for (;;) { + if (BSTR_OK != balloc (r, r->slen + s->maxBuffSz + 1)) return BSTR_ERR; + b = (unsigned char *) (r->data + r->slen); + l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm); + if (l <= 0) { + r->data[r->slen] = (unsigned char) '\0'; + s->buff->slen = 0; + s->isEOF = 1; + /* If nothing was read return with an error message */ + return BSTR_ERR & -(r->slen == rlo); + } + + b[l] = term->data[0]; /* Set sentinel */ + for (i=0; !testInCharField (&cf, b[i]); i++) ; + if (i < l) break; + r->slen += l; + } + + /* Terminator found, push over-read back to buffer */ + i++; + r->slen += i; + s->buff->slen = l - i; + bstr__memcpy (s->buff->data, b + i, l - i); + r->data[r->slen] = (unsigned char) '\0'; + return BSTR_OK; +} + +/* int bsreada (bstring r, struct bStream * s, int n) + * + * Read a bstring of length n (or, if it is fewer, as many bytes as is + * remaining) from the bStream. This function may read additional + * characters from the core stream that are not returned, but will be + * retained for subsequent read operations. This function will not read + * additional characters from the core stream beyond virtual stream pointer. + */ +int bsreada (bstring r, struct bStream * s, int n) { +int l, ret, orslen; +char * b; +struct tagbstring x; + + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 + || r->slen < 0 || r->mlen < r->slen || n <= 0) return BSTR_ERR; + + n += r->slen; + if (n <= 0) return BSTR_ERR; + + l = s->buff->slen; + + orslen = r->slen; + + if (0 == l) { + if (s->isEOF) return BSTR_ERR; + if (r->mlen > n) { + l = (int) s->readFnPtr (r->data + r->slen, 1, n - r->slen, s->parm); + if (0 >= l || l > n - r->slen) { + s->isEOF = 1; + return BSTR_ERR; + } + r->slen += l; + r->data[r->slen] = (unsigned char) '\0'; + return 0; + } + } + + if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR; + b = (char *) s->buff->data; + x.data = (unsigned char *) b; + + do { + if (l + r->slen >= n) { + x.slen = n - r->slen; + ret = bconcat (r, &x); + s->buff->slen = l; + if (BSTR_OK == ret) bdelete (s->buff, 0, x.slen); + return BSTR_ERR & -(r->slen == orslen); + } + + x.slen = l; + if (BSTR_OK != bconcat (r, &x)) break; + + l = n - r->slen; + if (l > s->maxBuffSz) l = s->maxBuffSz; + + l = (int) s->readFnPtr (b, 1, l, s->parm); + + } while (l > 0); + if (l < 0) l = 0; + if (l == 0) s->isEOF = 1; + s->buff->slen = l; + return BSTR_ERR & -(r->slen == orslen); +} + +/* int bsreadln (bstring r, struct bStream * s, char terminator) + * + * Read a bstring terminated by the terminator character or the end of the + * stream from the bStream (s) and return it into the parameter r. This + * function may read additional characters from the core stream that are not + * returned, but will be retained for subsequent read operations. + */ +int bsreadln (bstring r, struct bStream * s, char terminator) { + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0) + return BSTR_ERR; + if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR; + r->slen = 0; + return bsreadlna (r, s, terminator); +} + +/* int bsreadlns (bstring r, struct bStream * s, bstring term) + * + * Read a bstring terminated by any character in the term string or the end + * of the stream from the bStream (s) and return it into the parameter r. + * This function may read additional characters from the core stream that + * are not returned, but will be retained for subsequent read operations. + */ +int bsreadlns (bstring r, struct bStream * s, const_bstring term) { + if (s == NULL || s->buff == NULL || r == NULL || term == NULL + || term->data == NULL || r->mlen <= 0) return BSTR_ERR; + if (term->slen == 1) return bsreadln (r, s, term->data[0]); + if (term->slen < 1) return BSTR_ERR; + if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR; + r->slen = 0; + return bsreadlnsa (r, s, term); +} + +/* int bsread (bstring r, struct bStream * s, int n) + * + * Read a bstring of length n (or, if it is fewer, as many bytes as is + * remaining) from the bStream. This function may read additional + * characters from the core stream that are not returned, but will be + * retained for subsequent read operations. This function will not read + * additional characters from the core stream beyond virtual stream pointer. + */ +int bsread (bstring r, struct bStream * s, int n) { + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 + || n <= 0) return BSTR_ERR; + if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR; + r->slen = 0; + return bsreada (r, s, n); +} + +/* int bsunread (struct bStream * s, const_bstring b) + * + * Insert a bstring into the bStream at the current position. These + * characters will be read prior to those that actually come from the core + * stream. + */ +int bsunread (struct bStream * s, const_bstring b) { + if (s == NULL || s->buff == NULL) return BSTR_ERR; + return binsert (s->buff, 0, b, (unsigned char) '?'); +} + +/* int bspeek (bstring r, const struct bStream * s) + * + * Return the currently buffered characters from the bStream that will be + * read prior to reads from the core stream. + */ +int bspeek (bstring r, const struct bStream * s) { + if (s == NULL || s->buff == NULL) return BSTR_ERR; + return bassign (r, s->buff); +} + +/* bstring bjoin (const struct bstrList * bl, const_bstring sep); + * + * Join the entries of a bstrList into one bstring by sequentially + * concatenating them with the sep string in between. If there is an error + * NULL is returned, otherwise a bstring with the correct result is returned. + */ +bstring bjoin (const struct bstrList * bl, const_bstring sep) { +bstring b; +int i, c, v; + + if (bl == NULL || bl->qty < 0) return NULL; + if (sep != NULL && (sep->slen < 0 || sep->data == NULL)) return NULL; + + for (i = 0, c = 1; i < bl->qty; i++) { + v = bl->entry[i]->slen; + if (v < 0) return NULL; /* Invalid input */ + c += v; + if (c < 0) return NULL; /* Wrap around ?? */ + } + + if (sep != NULL) c += (bl->qty - 1) * sep->slen; + + b = (bstring) bstr__alloc (sizeof (struct tagbstring)); + if (NULL == b) return NULL; /* Out of memory */ + b->data = (unsigned char *) bstr__alloc (c); + if (b->data == NULL) { + bstr__free (b); + return NULL; + } + + b->mlen = c; + b->slen = c-1; + + for (i = 0, c = 0; i < bl->qty; i++) { + if (i > 0 && sep != NULL) { + bstr__memcpy (b->data + c, sep->data, sep->slen); + c += sep->slen; + } + v = bl->entry[i]->slen; + bstr__memcpy (b->data + c, bl->entry[i]->data, v); + c += v; + } + b->data[c] = (unsigned char) '\0'; + return b; +} + +#define BSSSC_BUFF_LEN (256) + +/* int bssplitscb (struct bStream * s, const_bstring splitStr, + * int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) + * + * Iterate the set of disjoint sequential substrings read from a stream + * divided by any of the characters in splitStr. An empty splitStr causes + * the whole stream to be iterated once. + * + * Note: At the point of calling the cb function, the bStream pointer is + * pointed exactly at the position right after having read the split + * character. The cb function can act on the stream by causing the bStream + * pointer to move, and bssplitscb will continue by starting the next split + * at the position of the pointer after the return from cb. + * + * However, if the cb causes the bStream s to be destroyed then the cb must + * return with a negative value, otherwise bssplitscb will continue in an + * undefined manner. + */ +int bssplitscb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) { +struct charField chrs; +bstring buff; +int i, p, ret; + + if (cb == NULL || s == NULL || s->readFnPtr == NULL + || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; + + if (NULL == (buff = bfromcstr (""))) return BSTR_ERR; + + if (splitStr->slen == 0) { + while (bsreada (buff, s, BSSSC_BUFF_LEN) >= 0) ; + if ((ret = cb (parm, 0, buff)) > 0) + ret = 0; + } else { + buildCharField (&chrs, splitStr); + ret = p = i = 0; + for (;;) { + if (i >= buff->slen) { + bsreada (buff, s, BSSSC_BUFF_LEN); + if (i >= buff->slen) { + if (0 < (ret = cb (parm, p, buff))) ret = 0; + break; + } + } + if (testInCharField (&chrs, buff->data[i])) { + struct tagbstring t; + unsigned char c; + + blk2tbstr (t, buff->data + i + 1, buff->slen - (i + 1)); + if ((ret = bsunread (s, &t)) < 0) break; + buff->slen = i; + c = buff->data[i]; + buff->data[i] = (unsigned char) '\0'; + if ((ret = cb (parm, p, buff)) < 0) break; + buff->data[i] = c; + buff->slen = 0; + p += i + 1; + i = -1; + } + i++; + } + } + + bdestroy (buff); + return ret; +} + +/* int bssplitstrcb (struct bStream * s, const_bstring splitStr, + * int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) + * + * Iterate the set of disjoint sequential substrings read from a stream + * divided by the entire substring splitStr. An empty splitStr causes + * each character of the stream to be iterated. + * + * Note: At the point of calling the cb function, the bStream pointer is + * pointed exactly at the position right after having read the split + * character. The cb function can act on the stream by causing the bStream + * pointer to move, and bssplitscb will continue by starting the next split + * at the position of the pointer after the return from cb. + * + * However, if the cb causes the bStream s to be destroyed then the cb must + * return with a negative value, otherwise bssplitscb will continue in an + * undefined manner. + */ +int bssplitstrcb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) { +bstring buff; +int i, p, ret; + + if (cb == NULL || s == NULL || s->readFnPtr == NULL + || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; + + if (splitStr->slen == 1) return bssplitscb (s, splitStr, cb, parm); + + if (NULL == (buff = bfromcstr (""))) return BSTR_ERR; + + if (splitStr->slen == 0) { + for (i=0; bsreada (buff, s, BSSSC_BUFF_LEN) >= 0; i++) { + if ((ret = cb (parm, 0, buff)) < 0) { + bdestroy (buff); + return ret; + } + buff->slen = 0; + } + return BSTR_OK; + } else { + ret = p = i = 0; + for (i=p=0;;) { + if ((ret = binstr (buff, 0, splitStr)) >= 0) { + struct tagbstring t; + blk2tbstr (t, buff->data, ret); + i = ret + splitStr->slen; + if ((ret = cb (parm, p, &t)) < 0) break; + p += i; + bdelete (buff, 0, i); + } else { + bsreada (buff, s, BSSSC_BUFF_LEN); + if (bseof (s)) { + if ((ret = cb (parm, p, buff)) > 0) ret = 0; + break; + } + } + } + } + + bdestroy (buff); + return ret; +} + +/* int bstrListCreate (void) + * + * Create a bstrList. + */ +struct bstrList * bstrListCreate (void) { +struct bstrList * sl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList)); + if (sl) { + sl->entry = (bstring *) bstr__alloc (1*sizeof (bstring)); + if (!sl->entry) { + bstr__free (sl); + sl = NULL; + } else { + sl->qty = 0; + sl->mlen = 1; + } + } + return sl; +} + +/* int bstrListDestroy (struct bstrList * sl) + * + * Destroy a bstrList that has been created by bsplit, bsplits or bstrListCreate. + */ +int bstrListDestroy (struct bstrList * sl) { +int i; + if (sl == NULL || sl->qty < 0) return BSTR_ERR; + for (i=0; i < sl->qty; i++) { + if (sl->entry[i]) { + bdestroy (sl->entry[i]); + sl->entry[i] = NULL; + } + } + sl->qty = -1; + sl->mlen = -1; + bstr__free (sl->entry); + sl->entry = NULL; + bstr__free (sl); + return BSTR_OK; +} + +/* int bstrListAlloc (struct bstrList * sl, int msz) + * + * Ensure that there is memory for at least msz number of entries for the + * list. + */ +int bstrListAlloc (struct bstrList * sl, int msz) { +bstring * l; +int smsz; +size_t nsz; + if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return BSTR_ERR; + if (sl->mlen >= msz) return BSTR_OK; + smsz = snapUpSize (msz); + nsz = ((size_t) smsz) * sizeof (bstring); + if (nsz < (size_t) smsz) return BSTR_ERR; + l = (bstring *) bstr__realloc (sl->entry, nsz); + if (!l) { + smsz = msz; + nsz = ((size_t) smsz) * sizeof (bstring); + l = (bstring *) bstr__realloc (sl->entry, nsz); + if (!l) return BSTR_ERR; + } + sl->mlen = smsz; + sl->entry = l; + return BSTR_OK; +} + +/* int bstrListAllocMin (struct bstrList * sl, int msz) + * + * Try to allocate the minimum amount of memory for the list to include at + * least msz entries or sl->qty whichever is greater. + */ +int bstrListAllocMin (struct bstrList * sl, int msz) { +bstring * l; +size_t nsz; + if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return BSTR_ERR; + if (msz < sl->qty) msz = sl->qty; + if (sl->mlen == msz) return BSTR_OK; + nsz = ((size_t) msz) * sizeof (bstring); + if (nsz < (size_t) msz) return BSTR_ERR; + l = (bstring *) bstr__realloc (sl->entry, nsz); + if (!l) return BSTR_ERR; + sl->mlen = msz; + sl->entry = l; + return BSTR_OK; +} + +/* int bsplitcb (const_bstring str, unsigned char splitChar, int pos, + * int (* cb) (void * parm, int ofs, int len), void * parm) + * + * Iterate the set of disjoint sequential substrings over str divided by the + * character in splitChar. + * + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. bsplitcb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, bsplitcb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, + * otherwise bsplitcb will continue in an undefined manner. + */ +int bsplitcb (const_bstring str, unsigned char splitChar, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm) { +int i, p, ret; + + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen) + return BSTR_ERR; + + p = pos; + do { + for (i=p; i < str->slen; i++) { + if (str->data[i] == splitChar) break; + } + if ((ret = cb (parm, p, i - p)) < 0) return ret; + p = i + 1; + } while (p <= str->slen); + return BSTR_OK; +} + +/* int bsplitscb (const_bstring str, const_bstring splitStr, int pos, + * int (* cb) (void * parm, int ofs, int len), void * parm) + * + * Iterate the set of disjoint sequential substrings over str divided by any + * of the characters in splitStr. An empty splitStr causes the whole str to + * be iterated once. + * + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. bsplitscb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, bsplitscb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, + * otherwise bsplitscb will continue in an undefined manner. + */ +int bsplitscb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm) { +struct charField chrs; +int i, p, ret; + + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen + || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; + if (splitStr->slen == 0) { + if ((ret = cb (parm, 0, str->slen)) > 0) ret = 0; + return ret; + } + + if (splitStr->slen == 1) + return bsplitcb (str, splitStr->data[0], pos, cb, parm); + + buildCharField (&chrs, splitStr); + + p = pos; + do { + for (i=p; i < str->slen; i++) { + if (testInCharField (&chrs, str->data[i])) break; + } + if ((ret = cb (parm, p, i - p)) < 0) return ret; + p = i + 1; + } while (p <= str->slen); + return BSTR_OK; +} + +/* int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, + * int (* cb) (void * parm, int ofs, int len), void * parm) + * + * Iterate the set of disjoint sequential substrings over str divided by the + * substring splitStr. An empty splitStr causes the whole str to be + * iterated once. + * + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. bsplitstrcb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, bsplitscb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, + * otherwise bsplitscb will continue in an undefined manner. + */ +int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm) { +int i, p, ret; + + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen + || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; + + if (0 == splitStr->slen) { + for (i=pos; i < str->slen; i++) { + if ((ret = cb (parm, i, 1)) < 0) return ret; + } + return BSTR_OK; + } + + if (splitStr->slen == 1) + return bsplitcb (str, splitStr->data[0], pos, cb, parm); + + for (i=p=pos; i <= str->slen - splitStr->slen; i++) { + if (0 == bstr__memcmp (splitStr->data, str->data + i, splitStr->slen)) { + if ((ret = cb (parm, p, i - p)) < 0) return ret; + i += splitStr->slen; + p = i; + } + } + if ((ret = cb (parm, p, str->slen - p)) < 0) return ret; + return BSTR_OK; +} + +struct genBstrList { + bstring b; + struct bstrList * bl; +}; + +static int bscb (void * parm, int ofs, int len) { +struct genBstrList * g = (struct genBstrList *) parm; + if (g->bl->qty >= g->bl->mlen) { + int mlen = g->bl->mlen * 2; + bstring * tbl; + + while (g->bl->qty >= mlen) { + if (mlen < g->bl->mlen) return BSTR_ERR; + mlen += mlen; + } + + tbl = (bstring *) bstr__realloc (g->bl->entry, sizeof (bstring) * mlen); + if (tbl == NULL) return BSTR_ERR; + + g->bl->entry = tbl; + g->bl->mlen = mlen; + } + + g->bl->entry[g->bl->qty] = bmidstr (g->b, ofs, len); + g->bl->qty++; + return BSTR_OK; +} + +/* struct bstrList * bsplit (const_bstring str, unsigned char splitChar) + * + * Create an array of sequential substrings from str divided by the character + * splitChar. + */ +struct bstrList * bsplit (const_bstring str, unsigned char splitChar) { +struct genBstrList g; + + if (str == NULL || str->data == NULL || str->slen < 0) return NULL; + + g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList)); + if (g.bl == NULL) return NULL; + g.bl->mlen = 4; + g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring)); + if (NULL == g.bl->entry) { + bstr__free (g.bl); + return NULL; + } + + g.b = (bstring) str; + g.bl->qty = 0; + if (bsplitcb (str, splitChar, 0, bscb, &g) < 0) { + bstrListDestroy (g.bl); + return NULL; + } + return g.bl; +} + +/* struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr) + * + * Create an array of sequential substrings from str divided by the entire + * substring splitStr. + */ +struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr) { +struct genBstrList g; + + if (str == NULL || str->data == NULL || str->slen < 0) return NULL; + + g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList)); + if (g.bl == NULL) return NULL; + g.bl->mlen = 4; + g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring)); + if (NULL == g.bl->entry) { + bstr__free (g.bl); + return NULL; + } + + g.b = (bstring) str; + g.bl->qty = 0; + if (bsplitstrcb (str, splitStr, 0, bscb, &g) < 0) { + bstrListDestroy (g.bl); + return NULL; + } + return g.bl; +} + +/* struct bstrList * bsplits (const_bstring str, bstring splitStr) + * + * Create an array of sequential substrings from str divided by any of the + * characters in splitStr. An empty splitStr causes a single entry bstrList + * containing a copy of str to be returned. + */ +struct bstrList * bsplits (const_bstring str, const_bstring splitStr) { +struct genBstrList g; + + if ( str == NULL || str->slen < 0 || str->data == NULL || + splitStr == NULL || splitStr->slen < 0 || splitStr->data == NULL) + return NULL; + + g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList)); + if (g.bl == NULL) return NULL; + g.bl->mlen = 4; + g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring)); + if (NULL == g.bl->entry) { + bstr__free (g.bl); + return NULL; + } + g.b = (bstring) str; + g.bl->qty = 0; + + if (bsplitscb (str, splitStr, 0, bscb, &g) < 0) { + bstrListDestroy (g.bl); + return NULL; + } + return g.bl; +} + +#if defined (__TURBOC__) && !defined (__BORLANDC__) +# ifndef BSTRLIB_NOVSNP +# define BSTRLIB_NOVSNP +# endif +#endif + +/* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */ +#if defined(__WATCOMC__) || defined(_MSC_VER) +#define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);} +#else +#ifdef BSTRLIB_NOVSNP +/* This is just a hack. If you are using a system without a vsnprintf, it is + not recommended that bformat be used at all. */ +#define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;} +#define START_VSNBUFF (256) +#else + +#ifdef __GNUC__ +/* Something is making gcc complain about this prototype not being here, so + I've just gone ahead and put it in. */ +extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg); +#endif + +#define exvsnprintf(r,b,n,f,a) {r = vsnprintf (b,n,f,a);} +#endif +#endif + +#if !defined (BSTRLIB_NOVSNP) + +#ifndef START_VSNBUFF +#define START_VSNBUFF (16) +#endif + +/* On IRIX vsnprintf returns n-1 when the operation would overflow the target + buffer, WATCOM and MSVC both return -1, while C99 requires that the + returned value be exactly what the length would be if the buffer would be + large enough. This leads to the idea that if the return value is larger + than n, then changing n to the return value will reduce the number of + iterations required. */ + +/* int bformata (bstring b, const char * fmt, ...) + * + * After the first parameter, it takes the same parameters as printf (), but + * rather than outputting results to stdio, it appends the results to + * a bstring which contains what would have been output. Note that if there + * is an early generation of a '\0' character, the bstring will be truncated + * to this end point. + */ +int bformata (bstring b, const char * fmt, ...) { +va_list arglist; +bstring buff; +int n, r; + + if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 + || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR; + + /* Since the length is not determinable beforehand, a search is + performed using the truncating "vsnprintf" call (to avoid buffer + overflows) on increasing potential sizes for the output result. */ + + if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; + if (NULL == (buff = bfromcstralloc (n + 2, ""))) { + n = 1; + if (NULL == (buff = bfromcstralloc (n + 2, ""))) return BSTR_ERR; + } + + for (;;) { + va_start (arglist, fmt); + exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); + va_end (arglist); + + buff->data[n] = (unsigned char) '\0'; + buff->slen = (int) (strlen) ((char *) buff->data); + + if (buff->slen < n) break; + + if (r > n) n = r; else n += n; + + if (BSTR_OK != balloc (buff, n + 2)) { + bdestroy (buff); + return BSTR_ERR; + } + } + + r = bconcat (b, buff); + bdestroy (buff); + return r; +} + +/* int bassignformat (bstring b, const char * fmt, ...) + * + * After the first parameter, it takes the same parameters as printf (), but + * rather than outputting results to stdio, it outputs the results to + * the bstring parameter b. Note that if there is an early generation of a + * '\0' character, the bstring will be truncated to this end point. + */ +int bassignformat (bstring b, const char * fmt, ...) { +va_list arglist; +bstring buff; +int n, r; + + if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 + || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR; + + /* Since the length is not determinable beforehand, a search is + performed using the truncating "vsnprintf" call (to avoid buffer + overflows) on increasing potential sizes for the output result. */ + + if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; + if (NULL == (buff = bfromcstralloc (n + 2, ""))) { + n = 1; + if (NULL == (buff = bfromcstralloc (n + 2, ""))) return BSTR_ERR; + } + + for (;;) { + va_start (arglist, fmt); + exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); + va_end (arglist); + + buff->data[n] = (unsigned char) '\0'; + buff->slen = (int) (strlen) ((char *) buff->data); + + if (buff->slen < n) break; + + if (r > n) n = r; else n += n; + + if (BSTR_OK != balloc (buff, n + 2)) { + bdestroy (buff); + return BSTR_ERR; + } + } + + r = bassign (b, buff); + bdestroy (buff); + return r; +} + +/* bstring bformat (const char * fmt, ...) + * + * Takes the same parameters as printf (), but rather than outputting results + * to stdio, it forms a bstring which contains what would have been output. + * Note that if there is an early generation of a '\0' character, the + * bstring will be truncated to this end point. + */ +bstring bformat (const char * fmt, ...) { +va_list arglist; +bstring buff; +int n, r; + + if (fmt == NULL) return NULL; + + /* Since the length is not determinable beforehand, a search is + performed using the truncating "vsnprintf" call (to avoid buffer + overflows) on increasing potential sizes for the output result. */ + + if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; + if (NULL == (buff = bfromcstralloc (n + 2, ""))) { + n = 1; + if (NULL == (buff = bfromcstralloc (n + 2, ""))) return NULL; + } + + for (;;) { + va_start (arglist, fmt); + exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); + va_end (arglist); + + buff->data[n] = (unsigned char) '\0'; + buff->slen = (int) (strlen) ((char *) buff->data); + + if (buff->slen < n) break; + + if (r > n) n = r; else n += n; + + if (BSTR_OK != balloc (buff, n + 2)) { + bdestroy (buff); + return NULL; + } + } + + return buff; +} + +/* int bvcformata (bstring b, int count, const char * fmt, va_list arglist) + * + * The bvcformata function formats data under control of the format control + * string fmt and attempts to append the result to b. The fmt parameter is + * the same as that of the printf function. The variable argument list is + * replaced with arglist, which has been initialized by the va_start macro. + * The size of the appended output is upper bounded by count. If the + * required output exceeds count, the string b is not augmented with any + * contents and a value below BSTR_ERR is returned. If a value below -count + * is returned then it is recommended that the negative of this value be + * used as an update to the count in a subsequent pass. On other errors, + * such as running out of memory, parameter errors or numeric wrap around + * BSTR_ERR is returned. BSTR_OK is returned when the output is successfully + * generated and appended to b. + * + * Note: There is no sanity checking of arglist, and this function is + * destructive of the contents of b from the b->slen point onward. If there + * is an early generation of a '\0' character, the bstring will be truncated + * to this end point. + */ +int bvcformata (bstring b, int count, const char * fmt, va_list arg) { +int n, r, l; + + if (b == NULL || fmt == NULL || count <= 0 || b->data == NULL + || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR; + + if (count > (n = b->slen + count) + 2) return BSTR_ERR; + if (BSTR_OK != balloc (b, n + 2)) return BSTR_ERR; + + exvsnprintf (r, (char *) b->data + b->slen, count + 2, fmt, arg); + + /* Did the operation complete successfully within bounds? */ + for (l = b->slen; l <= n; l++) { + if ('\0' == b->data[l]) { + b->slen = l; + return BSTR_OK; + } + } + + /* Abort, since the buffer was not large enough. The return value + tries to help set what the retry length should be. */ + + b->data[b->slen] = '\0'; + if (r > count + 1) { /* Does r specify a particular target length? */ + n = r; + } else { + n = count + count; /* If not, just double the size of count */ + if (count > n) n = INT_MAX; + } + n = -n; + + if (n > BSTR_ERR-1) n = BSTR_ERR-1; + return n; +} + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.h b/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.h new file mode 100644 index 0000000..24626b9 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.h @@ -0,0 +1,304 @@ +/* + * This source file is part of the bstring string library. This code was + * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause + * BSD open source license or GPL v2.0. Refer to the accompanying documentation + * for details on usage and license. + */ + +/* + * bstrlib.h + * + * This file is the header file for the core module for implementing the + * bstring functions. + */ + +#ifndef BSTRLIB_INCLUDE +#define BSTRLIB_INCLUDE + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP) +# if defined (__TURBOC__) && !defined (__BORLANDC__) +# define BSTRLIB_NOVSNP +# endif +#endif + +#define BSTR_ERR (-1) +#define BSTR_OK (0) +#define BSTR_BS_BUFF_LENGTH_GET (0) + +typedef struct tagbstring * bstring; +typedef const struct tagbstring * const_bstring; + +/* Copy functions */ +#define cstr2bstr bfromcstr +extern bstring bfromcstr (const char * str); +extern bstring bfromcstralloc (int mlen, const char * str); +extern bstring blk2bstr (const void * blk, int len); +extern char * bstr2cstr (const_bstring s, char z); +extern int bcstrfree (char * s); +extern bstring bstrcpy (const_bstring b1); +extern int bassign (bstring a, const_bstring b); +extern int bassignmidstr (bstring a, const_bstring b, int left, int len); +extern int bassigncstr (bstring a, const char * str); +extern int bassignblk (bstring a, const void * s, int len); + +/* Destroy function */ +extern int bdestroy (bstring b); + +/* Space allocation hinting functions */ +extern int balloc (bstring s, int len); +extern int ballocmin (bstring b, int len); + +/* Substring extraction */ +extern bstring bmidstr (const_bstring b, int left, int len); + +/* Various standard manipulations */ +extern int bconcat (bstring b0, const_bstring b1); +extern int bconchar (bstring b0, char c); +extern int bcatcstr (bstring b, const char * s); +extern int bcatblk (bstring b, const void * s, int len); +extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill); +extern int binsertch (bstring s1, int pos, int len, unsigned char fill); +extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill); +extern int bdelete (bstring s1, int pos, int len); +extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill); +extern int btrunc (bstring b, int n); + +/* Scan/search functions */ +extern int bstricmp (const_bstring b0, const_bstring b1); +extern int bstrnicmp (const_bstring b0, const_bstring b1, int n); +extern int biseqcaseless (const_bstring b0, const_bstring b1); +extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len); +extern int biseq (const_bstring b0, const_bstring b1); +extern int bisstemeqblk (const_bstring b0, const void * blk, int len); +extern int biseqcstr (const_bstring b, const char * s); +extern int biseqcstrcaseless (const_bstring b, const char * s); +extern int bstrcmp (const_bstring b0, const_bstring b1); +extern int bstrncmp (const_bstring b0, const_bstring b1, int n); +extern int binstr (const_bstring s1, int pos, const_bstring s2); +extern int binstrr (const_bstring s1, int pos, const_bstring s2); +extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2); +extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2); +extern int bstrchrp (const_bstring b, int c, int pos); +extern int bstrrchrp (const_bstring b, int c, int pos); +#define bstrchr(b,c) bstrchrp ((b), (c), 0) +#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1) +extern int binchr (const_bstring b0, int pos, const_bstring b1); +extern int binchrr (const_bstring b0, int pos, const_bstring b1); +extern int bninchr (const_bstring b0, int pos, const_bstring b1); +extern int bninchrr (const_bstring b0, int pos, const_bstring b1); +extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos); +extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos); + +/* List of string container functions */ +struct bstrList { + int qty, mlen; + bstring * entry; +}; +extern struct bstrList * bstrListCreate (void); +extern int bstrListDestroy (struct bstrList * sl); +extern int bstrListAlloc (struct bstrList * sl, int msz); +extern int bstrListAllocMin (struct bstrList * sl, int msz); + +/* String split and join functions */ +extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar); +extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr); +extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr); +extern bstring bjoin (const struct bstrList * bl, const_bstring sep); +extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); +extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); +extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + +/* Miscellaneous functions */ +extern int bpattern (bstring b, int len); +extern int btoupper (bstring b); +extern int btolower (bstring b); +extern int bltrimws (bstring b); +extern int brtrimws (bstring b); +extern int btrimws (bstring b); + +/* <*>printf format functions */ +#if !defined (BSTRLIB_NOVSNP) +extern bstring bformat (const char * fmt, ...); +extern int bformata (bstring b, const char * fmt, ...); +extern int bassignformat (bstring b, const char * fmt, ...); +extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist); + +#define bvformata(ret, b, fmt, lastarg) { \ +bstring bstrtmp_b = (b); \ +const char * bstrtmp_fmt = (fmt); \ +int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \ + for (;;) { \ + va_list bstrtmp_arglist; \ + va_start (bstrtmp_arglist, lastarg); \ + bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \ + va_end (bstrtmp_arglist); \ + if (bstrtmp_r >= 0) { /* Everything went ok */ \ + bstrtmp_r = BSTR_OK; \ + break; \ + } else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \ + bstrtmp_r = BSTR_ERR; \ + break; \ + } \ + bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \ + } \ + ret = bstrtmp_r; \ +} + +#endif + +typedef int (*bNgetc) (void *parm); +typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm); + +/* Input functions */ +extern bstring bgets (bNgetc getcPtr, void * parm, char terminator); +extern bstring bread (bNread readPtr, void * parm); +extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator); +extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator); +extern int breada (bstring b, bNread readPtr, void * parm); + +/* Stream functions */ +extern struct bStream * bsopen (bNread readPtr, void * parm); +extern void * bsclose (struct bStream * s); +extern int bsbufflength (struct bStream * s, int sz); +extern int bsreadln (bstring b, struct bStream * s, char terminator); +extern int bsreadlns (bstring r, struct bStream * s, const_bstring term); +extern int bsread (bstring b, struct bStream * s, int n); +extern int bsreadlna (bstring b, struct bStream * s, char terminator); +extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term); +extern int bsreada (bstring b, struct bStream * s, int n); +extern int bsunread (struct bStream * s, const_bstring b); +extern int bspeek (bstring r, const struct bStream * s); +extern int bssplitscb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); +extern int bssplitstrcb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); +extern int bseof (const struct bStream * s); + +struct tagbstring { + int mlen; + int slen; + unsigned char * data; +}; + +/* Accessor macros */ +#define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen)) +#define blength(b) (blengthe ((b), 0)) +#define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o)) +#define bdataofs(b, o) (bdataofse ((b), (o), (void *)0)) +#define bdatae(b, e) (bdataofse (b, 0, e)) +#define bdata(b) (bdataofs (b, 0)) +#define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e)) +#define bchar(b, p) bchare ((b), (p), '\0') + +/* Static constant string initialization macro */ +#define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")} +#if defined(_MSC_VER) +/* There are many versions of MSVC which emit __LINE__ as a non-constant. */ +# define bsStatic(q) bsStaticMlen(q,-32) +#endif +#ifndef bsStatic +# define bsStatic(q) bsStaticMlen(q,-__LINE__) +#endif + +/* Static constant block parameter pair */ +#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1) + +/* Reference building macros */ +#define cstr2tbstr btfromcstr +#define btfromcstr(t,s) { \ + (t).data = (unsigned char *) (s); \ + (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \ + (t).mlen = -1; \ +} +#define blk2tbstr(t,s,l) { \ + (t).data = (unsigned char *) (s); \ + (t).slen = l; \ + (t).mlen = -1; \ +} +#define btfromblk(t,s,l) blk2tbstr(t,s,l) +#define bmid2tbstr(t,b,p,l) { \ + const_bstring bstrtmp_s = (b); \ + if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \ + int bstrtmp_left = (p); \ + int bstrtmp_len = (l); \ + if (bstrtmp_left < 0) { \ + bstrtmp_len += bstrtmp_left; \ + bstrtmp_left = 0; \ + } \ + if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \ + bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \ + if (bstrtmp_len <= 0) { \ + (t).data = (unsigned char *)""; \ + (t).slen = 0; \ + } else { \ + (t).data = bstrtmp_s->data + bstrtmp_left; \ + (t).slen = bstrtmp_len; \ + } \ + } else { \ + (t).data = (unsigned char *)""; \ + (t).slen = 0; \ + } \ + (t).mlen = -__LINE__; \ +} +#define btfromblkltrimws(t,s,l) { \ + int bstrtmp_idx = 0, bstrtmp_len = (l); \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \ + if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ + } \ + } \ + (t).data = bstrtmp_s + bstrtmp_idx; \ + (t).slen = bstrtmp_len - bstrtmp_idx; \ + (t).mlen = -__LINE__; \ +} +#define btfromblkrtrimws(t,s,l) { \ + int bstrtmp_len = (l) - 1; \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_len >= 0; bstrtmp_len--) { \ + if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ + } \ + } \ + (t).data = bstrtmp_s; \ + (t).slen = bstrtmp_len + 1; \ + (t).mlen = -__LINE__; \ +} +#define btfromblktrimws(t,s,l) { \ + int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \ + if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ + } \ + for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \ + if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ + } \ + } \ + (t).data = bstrtmp_s + bstrtmp_idx; \ + (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \ + (t).mlen = -__LINE__; \ +} + +/* Write protection macros */ +#define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; } +#define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); } +#define biswriteprotected(t) ((t).mlen <= 0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.txt b/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.txt new file mode 100644 index 0000000..8ebb188 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/bstrlib.txt @@ -0,0 +1,3201 @@ +Better String library +--------------------- + +by Paul Hsieh + +The bstring library is an attempt to provide improved string processing +functionality to the C and C++ language. At the heart of the bstring library +(Bstrlib for short) is the management of "bstring"s which are a significant +improvement over '\0' terminated char buffers. + +=============================================================================== + +Motivation +---------- + +The standard C string library has serious problems: + + 1) Its use of '\0' to denote the end of the string means knowing a + string's length is O(n) when it could be O(1). + 2) It imposes an interpretation for the character value '\0'. + 3) gets() always exposes the application to a buffer overflow. + 4) strtok() modifies the string its parsing and thus may not be usable in + programs which are re-entrant or multithreaded. + 5) fgets has the unusual semantic of ignoring '\0's that occur before + '\n's are consumed. + 6) There is no memory management, and actions performed such as strcpy, + strcat and sprintf are common places for buffer overflows. + 7) strncpy() doesn't '\0' terminate the destination in some cases. + 8) Passing NULL to C library string functions causes an undefined NULL + pointer access. + 9) Parameter aliasing (overlapping, or self-referencing parameters) + within most C library functions has undefined behavior. + 10) Many C library string function calls take integer parameters with + restricted legal ranges. Parameters passed outside these ranges are + not typically detected and cause undefined behavior. + +So the desire is to create an alternative string library that does not suffer +from the above problems and adds in the following functionality: + + 1) Incorporate string functionality seen from other languages. + a) MID$() - from BASIC + b) split()/join() - from Python + c) string/char x n - from Perl + 2) Implement analogs to functions that combine stream IO and char buffers + without creating a dependency on stream IO functionality. + 3) Implement the basic text editor-style functions insert, delete, find, + and replace. + 4) Implement reference based sub-string access (as a generalization of + pointer arithmetic.) + 5) Implement runtime write protection for strings. + +There is also a desire to avoid "API-bloat". So functionality that can be +implemented trivially in other functionality is omitted. So there is no +left$() or right$() or reverse() or anything like that as part of the core +functionality. + +Explaining Bstrings +------------------- + +A bstring is basically a header which wraps a pointer to a char buffer. Lets +start with the declaration of a struct tagbstring: + + struct tagbstring { + int mlen; + int slen; + unsigned char * data; + }; + +This definition is considered exposed, not opaque (though it is neither +necessary nor recommended that low level maintenance of bstrings be performed +whenever the abstract interfaces are sufficient). The mlen field (usually) +describes a lower bound for the memory allocated for the data field. The +slen field describes the exact length for the bstring. The data field is a +single contiguous buffer of unsigned chars. Note that the existence of a '\0' +character in the unsigned char buffer pointed to by the data field does not +necessarily denote the end of the bstring. + +To be a well formed modifiable bstring the mlen field must be at least the +length of the slen field, and slen must be non-negative. Furthermore, the +data field must point to a valid buffer in which access to the first mlen +characters has been acquired. So the minimal check for correctness is: + + (slen >= 0 && mlen >= slen && data != NULL) + +bstrings returned by bstring functions can be assumed to be either NULL or +satisfy the above property. (When bstrings are only readable, the mlen >= +slen restriction is not required; this is discussed later in this section.) +A bstring itself is just a pointer to a struct tagbstring: + + typedef struct tagbstring * bstring; + +Note that use of the prefix "tag" in struct tagbstring is required to work +around the inconsistency between C and C++'s struct namespace usage. This +definition is also considered exposed. + +Bstrlib basically manages bstrings allocated as a header and an associated +data-buffer. Since the implementation is exposed, they can also be +constructed manually. Functions which mutate bstrings assume that the header +and data buffer have been malloced; the bstring library may perform free() or +realloc() on both the header and data buffer of any bstring parameter. +Functions which return bstring's create new bstrings. The string memory is +freed by a bdestroy() call (or using the bstrFree macro). + +The following related typedef is also provided: + + typedef const struct tagbstring * const_bstring; + +which is also considered exposed. These are directly bstring compatible (no +casting required) but are just used for parameters which are meant to be +non-mutable. So in general, bstring parameters which are read as input but +not meant to be modified will be declared as const_bstring, and bstring +parameters which may be modified will be declared as bstring. This convention +is recommended for user written functions as well. + +Since bstrings maintain interoperability with C library char-buffer style +strings, all functions which modify, update or create bstrings also append a +'\0' character into the position slen + 1. This trailing '\0' character is +not required for bstrings input to the bstring functions; this is provided +solely as a convenience for interoperability with standard C char-buffer +functionality. + +Analogs for the ANSI C string library functions have been created when they +are necessary, but have also been left out when they are not. In particular +there are no functions analogous to fwrite, or puts just for the purposes of +bstring. The ->data member of any string is exposed, and therefore can be +used just as easily as char buffers for C functions which read strings. + +For those that wish to hand construct bstrings, the following should be kept +in mind: + + 1) While bstrlib can accept constructed bstrings without terminating + '\0' characters, the rest of the C language string library will not + function properly on such non-terminated strings. This is obvious + but must be kept in mind. + 2) If it is intended that a constructed bstring be written to by the + bstring library functions then the data portion should be allocated + by the malloc function and the slen and mlen fields should be entered + properly. The struct tagbstring header is not reallocated, and only + freed by bdestroy. + 3) Writing arbitrary '\0' characters at various places in the string + will not modify its length as perceived by the bstring library + functions. In fact, '\0' is a legitimate non-terminating character + for a bstring to contain. + 4) For read only parameters, bstring functions do not check the mlen. + I.e., the minimal correctness requirements are reduced to: + + (slen >= 0 && data != NULL) + +Better pointer arithmetic +------------------------- + +One built-in feature of '\0' terminated char * strings, is that its very easy +and fast to obtain a reference to the tail of any string using pointer +arithmetic. Bstrlib does one better by providing a way to get a reference to +any substring of a bstring (or any other length delimited block of memory.) +So rather than just having pointer arithmetic, with bstrlib one essentially +has segment arithmetic. This is achieved using the macro blk2tbstr() which +builds a reference to a block of memory and the macro bmid2tbstr() which +builds a reference to a segment of a bstring. Bstrlib also includes +functions for direct consumption of memory blocks into bstrings, namely +bcatblk () and blk2bstr (). + +One scenario where this can be extremely useful is when string contains many +substrings which one would like to pass as read-only reference parameters to +some string consuming function without the need to allocate entire new +containers for the string data. More concretely, imagine parsing a command +line string whose parameters are space delimited. This can only be done for +tails of the string with '\0' terminated char * strings. + +Improved NULL semantics and error handling +------------------------------------------ + +Unless otherwise noted, if a NULL pointer is passed as a bstring or any other +detectably illegal parameter, the called function will return with an error +indicator (either NULL or BSTR_ERR) rather than simply performing a NULL +pointer access, or having undefined behavior. + +To illustrate the value of this, consider the following example: + + strcpy (p = malloc (13 * sizeof (char)), "Hello,"); + strcat (p, " World"); + +This is not correct because malloc may return NULL (due to an out of memory +condition), and the behaviour of strcpy is undefined if either of its +parameters are NULL. However: + + bstrcat (p = bfromcstr ("Hello,"), q = bfromcstr (" World")); + bdestroy (q); + +is well defined, because if either p or q are assigned NULL (indicating a +failure to allocate memory) both bstrcat and bdestroy will recognize it and +perform no detrimental action. + +Note that it is not necessary to check any of the members of a returned +bstring for internal correctness (in particular the data member does not need +to be checked against NULL when the header is non-NULL), since this is +assured by the bstring library itself. + +bStreams +-------- + +In addition to the bgets and bread functions, bstrlib can abstract streams +with a high performance read only stream called a bStream. In general, the +idea is to open a core stream (with something like fopen) then pass its +handle as well as a bNread function pointer (like fread) to the bsopen +function which will return a handle to an open bStream. Then the functions +bsread, bsreadln or bsreadlns can be called to read portions of the stream. +Finally, the bsclose function is called to close the bStream -- it will +return a handle to the original (core) stream. So bStreams, essentially, +wrap other streams. + +The bStreams have two main advantages over the bgets and bread (as well as +fgets/ungetc) paradigms: + +1) Improved functionality via the bunread function which allows a stream to + unread characters, giving the bStream stack-like functionality if so + desired. +2) A very high performance bsreadln function. The C library function fgets() + (and the bgets function) can typically be written as a loop on top of + fgetc(), thus paying all of the overhead costs of calling fgetc on a per + character basis. bsreadln will read blocks at a time, thus amortizing the + overhead of fread calls over many characters at once. + +However, clearly bStreams are suboptimal or unusable for certain kinds of +streams (stdin) or certain usage patterns (a few spotty, or non-sequential +reads from a slow stream.) For those situations, using bgets will be more +appropriate. + +The semantics of bStreams allows practical construction of layerable data +streams. What this means is that by writing a bNread compatible function on +top of a bStream, one can construct a new bStream on top of it. This can be +useful for writing multi-pass parsers that don't actually read the entire +input more than once and don't require the use of intermediate storage. + +Aliasing +-------- + +Aliasing occurs when a function is given two parameters which point to data +structures which overlap in the memory they occupy. While this does not +disturb read only functions, for many libraries this can make functions that +write to these memory locations malfunction. This is a common problem of the +C standard library and especially the string functions in the C standard +library. + +The C standard string library is entirely char by char oriented (as is +bstring) which makes conforming implementations alias safe for some +scenarios. However no actual detection of aliasing is typically performed, +so it is easy to find cases where the aliasing will cause anomolous or +undesirable behaviour (consider: strcat (p, p).) The C99 standard includes +the "restrict" pointer modifier which allows the compiler to document and +assume a no-alias condition on usage. However, only the most trivial cases +can be caught (if at all) by the compiler at compile time, and thus there is +no actual enforcement of non-aliasing. + +Bstrlib, by contrast, permits aliasing and is completely aliasing safe, in +the C99 sense of aliasing. That is to say, under the assumption that +pointers of incompatible types from distinct objects can never alias, bstrlib +is completely aliasing safe. (In practice this means that the data buffer +portion of any bstring and header of any bstring are assumed to never alias.) +With the exception of the reference building macros, the library behaves as +if all read-only parameters are first copied and replaced by temporary +non-aliased parameters before any writing to any output bstring is performed +(though actual copying is extremely rarely ever done.) + +Besides being a useful safety feature, bstring searching/comparison +functions can improve to O(1) execution when aliasing is detected. + +Note that aliasing detection and handling code in Bstrlib is generally +extremely cheap. There is almost never any appreciable performance penalty +for using aliased parameters. + +Reenterancy +----------- + +Nearly every function in Bstrlib is a leaf function, and is completely +reenterable with the exception of writing to common bstrings. The split +functions which use a callback mechanism requires only that the source string +not be destroyed by the callback function unless the callback function returns +with an error status (note that Bstrlib functions which return an error do +not modify the string in any way.) The string can in fact be modified by the +callback and the behaviour is deterministic. See the documentation of the +various split functions for more details. + +Undefined scenarios +------------------- + +One of the basic important premises for Bstrlib is to not to increase the +propogation of undefined situations from parameters that are otherwise legal +in of themselves. In particular, except for extremely marginal cases, usages +of bstrings that use the bstring library functions alone cannot lead to any +undefined action. But due to C/C++ language and library limitations, there +is no way to define a non-trivial library that is completely without +undefined operations. All such possible undefined operations are described +below: + +1) bstrings or struct tagbstrings that are not explicitely initialized cannot + be passed as a parameter to any bstring function. +2) The members of the NULL bstring cannot be accessed directly. (Though all + APIs and macros detect the NULL bstring.) +3) A bstring whose data member has not been obtained from a malloc or + compatible call and which is write accessible passed as a writable + parameter will lead to undefined results. (i.e., do not writeAllow any + constructed bstrings unless the data portion has been obtained from the + heap.) +4) If the headers of two strings alias but are not identical (which can only + happen via a defective manual construction), then passing them to a + bstring function in which one is writable is not defined. +5) If the mlen member is larger than the actual accessible length of the data + member for a writable bstring, or if the slen member is larger than the + readable length of the data member for a readable bstring, then the + corresponding bstring operations are undefined. +6) Any bstring definition whose header or accessible data portion has been + assigned to inaccessible or otherwise illegal memory clearly cannot be + acted upon by the bstring library in any way. +7) Destroying the source of an incremental split from within the callback + and not returning with a negative value (indicating that it should abort) + will lead to undefined behaviour. (Though *modifying* or adjusting the + state of the source data, even if those modification fail within the + bstrlib API, has well defined behavior.) +8) Modifying a bstring which is write protected by direct access has + undefined behavior. + +While this may seem like a long list, with the exception of invalid uses of +the writeAllow macro, and source destruction during an iterative split +without an accompanying abort, no usage of the bstring API alone can cause +any undefined scenario to occurr. I.e., the policy of restricting usage of +bstrings to the bstring API can significantly reduce the risk of runtime +errors (in practice it should eliminate them) related to string manipulation +due to undefined action. + +C++ wrapper +----------- + +A C++ wrapper has been created to enable bstring functionality for C++ in the +most natural (for C++ programers) way possible. The mandate for the C++ +wrapper is different from the base C bstring library. Since the C++ language +has far more abstracting capabilities, the CBString structure is considered +fully abstracted -- i.e., hand generated CBStrings are not supported (though +conversion from a struct tagbstring is allowed) and all detectable errors are +manifest as thrown exceptions. + +- The C++ class definitions are all under the namespace Bstrlib. bstrwrap.h + enables this namespace (with a using namespace Bstrlib; directive at the + end) unless the macro BSTRLIB_DONT_ASSUME_NAMESPACE has been defined before + it is included. + +- Erroneous accesses results in an exception being thrown. The exception + parameter is of type "struct CBStringException" which is derived from + std::exception if STL is used. A verbose description of the error message + can be obtained from the what() method. + +- CBString is a C++ structure derived from a struct tagbstring. An address + of a CBString cast to a bstring must not be passed to bdestroy. The bstring + C API has been made C++ safe and can be used directly in a C++ project. + +- It includes constructors which can take a char, '\0' terminated char + buffer, tagbstring, (char, repeat-value), a length delimited buffer or a + CBStringList to initialize it. + +- Concatenation is performed with the + and += operators. Comparisons are + done with the ==, !=, <, >, <= and >= operators. Note that == and != use + the biseq call, while <, >, <= and >= use bstrcmp. + +- CBString's can be directly cast to const character buffers. + +- CBString's can be directly cast to double, float, int or unsigned int so + long as the CBString are decimal representations of those types (otherwise + an exception will be thrown). Converting the other way should be done with + the format(a) method(s). + +- CBString contains the length, character and [] accessor methods. The + character and [] accessors are aliases of each other. If the bounds for + the string are exceeded, an exception is thrown. To avoid the overhead for + this check, first cast the CBString to a (const char *) and use [] to + dereference the array as normal. Note that the character and [] accessor + methods allows both reading and writing of individual characters. + +- The methods: format, formata, find, reversefind, findcaseless, + reversefindcaseless, midstr, insert, insertchrs, replace, findreplace, + findreplacecaseless, remove, findchr, nfindchr, alloc, toupper, tolower, + gets, read are analogous to the functions that can be found in the C API. + +- The caselessEqual and caselessCmp methods are analogous to biseqcaseless + and bstricmp functions respectively. + +- Note that just like the bformat function, the format and formata methods do + not automatically cast CBStrings into char * strings for "%s"-type + substitutions: + + CBString w("world"); + CBString h("Hello"); + CBString hw; + + /* The casts are necessary */ + hw.format ("%s, %s", (const char *)h, (const char *)w); + +- The methods trunc and repeat have been added instead of using pattern. + +- ltrim, rtrim and trim methods have been added. These remove characters + from a given character string set (defaulting to the whitespace characters) + from either the left, right or both ends of the CBString, respectively. + +- The method setsubstr is also analogous in functionality to bsetstr, except + that it cannot be passed NULL. Instead the method fill and the fill-style + constructor have been supplied to enable this functionality. + +- The writeprotect(), writeallow() and iswriteprotected() methods are + analogous to the bwriteprotect(), bwriteallow() and biswriteprotected() + macros in the C API. Write protection semantics in CBString are stronger + than with the C API in that indexed character assignment is checked for + write protection. However, unlike with the C API, a write protected + CBString can be destroyed by the destructor. + +- CBStream is a C++ structure which wraps a struct bStream (its not derived + from it, since destruction is slightly different). It is constructed by + passing in a bNread function pointer and a stream parameter cast to void *. + This structure includes methods for detecting eof, setting the buffer + length, reading the whole stream or reading entries line by line or block + by block, an unread function, and a peek function. + +- If STL is available, the CBStringList structure is derived from a vector of + CBString with various split methods. The split method has been overloaded + to accept either a character or CBString as the second parameter (when the + split parameter is a CBString any character in that CBString is used as a + seperator). The splitstr method takes a CBString as a substring seperator. + Joins can be performed via a CBString constructor which takes a + CBStringList as a parameter, or just using the CBString::join() method. + +- If there is proper support for std::iostreams, then the >> and << operators + and the getline() function have been added (with semantics the same as + those for std::string). + +Multithreading +-------------- + +A mutable bstring is kind of analogous to a small (two entry) linked list +allocated by malloc, with all aliasing completely under programmer control. +I.e., manipulation of one bstring will never affect any other distinct +bstring unless explicitely constructed to do so by the programmer via hand +construction or via building a reference. Bstrlib also does not use any +static or global storage, so there are no hidden unremovable race conditions. +Bstrings are also clearly not inherently thread local. So just like +char *'s, bstrings can be passed around from thread to thread and shared and +so on, so long as modifications to a bstring correspond to some kind of +exclusive access lock as should be expected (or if the bstring is read-only, +which can be enforced by bstring write protection) for any sort of shared +object in a multithreaded environment. + +Bsafe module +------------ + +For convenience, a bsafe module has been included. The idea is that if this +module is included, inadvertant usage of the most dangerous C functions will +be overridden and lead to an immediate run time abort. Of course, it should +be emphasized that usage of this module is completely optional. The +intention is essentially to provide an option for creating project safety +rules which can be enforced mechanically rather than socially. This is +useful for larger, or open development projects where its more difficult to +enforce social rules or "coding conventions". + +Problems not solved +------------------- + +Bstrlib is written for the C and C++ languages, which have inherent weaknesses +that cannot be easily solved: + +1. Memory leaks: Forgetting to call bdestroy on a bstring that is about to be + unreferenced, just as forgetting to call free on a heap buffer that is + about to be dereferenced. Though bstrlib itself is leak free. +2. Read before write usage: In C, declaring an auto bstring does not + automatically fill it with legal/valid contents. This problem has been + somewhat mitigated in C++. (The bstrDeclare and bstrFree macros from + bstraux can be used to help mitigate this problem.) + +Other problems not addressed: + +3. Built-in mutex usage to automatically avoid all bstring internal race + conditions in multitasking environments: The problem with trying to + implement such things at this low a level is that it is typically more + efficient to use locks in higher level primitives. There is also no + platform independent way to implement locks or mutexes. +4. Unicode/widecharacter support. + +Note that except for spotty support of wide characters, the default C +standard library does not address any of these problems either. + +Configurable compilation options +-------------------------------- + +All configuration options are meant solely for the purpose of compiler +compatibility. Configuration options are not meant to change the semantics +or capabilities of the library, except where it is unavoidable. + +Since some C++ compilers don't include the Standard Template Library and some +have the options of disabling exception handling, a number of macros can be +used to conditionally compile support for each of this: + +BSTRLIB_CAN_USE_STL + + - defining this will enable the used of the Standard Template Library. + Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. + +BSTRLIB_CANNOT_USE_STL + + - defining this will disable the use of the Standard Template Library. + Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. + +BSTRLIB_CAN_USE_IOSTREAM + + - defining this will enable the used of streams from class std. Defining + BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. + +BSTRLIB_CANNOT_USE_IOSTREAM + + - defining this will disable the use of streams from class std. Defining + BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. + +BSTRLIB_THROWS_EXCEPTIONS + + - defining this will enable the exception handling within bstring. + Defining BSTRLIB_THROWS_EXCEPTIONS overrides the + BSTRLIB_DOESNT_THROWS_EXCEPTIONS macro. + +BSTRLIB_DOESNT_THROW_EXCEPTIONS + + - defining this will disable the exception handling within bstring. + Defining BSTRLIB_THROWS_EXCEPTIONS overrides the + BSTRLIB_DOESNT_THROW_EXCEPTIONS macro. + +Note that these macros must be defined consistently throughout all modules +that use CBStrings including bstrwrap.cpp. + +Some older C compilers do not support functions such as vsnprintf. This is +handled by the following macro variables: + +BSTRLIB_NOVSNP + + - defining this indicates that the compiler does not support vsnprintf. + This will cause bformat and bformata to not be declared. Note that + for some compilers, such as Turbo C, this is set automatically. + Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. + +BSTRLIB_VSNP_OK + + - defining this will disable the autodetection of compilers the do not + support of compilers that do not support vsnprintf. + Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. + +Semantic compilation options +---------------------------- + +Bstrlib comes with very few compilation options for changing the semantics of +of the library. These are described below. + +BSTRLIB_DONT_ASSUME_NAMESPACE + + - Defining this before including bstrwrap.h will disable the automatic + enabling of the Bstrlib namespace for the C++ declarations. + +BSTRLIB_DONT_USE_VIRTUAL_DESTRUCTOR + + - Defining this will make the CBString destructor non-virtual. + +BSTRLIB_MEMORY_DEBUG + + - Defining this will cause the bstrlib modules bstrlib.c and bstrwrap.cpp + to invoke a #include "memdbg.h". memdbg.h has to be supplied by the user. + +Note that these macros must be defined consistently throughout all modules +that use bstrings or CBStrings including bstrlib.c, bstraux.c and +bstrwrap.cpp. + +=============================================================================== + +Files +----- + +bstrlib.c - C implementaion of bstring functions. +bstrlib.h - C header file for bstring functions. +bstraux.c - C example that implements trivial additional functions. +bstraux.h - C header for bstraux.c +bstest.c - C unit/regression test for bstrlib.c + +bstrwrap.cpp - C++ implementation of CBString. +bstrwrap.h - C++ header file for CBString. +test.cpp - C++ unit/regression test for bstrwrap.cpp + +bsafe.c - C runtime stubs to abort usage of unsafe C functions. +bsafe.h - C header file for bsafe.c functions. + +C projects need only include bstrlib.h and compile/link bstrlib.c to use the +bstring library. C++ projects need to additionally include bstrwrap.h and +compile/link bstrwrap.cpp. For both, there may be a need to make choices +about feature configuration as described in the "Configurable compilation +options" in the section above. + +Other files that are included in this archive are: + +license.txt - The 3 clause BSD license for Bstrlib +gpl.txt - The GPL version 2 +security.txt - A security statement useful for auditting Bstrlib +porting.txt - A guide to porting Bstrlib +bstrlib.txt - This file + +=============================================================================== + +The functions +------------- + + extern bstring bfromcstr (const char * str); + + Take a standard C library style '\0' terminated char buffer and generate + a bstring with the same contents as the char buffer. If an error occurs + NULL is returned. + + So for example: + + bstring b = bfromcstr ("Hello"); + if (!b) { + fprintf (stderr, "Out of memory"); + } else { + puts ((char *) b->data); + } + + .......................................................................... + + extern bstring bfromcstralloc (int mlen, const char * str); + + Create a bstring which contains the contents of the '\0' terminated + char * buffer str. The memory buffer backing the bstring is at least + mlen characters in length. If an error occurs NULL is returned. + + So for example: + + bstring b = bfromcstralloc (64, someCstr); + if (b) b->data[63] = 'x'; + + The idea is that this will set the 64th character of b to 'x' if it is at + least 64 characters long otherwise do nothing. And we know this is well + defined so long as b was successfully created, since it will have been + allocated with at least 64 characters. + + .......................................................................... + + extern bstring blk2bstr (const void * blk, int len); + + Create a bstring whose contents are described by the contiguous buffer + pointing to by blk with a length of len bytes. Note that this function + creates a copy of the data in blk, rather than simply referencing it. + Compare with the blk2tbstr macro. If an error occurs NULL is returned. + + .......................................................................... + + extern char * bstr2cstr (const_bstring s, char z); + + Create a '\0' terminated char buffer which contains the contents of the + bstring s, except that any contained '\0' characters are converted to the + character in z. This returned value should be freed with bcstrfree(), by + the caller. If an error occurs NULL is returned. + + .......................................................................... + + extern int bcstrfree (char * s); + + Frees a C-string generated by bstr2cstr (). This is normally unnecessary + since it just wraps a call to free (), however, if malloc () and free () + have been redefined as a macros within the bstrlib module (via macros in + the memdbg.h backdoor) with some difference in behaviour from the std + library functions, then this allows a correct way of freeing the memory + that allows higher level code to be independent from these macro + redefinitions. + + .......................................................................... + + extern bstring bstrcpy (const_bstring b1); + + Make a copy of the passed in bstring. The copied bstring is returned if + there is no error, otherwise NULL is returned. + + .......................................................................... + + extern int bassign (bstring a, const_bstring b); + + Overwrite the bstring a with the contents of bstring b. Note that the + bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a is not overwritten. + + .......................................................................... + + int bassigncstr (bstring a, const char * str); + + Overwrite the string a with the contents of char * string str. Note that + the bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a may be partially overwritten. + + .......................................................................... + + int bassignblk (bstring a, const void * s, int len); + + Overwrite the string a with the contents of the block (s, len). Note that + the bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a is not overwritten. + + .......................................................................... + + extern int bassignmidstr (bstring a, const_bstring b, int left, int len); + + Overwrite the bstring a with the middle of contents of bstring b + starting from position left and running for a length len. left and + len are clamped to the ends of b as with the function bmidstr. Note that + the bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a is not overwritten. + + .......................................................................... + + extern bstring bmidstr (const_bstring b, int left, int len); + + Create a bstring which is the substring of b starting from position left + and running for a length len (clamped by the end of the bstring b.) If + there was no error, the value of this constructed bstring is returned + otherwise NULL is returned. + + .......................................................................... + + extern int bdelete (bstring s1, int pos, int len); + + Removes characters from pos to pos+len-1 and shifts the tail of the + bstring starting from pos+len to pos. len must be positive for this call + to have any effect. The section of the bstring described by (pos, len) + is clamped to boundaries of the bstring b. The value BSTR_OK is returned + if the operation is successful, otherwise BSTR_ERR is returned. + + .......................................................................... + + extern int bconcat (bstring b0, const_bstring b1); + + Concatenate the bstring b1 to the end of bstring b0. The value BSTR_OK + is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int bconchar (bstring b, char c); + + Concatenate the character c to the end of bstring b. The value BSTR_OK + is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int bcatcstr (bstring b, const char * s); + + Concatenate the char * string s to the end of bstring b. The value + BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int bcatblk (bstring b, const void * s, int len); + + Concatenate a fixed length buffer (s, len) to the end of bstring b. The + value BSTR_OK is returned if the operation is successful, otherwise + BSTR_ERR is returned. + + .......................................................................... + + extern int biseq (const_bstring b0, const_bstring b1); + + Compare the bstring b0 and b1 for equality. If the bstrings differ, 0 + is returned, if the bstrings are the same, 1 is returned, if there is an + error, -1 is returned. If the length of the bstrings are different, this + function has O(1) complexity. Contained '\0' characters are not treated + as a termination character. + + Note that the semantics of biseq are not completely compatible with + bstrcmp because of its different treatment of the '\0' character. + + .......................................................................... + + extern int bisstemeqblk (const_bstring b, const void * blk, int len); + + Compare beginning of bstring b0 with a block of memory of length len for + equality. If the beginning of b0 differs from the memory block (or if b0 + is too short), 0 is returned, if the bstrings are the same, 1 is returned, + if there is an error, -1 is returned. + + .......................................................................... + + extern int biseqcaseless (const_bstring b0, const_bstring b1); + + Compare two bstrings for equality without differentiating between case. + If the bstrings differ other than in case, 0 is returned, if the bstrings + are the same, 1 is returned, if there is an error, -1 is returned. If + the length of the bstrings are different, this function is O(1). '\0' + termination characters are not treated in any special way. + + .......................................................................... + + extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len); + + Compare beginning of bstring b0 with a block of memory of length len + without differentiating between case for equality. If the beginning of b0 + differs from the memory block other than in case (or if b0 is too short), + 0 is returned, if the bstrings are the same, 1 is returned, if there is an + error, -1 is returned. + + .......................................................................... + + extern int biseqcstr (const_bstring b, const char *s); + + Compare the bstring b and char * bstring s. The C string s must be '\0' + terminated at exactly the length of the bstring b, and the contents + between the two must be identical with the bstring b with no '\0' + characters for the two contents to be considered equal. This is + equivalent to the condition that their current contents will be always be + equal when comparing them in the same format after converting one or the + other. If they are equal 1 is returned, if they are unequal 0 is + returned and if there is a detectable error BSTR_ERR is returned. + + .......................................................................... + + extern int biseqcstrcaseless (const_bstring b, const char *s); + + Compare the bstring b and char * string s. The C string s must be '\0' + terminated at exactly the length of the bstring b, and the contents + between the two must be identical except for case with the bstring b with + no '\0' characters for the two contents to be considered equal. This is + equivalent to the condition that their current contents will be always be + equal ignoring case when comparing them in the same format after + converting one or the other. If they are equal, except for case, 1 is + returned, if they are unequal regardless of case 0 is returned and if + there is a detectable error BSTR_ERR is returned. + + .......................................................................... + + extern int bstrcmp (const_bstring b0, const_bstring b1); + + Compare the bstrings b0 and b1 for ordering. If there is an error, + SHRT_MIN is returned, otherwise a value less than or greater than zero, + indicating that the bstring pointed to by b0 is lexicographically less + than or greater than the bstring pointed to by b1 is returned. If the + bstring lengths are unequal but the characters up until the length of the + shorter are equal then a value less than, or greater than zero, + indicating that the bstring pointed to by b0 is shorter or longer than the + bstring pointed to by b1 is returned. 0 is returned if and only if the + two bstrings are the same. If the length of the bstrings are different, + this function is O(n). Like its standard C library counter part, the + comparison does not proceed past any '\0' termination characters + encountered. + + The seemingly odd error return value, merely provides slightly more + granularity than the undefined situation given in the C library function + strcmp. The function otherwise behaves very much like strcmp(). + + Note that the semantics of bstrcmp are not completely compatible with + biseq because of its different treatment of the '\0' termination + character. + + .......................................................................... + + extern int bstrncmp (const_bstring b0, const_bstring b1, int n); + + Compare the bstrings b0 and b1 for ordering for at most n characters. If + there is an error, SHRT_MIN is returned, otherwise a value is returned as + if b0 and b1 were first truncated to at most n characters then bstrcmp + was called with these new bstrings are paremeters. If the length of the + bstrings are different, this function is O(n). Like its standard C + library counter part, the comparison does not proceed past any '\0' + termination characters encountered. + + The seemingly odd error return value, merely provides slightly more + granularity than the undefined situation given in the C library function + strncmp. The function otherwise behaves very much like strncmp(). + + .......................................................................... + + extern int bstricmp (const_bstring b0, const_bstring b1); + + Compare two bstrings without differentiating between case. The return + value is the difference of the values of the characters where the two + bstrings first differ, otherwise 0 is returned indicating that the + bstrings are equal. If the lengths are different, then a difference from + 0 is given, but if the first extra character is '\0', then it is taken to + be the value UCHAR_MAX+1. + + .......................................................................... + + extern int bstrnicmp (const_bstring b0, const_bstring b1, int n); + + Compare two bstrings without differentiating between case for at most n + characters. If the position where the two bstrings first differ is + before the nth position, the return value is the difference of the values + of the characters, otherwise 0 is returned. If the lengths are different + and less than n characters, then a difference from 0 is given, but if the + first extra character is '\0', then it is taken to be the value + UCHAR_MAX+1. + + .......................................................................... + + extern int bdestroy (bstring b); + + Deallocate the bstring passed. Passing NULL in as a parameter will have + no effect. Note that both the header and the data portion of the bstring + will be freed. No other bstring function which modifies one of its + parameters will free or reallocate the header. Because of this, in + general, bdestroy cannot be called on any declared struct tagbstring even + if it is not write protected. A bstring which is write protected cannot + be destroyed via the bdestroy call. Any attempt to do so will result in + no action taken, and BSTR_ERR will be returned. + + Note to C++ users: Passing in a CBString cast to a bstring will lead to + undefined behavior (free will be called on the header, rather than the + CBString destructor.) Instead just use the ordinary C++ language + facilities to dealloc a CBString. + + .......................................................................... + + extern int binstr (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + forward (increasing) direction. If it is found then it returns with the + first position after pos where it is found, otherwise it returns BSTR_ERR. + The algorithm used is brute force; O(m*n). + + .......................................................................... + + extern int binstrr (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + backward (decreasing) direction. If it is found then it returns with the + first position after pos where it is found, otherwise return BSTR_ERR. + Note that the current position at pos is tested as well -- so to be + disjoint from a previous forward search it is recommended that the + position be backed up (decremented) by one position. The algorithm used + is brute force; O(m*n). + + .......................................................................... + + extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + forward (increasing) direction but without regard to case. If it is + found then it returns with the first position after pos where it is + found, otherwise it returns BSTR_ERR. The algorithm used is brute force; + O(m*n). + + .......................................................................... + + extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + backward (decreasing) direction but without regard to case. If it is + found then it returns with the first position after pos where it is + found, otherwise return BSTR_ERR. Note that the current position at pos + is tested as well -- so to be disjoint from a previous forward search it + is recommended that the position be backed up (decremented) by one + position. The algorithm used is brute force; O(m*n). + + .......................................................................... + + extern int binchr (const_bstring b0, int pos, const_bstring b1); + + Search for the first position in b0 starting from pos or after, in which + one of the characters in b1 is found. This function has an execution + time of O(b0->slen + b1->slen). If such a position does not exist in b0, + then BSTR_ERR is returned. + + .......................................................................... + + extern int binchrr (const_bstring b0, int pos, const_bstring b1); + + Search for the last position in b0 no greater than pos, in which one of + the characters in b1 is found. This function has an execution time + of O(b0->slen + b1->slen). If such a position does not exist in b0, + then BSTR_ERR is returned. + + .......................................................................... + + extern int bninchr (const_bstring b0, int pos, const_bstring b1); + + Search for the first position in b0 starting from pos or after, in which + none of the characters in b1 is found and return it. This function has + an execution time of O(b0->slen + b1->slen). If such a position does + not exist in b0, then BSTR_ERR is returned. + + .......................................................................... + + extern int bninchrr (const_bstring b0, int pos, const_bstring b1); + + Search for the last position in b0 no greater than pos, in which none of + the characters in b1 is found and return it. This function has an + execution time of O(b0->slen + b1->slen). If such a position does not + exist in b0, then BSTR_ERR is returned. + + .......................................................................... + + extern int bstrchr (const_bstring b, int c); + + Search for the character c in the bstring b forwards from the start of + the bstring. Returns the position of the found character or BSTR_ERR if + it is not found. + + NOTE: This has been implemented as a macro on top of bstrchrp (). + + .......................................................................... + + extern int bstrrchr (const_bstring b, int c); + + Search for the character c in the bstring b backwards from the end of the + bstring. Returns the position of the found character or BSTR_ERR if it is + not found. + + NOTE: This has been implemented as a macro on top of bstrrchrp (). + + .......................................................................... + + extern int bstrchrp (const_bstring b, int c, int pos); + + Search for the character c in b forwards from the position pos + (inclusive). Returns the position of the found character or BSTR_ERR if + it is not found. + + .......................................................................... + + extern int bstrrchrp (const_bstring b, int c, int pos); + + Search for the character c in b backwards from the position pos in bstring + (inclusive). Returns the position of the found character or BSTR_ERR if + it is not found. + + .......................................................................... + + extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill); + + Overwrite the bstring b0 starting at position pos with the bstring b1. If + the position pos is past the end of b0, then the character "fill" is + appended as necessary to make up the gap between the end of b0 and pos. + If b1 is NULL, it behaves as if it were a 0-length bstring. The value + BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill); + + Inserts the bstring s2 into s1 at position pos. If the position pos is + past the end of s1, then the character "fill" is appended as necessary to + make up the gap between the end of s1 and pos. The value BSTR_OK is + returned if the operation is successful, otherwise BSTR_ERR is returned. + + .......................................................................... + + extern int binsertch (bstring s1, int pos, int len, unsigned char fill); + + Inserts the character fill repeatedly into s1 at position pos for a + length len. If the position pos is past the end of s1, then the + character "fill" is appended as necessary to make up the gap between the + end of s1 and the position pos + len (exclusive). The value BSTR_OK is + returned if the operation is successful, otherwise BSTR_ERR is returned. + + .......................................................................... + + extern int breplace (bstring b1, int pos, int len, const_bstring b2, + unsigned char fill); + + Replace a section of a bstring from pos for a length len with the bstring + b2. If the position pos is past the end of b1 then the character "fill" + is appended as necessary to make up the gap between the end of b1 and + pos. + + .......................................................................... + + extern int bfindreplace (bstring b, const_bstring find, + const_bstring replace, int position); + + Replace all occurrences of the find substring with a replace bstring + after a given position in the bstring b. The find bstring must have a + length > 0 otherwise BSTR_ERR is returned. This function does not + perform recursive per character replacement; that is to say successive + searches resume at the position after the last replace. + + So for example: + + bfindreplace (a0 = bfromcstr("aabaAb"), a1 = bfromcstr("a"), + a2 = bfromcstr("aa"), 0); + + Should result in changing a0 to "aaaabaaAb". + + This function performs exactly (b->slen - position) bstring comparisons, + and data movement is bounded above by character volume equivalent to size + of the output bstring. + + .......................................................................... + + extern int bfindreplacecaseless (bstring b, const_bstring find, + const_bstring replace, int position); + + Replace all occurrences of the find substring, ignoring case, with a + replace bstring after a given position in the bstring b. The find bstring + must have a length > 0 otherwise BSTR_ERR is returned. This function + does not perform recursive per character replacement; that is to say + successive searches resume at the position after the last replace. + + So for example: + + bfindreplacecaseless (a0 = bfromcstr("AAbaAb"), a1 = bfromcstr("a"), + a2 = bfromcstr("aa"), 0); + + Should result in changing a0 to "aaaabaaaab". + + This function performs exactly (b->slen - position) bstring comparisons, + and data movement is bounded above by character volume equivalent to size + of the output bstring. + + .......................................................................... + + extern int balloc (bstring b, int length); + + Increase the allocated memory backing the data buffer for the bstring b + to a length of at least length. If the memory backing the bstring b is + already large enough, not action is performed. This has no effect on the + bstring b that is visible to the bstring API. Usually this function will + only be used when a minimum buffer size is required coupled with a direct + access to the ->data member of the bstring structure. + + Be warned that like any other bstring function, the bstring must be well + defined upon entry to this function. I.e., doing something like: + + b->slen *= 2; /* ?? Most likely incorrect */ + balloc (b, b->slen); + + is invalid, and should be implemented as: + + int t; + if (BSTR_OK == balloc (b, t = (b->slen * 2))) b->slen = t; + + This function will return with BSTR_ERR if b is not detected as a valid + bstring or length is not greater than 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int ballocmin (bstring b, int length); + + Change the amount of memory backing the bstring b to at least length. + This operation will never truncate the bstring data including the + extra terminating '\0' and thus will not decrease the length to less than + b->slen + 1. Note that repeated use of this function may cause + performance problems (realloc may be called on the bstring more than + the O(log(INT_MAX)) times). This function will return with BSTR_ERR if b + is not detected as a valid bstring or length is not greater than 0, + otherwise BSTR_OK is returned. + + So for example: + + if (BSTR_OK == ballocmin (b, 64)) b->data[63] = 'x'; + + The idea is that this will set the 64th character of b to 'x' if it is at + least 64 characters long otherwise do nothing. And we know this is well + defined so long as the ballocmin call was successfully, since it will + ensure that b has been allocated with at least 64 characters. + + .......................................................................... + + int btrunc (bstring b, int n); + + Truncate the bstring to at most n characters. This function will return + with BSTR_ERR if b is not detected as a valid bstring or n is less than + 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int bpattern (bstring b, int len); + + Replicate the starting bstring, b, end to end repeatedly until it + surpasses len characters, then chop the result to exactly len characters. + This function operates in-place. This function will return with BSTR_ERR + if b is NULL or of length 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int btoupper (bstring b); + + Convert contents of bstring to upper case. This function will return with + BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int btolower (bstring b); + + Convert contents of bstring to lower case. This function will return with + BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int bltrimws (bstring b); + + Delete whitespace contiguous from the left end of the bstring. This + function will return with BSTR_ERR if b is NULL or of length 0, otherwise + BSTR_OK is returned. + + .......................................................................... + + extern int brtrimws (bstring b); + + Delete whitespace contiguous from the right end of the bstring. This + function will return with BSTR_ERR if b is NULL or of length 0, otherwise + BSTR_OK is returned. + + .......................................................................... + + extern int btrimws (bstring b); + + Delete whitespace contiguous from both ends of the bstring. This function + will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK + is returned. + + .......................................................................... + + extern int bstrListCreate (void); + + Create an empty struct bstrList. The struct bstrList output structure is + declared as follows: + + struct bstrList { + int qty, mlen; + bstring * entry; + }; + + The entry field actually is an array with qty number entries. The mlen + record counts the maximum number of bstring's for which there is memory + in the entry record. + + The Bstrlib API does *NOT* include a comprehensive set of functions for + full management of struct bstrList in an abstracted way. The reason for + this is because aliasing semantics of the list are best left to the user + of this function, and performance varies wildly depending on the + assumptions made. For a complete list of bstring data type it is + recommended that the C++ public std::vector be used, since its + semantics are usage are more standard. + + .......................................................................... + + extern int bstrListDestroy (struct bstrList * sl); + + Destroy a struct bstrList structure that was returned by the bsplit + function. Note that this will destroy each bstring in the ->entry array + as well. See bstrListCreate() above for structure of struct bstrList. + + .......................................................................... + + extern int bstrListAlloc (struct bstrList * sl, int msz); + + Ensure that there is memory for at least msz number of entries for the + list. + + .......................................................................... + + extern int bstrListAllocMin (struct bstrList * sl, int msz); + + Try to allocate the minimum amount of memory for the list to include at + least msz entries or sl->qty whichever is greater. + + .......................................................................... + + extern struct bstrList * bsplit (bstring str, unsigned char splitChar); + + Create an array of sequential substrings from str divided by the + character splitChar. Successive occurrences of the splitChar will be + divided by empty bstring entries, following the semantics from the Python + programming language. To reclaim the memory from this output structure, + bstrListDestroy () should be called. See bstrListCreate() above for + structure of struct bstrList. + + .......................................................................... + + extern struct bstrList * bsplits (bstring str, const_bstring splitStr); + + Create an array of sequential substrings from str divided by any + character contained in splitStr. An empty splitStr causes a single entry + bstrList containing a copy of str to be returned. See bstrListCreate() + above for structure of struct bstrList. + + .......................................................................... + + extern struct bstrList * bsplitstr (bstring str, const_bstring splitStr); + + Create an array of sequential substrings from str divided by the entire + substring splitStr. An empty splitStr causes a single entry bstrList + containing a copy of str to be returned. See bstrListCreate() above for + structure of struct bstrList. + + .......................................................................... + + extern bstring bjoin (const struct bstrList * bl, const_bstring sep); + + Join the entries of a bstrList into one bstring by sequentially + concatenating them with the sep bstring in between. If sep is NULL, it + is treated as if it were the empty bstring. Note that: + + bjoin (l = bsplit (b, s->data[0]), s); + + should result in a copy of b, if s->slen is 1. If there is an error NULL + is returned, otherwise a bstring with the correct result is returned. + See bstrListCreate() above for structure of struct bstrList. + + .......................................................................... + + extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + + Iterate the set of disjoint sequential substrings over str starting at + position pos divided by the character splitChar. The parm passed to + bsplitcb is passed on to cb. If the function cb returns a value < 0, + then further iterating is halted and this value is returned by bsplitcb. + + Note: Non-destructive modification of str from within the cb function + while performing this split is not undefined. bsplitcb behaves in + sequential lock step with calls to cb. I.e., after returning from a cb + that return a non-negative integer, bsplitcb continues from the position + 1 character after the last detected split character and it will halt + immediately if the length of str falls below this point. However, if the + cb function destroys str, then it *must* return with a negative value, + otherwise bsplitcb will continue in an undefined manner. + + This function is provided as an incremental alternative to bsplit that is + abortable and which does not impose additional memory allocation. + + .......................................................................... + + extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + + Iterate the set of disjoint sequential substrings over str starting at + position pos divided by any of the characters in splitStr. An empty + splitStr causes the whole str to be iterated once. The parm passed to + bsplitcb is passed on to cb. If the function cb returns a value < 0, + then further iterating is halted and this value is returned by bsplitcb. + + Note: Non-destructive modification of str from within the cb function + while performing this split is not undefined. bsplitscb behaves in + sequential lock step with calls to cb. I.e., after returning from a cb + that return a non-negative integer, bsplitscb continues from the position + 1 character after the last detected split character and it will halt + immediately if the length of str falls below this point. However, if the + cb function destroys str, then it *must* return with a negative value, + otherwise bsplitscb will continue in an undefined manner. + + This function is provided as an incremental alternative to bsplits that + is abortable and which does not impose additional memory allocation. + + .......................................................................... + + extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + + Iterate the set of disjoint sequential substrings over str starting at + position pos divided by the entire substring splitStr. An empty splitStr + causes each character of str to be iterated. The parm passed to bsplitcb + is passed on to cb. If the function cb returns a value < 0, then further + iterating is halted and this value is returned by bsplitcb. + + Note: Non-destructive modification of str from within the cb function + while performing this split is not undefined. bsplitstrcb behaves in + sequential lock step with calls to cb. I.e., after returning from a cb + that return a non-negative integer, bsplitstrcb continues from the position + 1 character after the last detected split character and it will halt + immediately if the length of str falls below this point. However, if the + cb function destroys str, then it *must* return with a negative value, + otherwise bsplitscb will continue in an undefined manner. + + This function is provided as an incremental alternative to bsplitstr that + is abortable and which does not impose additional memory allocation. + + .......................................................................... + + extern bstring bformat (const char * fmt, ...); + + Takes the same parameters as printf (), but rather than outputting + results to stdio, it forms a bstring which contains what would have been + output. Note that if there is an early generation of a '\0' character, + the bstring will be truncated to this end point. + + Note that %s format tokens correspond to '\0' terminated char * buffers, + not bstrings. To print a bstring, first dereference data element of the + the bstring: + + /* b1->data needs to be '\0' terminated, so tagbstrings generated + by blk2tbstr () might not be suitable. */ + b0 = bformat ("Hello, %s", b1->data); + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bformat function is not present. + + .......................................................................... + + extern int bformata (bstring b, const char * fmt, ...); + + In addition to the initial output buffer b, bformata takes the same + parameters as printf (), but rather than outputting results to stdio, it + appends the results to the initial bstring parameter. Note that if + there is an early generation of a '\0' character, the bstring will be + truncated to this end point. + + Note that %s format tokens correspond to '\0' terminated char * buffers, + not bstrings. To print a bstring, first dereference data element of the + the bstring: + + /* b1->data needs to be '\0' terminated, so tagbstrings generated + by blk2tbstr () might not be suitable. */ + bformata (b0 = bfromcstr ("Hello"), ", %s", b1->data); + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bformata function is not present. + + .......................................................................... + + extern int bassignformat (bstring b, const char * fmt, ...); + + After the first parameter, it takes the same parameters as printf (), but + rather than outputting results to stdio, it outputs the results to + the bstring parameter b. Note that if there is an early generation of a + '\0' character, the bstring will be truncated to this end point. + + Note that %s format tokens correspond to '\0' terminated char * buffers, + not bstrings. To print a bstring, first dereference data element of the + the bstring: + + /* b1->data needs to be '\0' terminated, so tagbstrings generated + by blk2tbstr () might not be suitable. */ + bassignformat (b0 = bfromcstr ("Hello"), ", %s", b1->data); + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bassignformat function is not present. + + .......................................................................... + + extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist); + + The bvcformata function formats data under control of the format control + string fmt and attempts to append the result to b. The fmt parameter is + the same as that of the printf function. The variable argument list is + replaced with arglist, which has been initialized by the va_start macro. + The size of the output is upper bounded by count. If the required output + exceeds count, the string b is not augmented with any contents and a value + below BSTR_ERR is returned. If a value below -count is returned then it + is recommended that the negative of this value be used as an update to the + count in a subsequent pass. On other errors, such as running out of + memory, parameter errors or numeric wrap around BSTR_ERR is returned. + BSTR_OK is returned when the output is successfully generated and + appended to b. + + Note: There is no sanity checking of arglist, and this function is + destructive of the contents of b from the b->slen point onward. If there + is an early generation of a '\0' character, the bstring will be truncated + to this end point. + + Although this function is part of the external API for Bstrlib, the + interface and semantics (length limitations, and unusual return codes) + are fairly atypical. The real purpose for this function is to provide an + engine for the bvformata macro. + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bvcformata function is not present. + + .......................................................................... + + extern bstring bread (bNread readPtr, void * parm); + typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, + void *parm); + + Read an entire stream into a bstring, verbatum. The readPtr function + pointer is compatible with fread sematics, except that it need not obtain + the stream data from a file. The intention is that parm would contain + the stream data context/state required (similar to the role of the FILE* + I/O stream parameter of fread.) + + Abstracting the block read function allows for block devices other than + file streams to be read if desired. Note that there is an ANSI + compatibility issue if "fread" is used directly; see the ANSI issues + section below. + + .......................................................................... + + extern int breada (bstring b, bNread readPtr, void * parm); + + Read an entire stream and append it to a bstring, verbatum. Behaves + like bread, except that it appends it results to the bstring b. + BSTR_ERR is returned on error, otherwise 0 is returned. + + .......................................................................... + + extern bstring bgets (bNgetc getcPtr, void * parm, char terminator); + typedef int (* bNgetc) (void * parm); + + Read a bstring from a stream. As many bytes as is necessary are read + until the terminator is consumed or no more characters are available from + the stream. If read from the stream, the terminator character will be + appended to the end of the returned bstring. The getcPtr function must + have the same semantics as the fgetc C library function (i.e., returning + an integer whose value is negative when there are no more characters + available, otherwise the value of the next available unsigned character + from the stream.) The intention is that parm would contain the stream + data context/state required (similar to the role of the FILE* I/O stream + parameter of fgets.) If no characters are read, or there is some other + detectable error, NULL is returned. + + bgets will never call the getcPtr function more often than necessary to + construct its output (including a single call, if required, to determine + that the stream contains no more characters.) + + Abstracting the character stream function and terminator character allows + for different stream devices and string formats other than '\n' + terminated lines in a file if desired (consider \032 terminated email + messages, in a UNIX mailbox for example.) + + For files, this function can be used analogously as fgets as follows: + + fp = fopen ( ... ); + if (fp) b = bgets ((bNgetc) fgetc, fp, '\n'); + + (Note that only one terminator character can be used, and that '\0' is + not assumed to terminate the stream in addition to the terminator + character. This is consistent with the semantics of fgets.) + + .......................................................................... + + extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator); + + Read from a stream and concatenate to a bstring. Behaves like bgets, + except that it appends it results to the bstring b. The value 1 is + returned if no characters are read before a negative result is returned + from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned + in other normal cases. + + .......................................................................... + + extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator); + + Read from a stream and concatenate to a bstring. Behaves like bgets, + except that it assigns the results to the bstring b. The value 1 is + returned if no characters are read before a negative result is returned + from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned + in other normal cases. + + .......................................................................... + + extern struct bStream * bsopen (bNread readPtr, void * parm); + + Wrap a given open stream (described by a fread compatible function + pointer and stream handle) into an open bStream suitable for the bstring + library streaming functions. + + .......................................................................... + + extern void * bsclose (struct bStream * s); + + Close the bStream, and return the handle to the stream that was + originally used to open the given stream. If s is NULL or detectably + invalid, NULL will be returned. + + .......................................................................... + + extern int bsbufflength (struct bStream * s, int sz); + + Set the length of the buffer used by the bStream. If sz is the macro + BSTR_BS_BUFF_LENGTH_GET (which is 0), the length is not set. If s is + NULL or sz is negative, the function will return with BSTR_ERR, otherwise + this function returns with the previous length. + + .......................................................................... + + extern int bsreadln (bstring r, struct bStream * s, char terminator); + + Read a bstring terminated by the terminator character or the end of the + stream from the bStream (s) and return it into the parameter r. The + matched terminator, if found, appears at the end of the line read. If + the stream has been exhausted of all available data, before any can be + read, BSTR_ERR is returned. This function may read additional characters + into the stream buffer from the core stream that are not returned, but + will be retained for subsequent read operations. When reading from high + speed streams, this function can perform significantly faster than bgets. + + .......................................................................... + + extern int bsreadlna (bstring r, struct bStream * s, char terminator); + + Read a bstring terminated by the terminator character or the end of the + stream from the bStream (s) and concatenate it to the parameter r. The + matched terminator, if found, appears at the end of the line read. If + the stream has been exhausted of all available data, before any can be + read, BSTR_ERR is returned. This function may read additional characters + into the stream buffer from the core stream that are not returned, but + will be retained for subsequent read operations. When reading from high + speed streams, this function can perform significantly faster than bgets. + + .......................................................................... + + extern int bsreadlns (bstring r, struct bStream * s, bstring terminators); + + Read a bstring terminated by any character in the terminators bstring or + the end of the stream from the bStream (s) and return it into the + parameter r. This function may read additional characters from the core + stream that are not returned, but will be retained for subsequent read + operations. + + .......................................................................... + + extern int bsreadlnsa (bstring r, struct bStream * s, bstring terminators); + + Read a bstring terminated by any character in the terminators bstring or + the end of the stream from the bStream (s) and concatenate it to the + parameter r. If the stream has been exhausted of all available data, + before any can be read, BSTR_ERR is returned. This function may read + additional characters from the core stream that are not returned, but + will be retained for subsequent read operations. + + .......................................................................... + + extern int bsread (bstring r, struct bStream * s, int n); + + Read a bstring of length n (or, if it is fewer, as many bytes as is + remaining) from the bStream. This function will read the minimum + required number of additional characters from the core stream. When the + stream is at the end of the file BSTR_ERR is returned, otherwise BSTR_OK + is returned. + + .......................................................................... + + extern int bsreada (bstring r, struct bStream * s, int n); + + Read a bstring of length n (or, if it is fewer, as many bytes as is + remaining) from the bStream and concatenate it to the parameter r. This + function will read the minimum required number of additional characters + from the core stream. When the stream is at the end of the file BSTR_ERR + is returned, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int bsunread (struct bStream * s, const_bstring b); + + Insert a bstring into the bStream at the current position. These + characters will be read prior to those that actually come from the core + stream. + + .......................................................................... + + extern int bspeek (bstring r, const struct bStream * s); + + Return the number of currently buffered characters from the bStream that + will be read prior to reads from the core stream, and append it to the + the parameter r. + + .......................................................................... + + extern int bssplitscb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); + + Iterate the set of disjoint sequential substrings over the stream s + divided by any character from the bstring splitStr. The parm passed to + bssplitscb is passed on to cb. If the function cb returns a value < 0, + then further iterating is halted and this return value is returned by + bssplitscb. + + Note: At the point of calling the cb function, the bStream pointer is + pointed exactly at the position right after having read the split + character. The cb function can act on the stream by causing the bStream + pointer to move, and bssplitscb will continue by starting the next split + at the position of the pointer after the return from cb. + + However, if the cb causes the bStream s to be destroyed then the cb must + return with a negative value, otherwise bssplitscb will continue in an + undefined manner. + + This function is provided as way to incrementally parse through a file + or other generic stream that in total size may otherwise exceed the + practical or desired memory available. As with the other split callback + based functions this is abortable and does not impose additional memory + allocation. + + .......................................................................... + + extern int bssplitstrcb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); + + Iterate the set of disjoint sequential substrings over the stream s + divided by the entire substring splitStr. The parm passed to + bssplitstrcb is passed on to cb. If the function cb returns a + value < 0, then further iterating is halted and this return value is + returned by bssplitstrcb. + + Note: At the point of calling the cb function, the bStream pointer is + pointed exactly at the position right after having read the split + character. The cb function can act on the stream by causing the bStream + pointer to move, and bssplitstrcb will continue by starting the next + split at the position of the pointer after the return from cb. + + However, if the cb causes the bStream s to be destroyed then the cb must + return with a negative value, otherwise bssplitscb will continue in an + undefined manner. + + This function is provided as way to incrementally parse through a file + or other generic stream that in total size may otherwise exceed the + practical or desired memory available. As with the other split callback + based functions this is abortable and does not impose additional memory + allocation. + + .......................................................................... + + extern int bseof (const struct bStream * s); + + Return the defacto "EOF" (end of file) state of a stream (1 if the + bStream is in an EOF state, 0 if not, and BSTR_ERR if stream is closed or + detectably erroneous.) When the readPtr callback returns a value <= 0 + the stream reaches its "EOF" state. Note that bunread with non-empty + content will essentially turn off this state, and the stream will not be + in its "EOF" state so long as its possible to read more data out of it. + + Also note that the semantics of bseof() are slightly different from + something like feof(). I.e., reaching the end of the stream does not + necessarily guarantee that bseof() will return with a value indicating + that this has happened. bseof() will only return indicating that it has + reached the "EOF" and an attempt has been made to read past the end of + the bStream. + +The macros +---------- + + The macros described below are shown in a prototype form indicating their + intended usage. Note that the parameters passed to these macros will be + referenced multiple times. As with all macros, programmer care is + required to guard against unintended side effects. + + int blengthe (const_bstring b, int err); + + Returns the length of the bstring. If the bstring is NULL err is + returned. + + .......................................................................... + + int blength (const_bstring b); + + Returns the length of the bstring. If the bstring is NULL, the length + returned is 0. + + .......................................................................... + + int bchare (const_bstring b, int p, int c); + + Returns the p'th character of the bstring b. If the position p refers to + a position that does not exist in the bstring or the bstring is NULL, + then c is returned. + + .......................................................................... + + char bchar (const_bstring b, int p); + + Returns the p'th character of the bstring b. If the position p refers to + a position that does not exist in the bstring or the bstring is NULL, + then '\0' is returned. + + .......................................................................... + + char * bdatae (bstring b, char * err); + + Returns the char * data portion of the bstring b. If b is NULL, err is + returned. + + .......................................................................... + + char * bdata (bstring b); + + Returns the char * data portion of the bstring b. If b is NULL, NULL is + returned. + + .......................................................................... + + char * bdataofse (bstring b, int ofs, char * err); + + Returns the char * data portion of the bstring b offset by ofs. If b is + NULL, err is returned. + + .......................................................................... + + char * bdataofs (bstring b, int ofs); + + Returns the char * data portion of the bstring b offset by ofs. If b is + NULL, NULL is returned. + + .......................................................................... + + struct tagbstring var = bsStatic ("..."); + + The bsStatic macro allows for static declarations of literal string + constants as struct tagbstring structures. The resulting tagbstring does + not need to be freed or destroyed. Note that this macro is only well + defined for string literal arguments. For more general string pointers, + use the btfromcstr macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + <- bsStaticBlkParms ("...") + + The bsStaticBlkParms macro emits a pair of comma seperated parameters + corresponding to the block parameters for the block functions in Bstrlib + (i.e., blk2bstr, bcatblk, blk2tbstr, bisstemeqblk, bisstemeqcaselessblk.) + Note that this macro is only well defined for string literal arguments. + + Examples: + + bstring b = blk2bstr (bsStaticBlkParms ("Fast init. ")); + bcatblk (b, bsStaticBlkParms ("No frills fast concatenation.")); + + These are faster than using bfromcstr() and bcatcstr() respectively + because the length of the inline string is known as a compile time + constant. Also note that seperate struct tagbstring declarations for + holding the output of a bsStatic() macro are not required. + + .......................................................................... + + void btfromcstr (struct tagbstring& t, const char * s); + + Fill in the tagbstring t with the '\0' terminated char buffer s. This + action is purely reference oriented; no memory management is done. The + data member is just assigned s, and slen is assigned the strlen of s. + The s parameter is accessed exactly once in this macro. + + The resulting struct tagbstring is initially write protected. Attempts + to write to this struct tagbstring in a write protected state from any + bstrlib function will lead to BSTR_ERR being returned. Invoke the + bwriteallow on this struct tagbstring to make it writeable (though this + requires that s be obtained from a function compatible with malloc.) + + .......................................................................... + + void btfromblk (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len. This + action is purely reference oriented; no memory management is done. The + data member of t is just assigned s, and slen is assigned len. Note that + the buffer is not appended with a '\0' character. The s and len + parameters are accessed exactly once each in this macro. + + The resulting struct tagbstring is initially write protected. Attempts + to write to this struct tagbstring in a write protected state from any + bstrlib function will lead to BSTR_ERR being returned. Invoke the + bwriteallow on this struct tagbstring to make it writeable (though this + requires that s be obtained from a function compatible with malloc.) + + .......................................................................... + + void btfromblkltrimws (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len after it + has been left trimmed. This action is purely reference oriented; no + memory management is done. The data member of t is just assigned to a + pointer inside the buffer s. Note that the buffer is not appended with a + '\0' character. The s and len parameters are accessed exactly once each + in this macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + void btfromblkrtrimws (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len after it + has been right trimmed. This action is purely reference oriented; no + memory management is done. The data member of t is just assigned to a + pointer inside the buffer s. Note that the buffer is not appended with a + '\0' character. The s and len parameters are accessed exactly once each + in this macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + void btfromblktrimws (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len after it + has been left and right trimmed. This action is purely reference + oriented; no memory management is done. The data member of t is just + assigned to a pointer inside the buffer s. Note that the buffer is not + appended with a '\0' character. The s and len parameters are accessed + exactly once each in this macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + void bmid2tbstr (struct tagbstring& t, bstring b, int pos, int len); + + Fill the tagbstring t with the substring from b, starting from position + pos with a length len. The segment is clamped by the boundaries of + the bstring b. This action is purely reference oriented; no memory + management is done. Note that the buffer is not appended with a '\0' + character. Note that the t parameter to this macro may be accessed + multiple times. Note that the contents of t will become undefined + if the contents of b change or are destroyed. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring in a write protected state from any + bstrlib function will lead to BSTR_ERR being returned. Invoking the + bwriteallow macro on this struct tagbstring will have no effect. + + .......................................................................... + + void bvformata (int& ret, bstring b, const char * format, lastarg); + + Append the bstring b with printf like formatting with the format control + string, and the arguments taken from the ... list of arguments after + lastarg passed to the containing function. If the containing function + does not have ... parameters or lastarg is not the last named parameter + before the ... then the results are undefined. If successful, the + results are appended to b and BSTR_OK is assigned to ret. Otherwise + BSTR_ERR is assigned to ret. + + Example: + + void dbgerror (FILE * fp, const char * fmt, ...) { + int ret; + bstring b; + bvformata (ret, b = bfromcstr ("DBG: "), fmt, fmt); + if (BSTR_OK == ret) fputs ((char *) bdata (b), fp); + bdestroy (b); + } + + Note that if the BSTRLIB_NOVSNP macro was set when bstrlib had been + compiled the bvformata macro will not link properly. If the + BSTRLIB_NOVSNP macro has been set, the bvformata macro will not be + available. + + .......................................................................... + + void bwriteprotect (struct tagbstring& t); + + Disallow bstring from being written to via the bstrlib API. Attempts to + write to the resulting tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. + + Note: bstrings which are write protected cannot be destroyed via bdestroy. + + Note to C++ users: Setting a CBString as write protected will not prevent + it from being destroyed by the destructor. + + .......................................................................... + + void bwriteallow (struct tagbstring& t); + + Allow bstring to be written to via the bstrlib API. Note that such an + action makes the bstring both writable and destroyable. If the bstring is + not legitimately writable (as is the case for struct tagbstrings + initialized with a bsStatic value), the results of this are undefined. + + Note that invoking the bwriteallow macro may increase the number of + reallocs by one more than necessary for every call to bwriteallow + interleaved with any bstring API which writes to this bstring. + + .......................................................................... + + int biswriteprotected (struct tagbstring& t); + + Returns 1 if the bstring is write protected, otherwise 0 is returned. + +=============================================================================== + +The bstest module +----------------- + +The bstest module is just a unit test for the bstrlib module. For correct +implementations of bstrlib, it should execute with 0 failures being reported. +This test should be utilized if modifications/customizations to bstrlib have +been performed. It tests each core bstrlib function with bstrings of every +mode (read-only, NULL, static and mutable) and ensures that the expected +semantics are observed (including results that should indicate an error). It +also tests for aliasing support. Passing bstest is a necessary but not a +sufficient condition for ensuring the correctness of the bstrlib module. + + +The test module +--------------- + +The test module is just a unit test for the bstrwrap module. For correct +implementations of bstrwrap, it should execute with 0 failures being +reported. This test should be utilized if modifications/customizations to +bstrwrap have been performed. It tests each core bstrwrap function with +CBStrings write protected or not and ensures that the expected semantics are +observed (including expected exceptions.) Note that exceptions cannot be +disabled to run this test. Passing test is a necessary but not a sufficient +condition for ensuring the correctness of the bstrwrap module. + +=============================================================================== + +Using Bstring and CBString as an alternative to the C library +------------------------------------------------------------- + +First let us give a table of C library functions and the alternative bstring +functions and CBString methods that should be used instead of them. + +C-library Bstring alternative CBString alternative +--------- ------------------- -------------------- +gets bgets ::gets +strcpy bassign = operator +strncpy bassignmidstr ::midstr +strcat bconcat += operator +strncat bconcat + btrunc += operator + ::trunc +strtok bsplit, bsplits ::split +sprintf b(assign)format ::format +snprintf b(assign)format + btrunc ::format + ::trunc +vsprintf bvformata bvformata + +vsnprintf bvformata + btrunc bvformata + btrunc +vfprintf bvformata + fputs use bvformata + fputs +strcmp biseq, bstrcmp comparison operators. +strncmp bstrncmp, memcmp bstrncmp, memcmp +strlen ->slen, blength ::length +strdup bstrcpy constructor +strset bpattern ::fill +strstr binstr ::find +strpbrk binchr ::findchr +stricmp bstricmp cast & use bstricmp +strlwr btolower cast & use btolower +strupr btoupper cast & use btoupper +strrev bReverse (aux module) cast & use bReverse +strchr bstrchr cast & use bstrchr +strspnp use strspn use strspn +ungetc bsunread bsunread + +The top 9 C functions listed here are troublesome in that they impose memory +management in the calling function. The Bstring and CBstring interfaces have +built-in memory management, so there is far less code with far less potential +for buffer overrun problems. strtok can only be reliably called as a "leaf" +calculation, since it (quite bizarrely) maintains hidden internal state. And +gets is well known to be broken no matter what. The Bstrlib alternatives do +not suffer from those sorts of problems. + +The substitute for strncat can be performed with higher performance by using +the blk2tbstr macro to create a presized second operand for bconcat. + +C-library Bstring alternative CBString alternative +--------- ------------------- -------------------- +strspn strspn acceptable strspn acceptable +strcspn strcspn acceptable strcspn acceptable +strnset strnset acceptable strnset acceptable +printf printf acceptable printf acceptable +puts puts acceptable puts acceptable +fprintf fprintf acceptable fprintf acceptable +fputs fputs acceptable fputs acceptable +memcmp memcmp acceptable memcmp acceptable + +Remember that Bstring (and CBstring) functions will automatically append the +'\0' character to the character data buffer. So by simply accessing the data +buffer directly, ordinary C string library functions can be called directly +on them. Note that bstrcmp is not the same as memcmp in exactly the same way +that strcmp is not the same as memcmp. + +C-library Bstring alternative CBString alternative +--------- ------------------- -------------------- +fread balloc + fread ::alloc + fread +fgets balloc + fgets ::alloc + fgets + +These are odd ones because of the exact sizing of the buffer required. The +Bstring and CBString alternatives requires that the buffers are forced to +hold at least the prescribed length, then just use fread or fgets directly. +However, typically the automatic memory management of Bstring and CBstring +will make the typical use of fgets and fread to read specifically sized +strings unnecessary. + +Implementation Choices +---------------------- + +Overhead: +......... + +The bstring library has more overhead versus straight char buffers for most +functions. This overhead is essentially just the memory management and +string header allocation. This overhead usually only shows up for small +string manipulations. The performance loss has to be considered in +light of the following: + +1) What would be the performance loss of trying to write this management + code in one's own application? +2) Since the bstring library source code is given, a sufficiently powerful + modern inlining globally optimizing compiler can remove function call + overhead. + +Since the data type is exposed, a developer can replace any unsatisfactory +function with their own inline implementation. And that is besides the main +point of what the better string library is mainly meant to provide. Any +overhead lost has to be compared against the value of the safe abstraction +for coupling memory management and string functionality. + +Performance of the C interface: +............................... + +The algorithms used have performance advantages versus the analogous C +library functions. For example: + +1. bfromcstr/blk2str/bstrcpy versus strcpy/strdup. By using memmove instead + of strcpy, the break condition of the copy loop is based on an independent + counter (that should be allocated in a register) rather than having to + check the results of the load. Modern out-of-order executing CPUs can + parallelize the final branch mis-predict penality with the loading of the + source string. Some CPUs will also tend to have better built-in hardware + support for counted memory moves than load-compare-store. (This is a + minor, but non-zero gain.) +2. biseq versus strcmp. If the strings are unequal in length, bsiseq will + return in O(1) time. If the strings are aliased, or have aliased data + buffers, biseq will return in O(1) time. strcmp will always be O(k), + where k is the length of the common prefix or the whole string if they are + identical. +3. ->slen versus strlen. ->slen is obviously always O(1), while strlen is + always O(n) where n is the length of the string. +4. bconcat versus strcat. Both rely on precomputing the length of the + destination string argument, which will favor the bstring library. On + iterated concatenations the performance difference can be enormous. +5. bsreadln versus fgets. The bsreadln function reads large blocks at a time + from the given stream, then parses out lines from the buffers directly. + Some C libraries will implement fgets as a loop over single fgetc calls. + Testing indicates that the bsreadln approach can be several times faster + for fast stream devices (such as a file that has been entirely cached.) +6. bsplits/bsplitscb versus strspn. Accelerators for the set of match + characters are generated only once. +7. binstr versus strstr. The binstr implementation unrolls the loops to + help reduce loop overhead. This will matter if the target string is + long and source string is not found very early in the target string. + With strstr, while it is possible to unroll the source contents, it is + not possible to do so with the destination contents in a way that is + effective because every destination character must be tested against + '\0' before proceeding to the next character. +8. bReverse versus strrev. The C function must find the end of the string + first before swaping character pairs. +9. bstrrchr versus no comparable C function. Its not hard to write some C + code to search for a character from the end going backwards. But there + is no way to do this without computing the length of the string with + strlen. + +Practical testing indicates that in general Bstrlib is never signifcantly +slower than the C library for common operations, while very often having a +performance advantage that ranges from significant to massive. Even for +functions like b(n)inchr versus str(c)spn() (where, in theory, there is no +advantage for the Bstrlib architecture) the performance of Bstrlib is vastly +superior to most tested C library implementations. + +Some of Bstrlib's extra functionality also lead to inevitable performance +advantages over typical C solutions. For example, using the blk2tbstr macro, +one can (in O(1) time) generate an internal substring by reference while not +disturbing the original string. If disturbing the original string is not an +option, typically, a comparable char * solution would have to make a copy of +the substring to provide similar functionality. Another example is reverse +character set scanning -- the str(c)spn functions only scan in a forward +direction which can complicate some parsing algorithms. + +Where high performance char * based algorithms are available, Bstrlib can +still leverage them by accessing the ->data field on bstrings. So +realistically Bstrlib can never be significantly slower than any standard +'\0' terminated char * based solutions. + +Performance of the C++ interface: +................................. + +The C++ interface has been designed with an emphasis on abstraction and safety +first. However, since it is substantially a wrapper for the C bstring +functions, for longer strings the performance comments described in the +"Performance of the C interface" section above still apply. Note that the +(CBString *) type can be directly cast to a (bstring) type, and passed as +parameters to the C functions (though a CBString must never be passed to +bdestroy.) + +Probably the most controversial choice is performing full bounds checking on +the [] operator. This decision was made because 1) the fast alternative of +not bounds checking is still available by first casting the CBString to a +(const char *) buffer or to a (struct tagbstring) then derefencing .data and +2) because the lack of bounds checking is seen as one of the main weaknesses +of C/C++ versus other languages. This check being done on every access leads +to individual character extraction being actually slower than other languages +in this one respect (other language's compilers will normally dedicate more +resources on hoisting or removing bounds checking as necessary) but otherwise +bring C++ up to the level of other languages in terms of functionality. + +It is common for other C++ libraries to leverage the abstractions provided by +C++ to use reference counting and "copy on write" policies. While these +techniques can speed up some scenarios, they impose a problem with respect to +thread safety. bstrings and CBStrings can be properly protected with +"per-object" mutexes, meaning that two bstrlib calls can be made and execute +simultaneously, so long as the bstrings and CBstrings are distinct. With a +reference count and alias before copy on write policy, global mutexes are +required that prevent multiple calls to the strings library to execute +simultaneously regardless of whether or not the strings represent the same +string. + +One interesting trade off in CBString is that the default constructor is not +trivial. I.e., it always prepares a ready to use memory buffer. The purpose +is to ensure that there is a uniform internal composition for any functioning +CBString that is compatible with bstrings. It also means that the other +methods in the class are not forced to perform "late initialization" checks. +In the end it means that construction of CBStrings are slower than other +comparable C++ string classes. Initial testing, however, indicates that +CBString outperforms std::string and MFC's CString, for example, in all other +operations. So to work around this weakness it is recommended that CBString +declarations be pushed outside of inner loops. + +Practical testing indicates that with the exception of the caveats given +above (constructors and safe index character manipulations) the C++ API for +Bstrlib generally outperforms popular standard C++ string classes. Amongst +the standard libraries and compilers, the quality of concatenation operations +varies wildly and very little care has gone into search functions. Bstrlib +dominates those performance benchmarks. + +Memory management: +.................. + +The bstring functions which write and modify bstrings will automatically +reallocate the backing memory for the char buffer whenever it is required to +grow. The algorithm for resizing chosen is to snap up to sizes that are a +power of two which are sufficient to hold the intended new size. Memory +reallocation is not performed when the required size of the buffer is +decreased. This behavior can be relied on, and is necessary to make the +behaviour of balloc deterministic. This trades off additional memory usage +for decreasing the frequency for required reallocations: + +1. For any bstring whose size never exceeds n, its buffer is not ever + reallocated more than log_2(n) times for its lifetime. +2. For any bstring whose size never exceeds n, its buffer is never more than + 2*(n+1) in length. (The extra characters beyond 2*n are to allow for the + implicit '\0' which is always added by the bstring modifying functions.) + +Decreasing the buffer size when the string decreases in size would violate 1) +above and in real world case lead to pathological heap thrashing. Similarly, +allocating more tightly than "least power of 2 greater than necessary" would +lead to a violation of 1) and have the same potential for heap thrashing. + +Property 2) needs emphasizing. Although the memory allocated is always a +power of 2, for a bstring that grows linearly in size, its buffer memory also +grows linearly, not exponentially. The reason is that the amount of extra +space increases with each reallocation, which decreases the frequency of +future reallocations. + +Obviously, given that bstring writing functions may reallocate the data +buffer backing the target bstring, one should not attempt to cache the data +buffer address and use it after such bstring functions have been called. +This includes making reference struct tagbstrings which alias to a writable +bstring. + +balloc or bfromcstralloc can be used to preallocate the minimum amount of +space used for a given bstring. This will reduce even further the number of +times the data portion is reallocated. If the length of the string is never +more than one less than the memory length then there will be no further +reallocations. + +Note that invoking the bwriteallow macro may increase the number of reallocs +by one more than necessary for every call to bwriteallow interleaved with any +bstring API which writes to this bstring. + +The library does not use any mechanism for automatic clean up for the C API. +Thus explicit clean up via calls to bdestroy() are required to avoid memory +leaks. + +Constant and static tagbstrings: +................................ + +A struct tagbstring can be write protected from any bstrlib function using +the bwriteprotect macro. A write protected struct tagbstring can then be +reset to being writable via the bwriteallow macro. There is, of course, no +protection from attempts to directly access the bstring members. Modifying a +bstring which is write protected by direct access has undefined behavior. + +static struct tagbstrings can be declared via the bsStatic macro. They are +considered permanently unwritable. Such struct tagbstrings's are declared +such that attempts to write to it are not well defined. Invoking either +bwriteallow or bwriteprotect on static struct tagbstrings has no effect. + +struct tagbstring's initialized via btfromcstr or blk2tbstr are protected by +default but can be made writeable via the bwriteallow macro. If bwriteallow +is called on such struct tagbstring's, it is the programmer's responsibility +to ensure that: + +1) the buffer supplied was allocated from the heap. +2) bdestroy is not called on this tagbstring (unless the header itself has + also been allocated from the heap.) +3) free is called on the buffer to reclaim its memory. + +bwriteallow and bwriteprotect can be invoked on ordinary bstrings (they have +to be dereferenced with the (*) operator to get the levels of indirection +correct) to give them write protection. + +Buffer declaration: +................... + +The memory buffer is actually declared "unsigned char *" instead of "char *". +The reason for this is to trigger compiler warnings whenever uncasted char +buffers are assigned to the data portion of a bstring. This will draw more +diligent programmers into taking a second look at the code where they +have carelessly left off the typically required cast. (Research from +AT&T/Lucent indicates that additional programmer eyeballs is one of the most +effective mechanisms at ferreting out bugs.) + +Function pointers: +.................. + +The bgets, bread and bStream functions use function pointers to obtain +strings from data streams. The function pointer declarations have been +specifically chosen to be compatible with the fgetc and fread functions. +While this may seem to be a convoluted way of implementing fgets and fread +style functionality, it has been specifically designed this way to ensure +that there is no dependency on a single narrowly defined set of device +interfaces, such as just stream I/O. In the embedded world, its quite +possible to have environments where such interfaces may not exist in the +standard C library form. Furthermore, the generalization that this opens up +allows for more sophisticated uses for these functions (performing an fgets +like function on a socket, for example.) By using function pointers, it also +allows such abstract stream interfaces to be created using the bstring library +itself while not creating a circular dependency. + +Use of int's for sizes: +....................... + +This is just a recognition that 16bit platforms with requirements for strings +that are larger than 64K and 32bit+ platforms with requirements for strings +that are larger than 4GB are pretty marginal. The main focus is for 32bit +platforms, and emerging 64bit platforms with reasonable < 4GB string +requirements. Using ints allows for negative values which has meaning +internally to bstrlib. + +Semantic consideration: +....................... + +Certain care needs to be taken when copying and aliasing bstrings. A bstring +is essentially a pointer type which points to a multipart abstract data +structure. Thus usage, and lifetime of bstrings have semantics that follow +these considerations. For example: + + bstring a, b; + struct tagbstring t; + + a = bfromcstr("Hello"); /* Create new bstring and copy "Hello" into it. */ + b = a; /* Alias b to the contents of a. */ + t = *a; /* Create a current instance pseudo-alias of a. */ + bconcat (a, b); /* Double a and b, t is now undefined. */ + bdestroy (a); /* Destroy the contents of both a and b. */ + +Variables of type bstring are really just references that point to real +bstring objects. The equal operator (=) creates aliases, and the asterisk +dereference operator (*) creates a kind of alias to the current instance (which +is generally not useful for any purpose.) Using bstrcpy() is the correct way +of creating duplicate instances. The ampersand operator (&) is useful for +creating aliases to struct tagbstrings (remembering that constructed struct +tagbstrings are not writable by default.) + +CBStrings use complete copy semantics for the equal operator (=), and thus do +not have these sorts of issues. + +Debugging: +.......... + +Bstrings have a simple, exposed definition and construction, and the library +itself is open source. So most debugging is going to be fairly straight- +forward. But the memory for bstrings come from the heap, which can often be +corrupted indirectly, and it might not be obvious what has happened even from +direct examination of the contents in a debugger or a core dump. There are +some tools such as Purify, Insure++ and Electric Fence which can help solve +such problems, however another common approach is to directly instrument the +calls to malloc, realloc, calloc, free, memcpy, memmove and/or other calls +by overriding them with macro definitions. + +Although the user could hack on the Bstrlib sources directly as necessary to +perform such an instrumentation, Bstrlib comes with a built-in mechanism for +doing this. By defining the macro BSTRLIB_MEMORY_DEBUG and providing an +include file named memdbg.h this will force the core Bstrlib modules to +attempt to include this file. In such a file, macros could be defined which +overrides Bstrlib's useage of the C standard library. + +Rather than calling malloc, realloc, free, memcpy or memmove directly, Bstrlib +emits the macros bstr__alloc, bstr__realloc, bstr__free, bstr__memcpy and +bstr__memmove in their place respectively. By default these macros are simply +assigned to be equivalent to their corresponding C standard library function +call. However, if they are given earlier macro definitions (via the back +door include file) they will not be given their default definition. In this +way Bstrlib's interface to the standard library can be changed but without +having to directly redefine or link standard library symbols (both of which +are not strictly ANSI C compliant.) + +An example definition might include: + + #define bstr__alloc(sz) X_malloc ((sz), __LINE__, __FILE__) + +which might help contextualize heap entries in a debugging environment. + +The NULL parameter and sanity checking of bstrings is part of the Bstrlib +API, and thus Bstrlib itself does not present any different modes which would +correspond to "Debug" or "Release" modes. Bstrlib always contains mechanisms +which one might think of as debugging features, but retains the performance +and small memory footprint one would normally associate with release mode +code. + +Integration Microsoft's Visual Studio debugger: +............................................... + +Microsoft's Visual Studio debugger has a capability of customizable mouse +float over data type descriptions. This is accomplished by editting the +AUTOEXP.DAT file to include the following: + + ; new for CBString + tagbstring =slen= mlen= + Bstrlib::CBStringList =count= + +In Visual C++ 6.0 this file is located in the directory: + + C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin + +and in Visual Studio .NET 2003 its located here: + + C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger + +This will improve the ability of debugging with Bstrlib under Visual Studio. + +Security +-------- + +Bstrlib does not come with explicit security features outside of its fairly +comprehensive error detection, coupled with its strict semantic support. +That is to say that certain common security problems, such as buffer overrun, +constant overwrite, arbitrary truncation etc, are far less likely to happen +inadvertently. Where it does help, Bstrlib maximizes its advantage by +providing developers a simple adoption path that lets them leave less secure +string mechanisms behind. The library will not leave developers wanting, so +they will be less likely to add new code using a less secure string library +to add functionality that might be missing from Bstrlib. + +That said there are a number of security ideas not addressed by Bstrlib: + +1. Race condition exploitation (i.e., verifying a string's contents, then +raising the privilege level and execute it as a shell command as two +non-atomic steps) is well beyond the scope of what Bstrlib can provide. It +should be noted that MFC's built-in string mutex actually does not solve this +problem either -- it just removes immediate data corruption as a possible +outcome of such exploit attempts (it can be argued that this is worse, since +it will leave no trace of the exploitation). In general race conditions have +to be dealt with by careful design and implementation; it cannot be assisted +by a string library. + +2. Any kind of access control or security attributes to prevent usage in +dangerous interfaces such as system(). Perl includes a "trust" attribute +which can be endowed upon strings that are intended to be passed to such +dangerous interfaces. However, Perl's solution reflects its own limitations +-- notably that it is not a strongly typed language. In the example code for +Bstrlib, there is a module called taint.cpp. It demonstrates how to write a +simple wrapper class for managing "untainted" or trusted strings using the +type system to prevent questionable mixing of ordinary untrusted strings with +untainted ones then passing them to dangerous interfaces. In this way the +security correctness of the code reduces to auditing the direct usages of +dangerous interfaces or promotions of tainted strings to untainted ones. + +3. Encryption of string contents is way beyond the scope of Bstrlib. +Maintaining encrypted string contents in the futile hopes of thwarting things +like using system-level debuggers to examine sensitive string data is likely +to be a wasted effort (imagine a debugger that runs at a higher level than a +virtual processor where the application runs). For more standard encryption +usages, since the bstring contents are simply binary blocks of data, this +should pose no problem for usage with other standard encryption libraries. + +Compatibility +------------- + +The Better String Library is known to compile and function correctly with the +following compilers: + + - Microsoft Visual C++ + - Watcom C/C++ + - Intel's C/C++ compiler (Windows) + - The GNU C/C++ compiler (cygwin and Linux on PPC64) + - Borland C + - Turbo C + +Setting of configuration options should be unnecessary for these compilers +(unless exceptions are being disabled or STLport has been added to WATCOM +C/C++). Bstrlib has been developed with an emphasis on portability. As such +porting it to other compilers should be straight forward. This package +includes a porting guide (called porting.txt) which explains what issues may +exist for porting Bstrlib to different compilers and environments. + +ANSI issues +----------- + +1. The function pointer types bNgetc and bNread have prototypes which are very +similar to, but not exactly the same as fgetc and fread respectively. +Basically the FILE * parameter is replaced by void *. The purpose of this +was to allow one to create other functions with fgetc and fread like +semantics without being tied to ANSI C's file streaming mechanism. I.e., one +could very easily adapt it to sockets, or simply reading a block of memory, +or procedurally generated strings (for fractal generation, for example.) + +The problem is that invoking the functions (bNgetc)fgetc and (bNread)fread is +not technically legal in ANSI C. The reason being that the compiler is only +able to coerce the function pointers themselves into the target type, however +are unable to perform any cast (implicit or otherwise) on the parameters +passed once invoked. I.e., if internally void * and FILE * need some kind of +mechanical coercion, the compiler will not properly perform this conversion +and thus lead to undefined behavior. + +Apparently a platform from Data General called "Eclipse" and another from +Tandem called "NonStop" have a different representation for pointers to bytes +and pointers to words, for example, where coercion via casting is necessary. +(Actual confirmation of the existence of such machines is hard to come by, so +it is prudent to be skeptical about this information.) However, this is not +an issue for any known contemporary platforms. One may conclude that such +platforms are effectively apocryphal even if they do exist. + +To correctly work around this problem to the satisfaction of the ANSI +limitations, one needs to create wrapper functions for fgets and/or +fread with the prototypes of bNgetc and/or bNread respectively which performs +no other action other than to explicitely cast the void * parameter to a +FILE *, and simply pass the remaining parameters straight to the function +pointer call. + +The wrappers themselves are trivial: + + size_t freadWrap (void * buff, size_t esz, size_t eqty, void * parm) { + return fread (buff, esz, eqty, (FILE *) parm); + } + + int fgetcWrap (void * parm) { + return fgetc ((FILE *) parm); + } + +These have not been supplied in bstrlib or bstraux to prevent unnecessary +linking with file I/O functions. + +2. vsnprintf is not available on all compilers. Because of this, the bformat +and bformata functions (and format and formata methods) are not guaranteed to +work properly. For those compilers that don't have vsnprintf, the +BSTRLIB_NOVSNP macro should be set before compiling bstrlib, and the format +functions/method will be disabled. + +The more recent ANSI C standards have specified the required inclusion of a +vsnprintf function. + +3. The bstrlib function names are not unique in the first 6 characters. This +is only an issue for older C compiler environments which do not store more +than 6 characters for function names. + +4. The bsafe module defines macros and function names which are part of the +C library. This simply overrides the definition as expected on all platforms +tested, however it is not sanctioned by the ANSI standard. This module is +clearly optional and should be omitted on platforms which disallow its +undefined semantics. + +In practice the real issue is that some compilers in some modes of operation +can/will inline these standard library functions on a module by module basis +as they appear in each. The linker will thus have no opportunity to override +the implementation of these functions for those cases. This can lead to +inconsistent behaviour of the bsafe module on different platforms and +compilers. + +=============================================================================== + +Comparison with Microsoft's CString class +----------------------------------------- + +Although developed independently, CBStrings have very similar functionality to +Microsoft's CString class. However, the bstring library has significant +advantages over CString: + +1. Bstrlib is a C-library as well as a C++ library (using the C++ wrapper). + + - Thus it is compatible with more programming environments and + available to a wider population of programmers. + +2. The internal structure of a bstring is considered exposed. + + - A single contiguous block of data can be cut into read-only pieces by + simply creating headers, without allocating additional memory to create + reference copies of each of these sub-strings. + - In this way, using bstrings in a totally abstracted way becomes a choice + rather than an imposition. Further this choice can be made differently + at different layers of applications that use it. + +3. Static declaration support precludes the need for constructor + invocation. + + - Allows for static declarations of constant strings that has no + additional constructor overhead. + +4. Bstrlib is not attached to another library. + + - Bstrlib is designed to be easily plugged into any other library + collection, without dependencies on other libraries or paradigms (such + as "MFC".) + +The bstring library also comes with a few additional functions that are not +available in the CString class: + + - bsetstr + - bsplit + - bread + - breplace (this is different from CString::Replace()) + - Writable indexed characters (for example a[i]='x') + +Interestingly, although Microsoft did implement mid$(), left$() and right$() +functional analogues (these are functions from GWBASIC) they seem to have +forgotten that mid$() could be also used to write into the middle of a string. +This functionality exists in Bstrlib with the bsetstr() and breplace() +functions. + +Among the disadvantages of Bstrlib is that there is no special support for +localization or wide characters. Such things are considered beyond the scope +of what bstrings are trying to deliver. CString essentially supports the +older UCS-2 version of Unicode via widechar_t as an application-wide compile +time switch. + +CString's also use built-in mechanisms for ensuring thread safety under all +situations. While this makes writing thread safe code that much easier, this +built-in safety feature has a price -- the inner loops of each CString method +runs in its own critical section (grabbing and releasing a light weight mutex +on every operation.) The usual way to decrease the impact of a critical +section performance penalty is to amortize more operations per critical +section. But since the implementation of CStrings is fixed as a one critical +section per-operation cost, there is no way to leverage this common +performance enhancing idea. + +The search facilities in Bstrlib are comparable to those in MFC's CString +class, though it is missing locale specific collation. But because Bstrlib +is interoperable with C's char buffers, it will allow programmers to write +their own string searching mechanism (such as Boyer-Moore), or be able to +choose from a variety of available existing string searching libraries (such +as those for regular expressions) without difficulty. + +Microsoft used a very non-ANSI conforming trick in its implementation to +allow printf() to use the "%s" specifier to output a CString correctly. This +can be convenient, but it is inherently not portable. CBString requires an +explicit cast, while bstring requires the data member to be dereferenced. +Microsoft's own documentation recommends casting, instead of relying on this +feature. + +Comparison with C++'s std::string +--------------------------------- + +This is the C++ language's standard STL based string class. + +1. There is no C implementation. +2. The [] operator is not bounds checked. +3. Missing a lot of useful functions like printf-like formatting. +4. Some sub-standard std::string implementations (SGI) are necessarily unsafe + to use with multithreading. +5. Limited by STL's std::iostream which in turn is limited by ifstream which + can only take input from files. (Compare to CBStream's API which can take + abstracted input.) +6. Extremely uneven performance across implementations. + +Comparison with ISO C TR 24731 proposal +--------------------------------------- + +Following the ISO C99 standard, Microsoft has proposed a group of C library +extensions which are supposedly "safer and more secure". This proposal is +expected to be adopted by the ISO C standard which follows C99. + +The proposal reveals itself to be very similar to Microsoft's "StrSafe" +library. The functions are basically the same as other standard C library +string functions except that destination parameters are paired with an +additional length parameter of type rsize_t. rsize_t is the same as size_t, +however, the range is checked to make sure its between 1 and RSIZE_MAX. Like +Bstrlib, the functions perform a "parameter check". Unlike Bstrlib, when a +parameter check fails, rather than simply outputing accumulatable error +statuses, they call a user settable global error function handler, and upon +return of control performs no (additional) detrimental action. The proposal +covers basic string functions as well as a few non-reenterable functions +(asctime, ctime, and strtok). + +1. Still based solely on char * buffers (and therefore strlen() and strcat() + is still O(n), and there are no faster streq() comparison functions.) +2. No growable string semantics. +3. Requires manual buffer length synchronization in the source code. +4. No attempt to enhance functionality of the C library. +5. Introduces a new error scenario (strings exceeding RSIZE_MAX length). + +The hope is that by exposing the buffer length requirements there will be +fewer buffer overrun errors. However, the error modes are really just +transformed, rather than removed. The real problem of buffer overflows is +that they all happen as a result of erroneous programming. So forcing +programmers to manually deal with buffer limits, will make them more aware of +the problem but doesn't remove the possibility of erroneous programming. So +a programmer that erroneously mixes up the rsize_t parameters is no better off +from a programmer that introduces potential buffer overflows through other +more typical lapses. So at best this may reduce the rate of erroneous +programming, rather than making any attempt at removing failure modes. + +The error handler can discriminate between types of failures, but does not +take into account any callsite context. So the problem is that the error is +going to be manifest in a piece of code, but there is no pointer to that +code. It would seem that passing in the call site __FILE__, __LINE__ as +parameters would be very useful, but the API clearly doesn't support such a +thing (it would increase code bloat even more than the extra length +parameter does, and would require macro tricks to implement). + +The Bstrlib C API takes the position that error handling needs to be done at +the callsite, and just tries to make it as painless as possible. Furthermore, +error modes are removed by supporting auto-growing strings and aliasing. For +capturing errors in more central code fragments, Bstrlib's C++ API uses +exception handling extensively, which is superior to the leaf-only error +handler approach. + +Comparison with Managed String Library CERT proposal +---------------------------------------------------- + +The main webpage for the managed string library: +http://www.cert.org/secure-coding/managedstring.html + +Robert Seacord at CERT has proposed a C string library that he calls the +"Managed String Library" for C. Like Bstrlib, it introduces a new type +which is called a managed string. The structure of a managed string +(string_m) is like a struct tagbstring but missing the length field. This +internal structure is considered opaque. The length is, like the C standard +library, always computed on the fly by searching for a terminating NUL on +every operation that requires it. So it suffers from every performance +problem that the C standard library suffers from. Interoperating with C +string APIs (like printf, fopen, or anything else that takes a string +parameter) requires copying to additionally allocating buffers that have to +be manually freed -- this makes this library probably slower and more +cumbersome than any other string library in existence. + +The library gives a fully populated error status as the return value of every +string function. The hope is to be able to diagnose all problems +specifically from the return code alone. Comparing this to Bstrlib, which +aways returns one consistent error message, might make it seem that Bstrlib +would be harder to debug; but this is not true. With Bstrlib, if an error +occurs there is always enough information from just knowing there was an error +and examining the parameters to deduce exactly what kind of error has +happened. The managed string library thus gives up nested function calls +while achieving little benefit, while Bstrlib does not. + +One interesting feature that "managed strings" has is the idea of data +sanitization via character set whitelisting. That is to say, a globally +definable filter that makes any attempt to put invalid characters into strings +lead to an error and not modify the string. The author gives the following +example: + + // create valid char set + if (retValue = strcreate_m(&str1, "abc") ) { + fprintf( + stderr, + "Error %d from strcreate_m.\n", + retValue + ); + } + if (retValue = setcharset(str1)) { + fprintf( + stderr, + "Error %d from setcharset().\n", + retValue + ); + } + if (retValue = strcreate_m(&str1, "aabbccabc")) { + fprintf( + stderr, + "Error %d from strcreate_m.\n", + retValue + ); + } + // create string with invalid char set + if (retValue = strcreate_m(&str1, "abbccdabc")) { + fprintf( + stderr, + "Error %d from strcreate_m.\n", + retValue + ); + } + +Which we can compare with a more Bstrlib way of doing things: + + bstring bCreateWithFilter (const char * cstr, const_bstring filter) { + bstring b = bfromcstr (cstr); + if (BSTR_ERR != bninchr (b, filter) && NULL != b) { + fprintf (stderr, "Filter violation.\n"); + bdestroy (b); + b = NULL; + } + return b; + } + + struct tagbstring charFilter = bsStatic ("abc"); + bstring str1 = bCreateWithFilter ("aabbccabc", &charFilter); + bstring str2 = bCreateWithFilter ("aabbccdabc", &charFilter); + +The first thing we should notice is that with the Bstrlib approach you can +have different filters for different strings if necessary. Furthermore, +selecting a charset filter in the Managed String Library is uni-contextual. +That is to say, there can only be one such filter active for the entire +program, which means its usage is not well defined for intermediate library +usage (a library that uses it will interfere with user code that uses it, and +vice versa.) It is also likely to be poorly defined in multi-threading +environments. + +There is also a question as to whether the data sanitization filter is checked +on every operation, or just on creation operations. Since the charset can be +set arbitrarily at run time, it might be set *after* some managed strings have +been created. This would seem to imply that all functions should run this +additional check every time if there is an attempt to enforce this. This +would make things tremendously slow. On the other hand, if it is assumed that +only creates and other operations that take char *'s as input need be checked +because the charset was only supposed to be called once at and before any +other managed string was created, then one can see that its easy to cover +Bstrlib with equivalent functionality via a few wrapper calls such as the +example given above. + +And finally we have to question the value of sanitation in the first place. +For example, for httpd servers, there is generally a requirement that the +URLs parsed have some form that avoids undesirable translation to local file +system filenames or resources. The problem is that the way URLs can be +encoded, it must be completely parsed and translated to know if it is using +certain invalid character combinations. That is to say, merely filtering +each character one at a time is not necessarily the right way to ensure that +a string has safe contents. + +In the article that describes this proposal, it is claimed that it fairly +closely approximates the existing C API semantics. On this point we should +compare this "closeness" with Bstrlib: + + Bstrlib Managed String Library + ------- ---------------------- + +Pointer arithmetic Segment arithmetic N/A + +Use in C Std lib ->data, or bdata{e} getstr_m(x,*) ... free(x) + +String literals bsStatic, bsStaticBlk strcreate_m() + +Transparency Complete None + +Its pretty clear that the semantic mapping from C strings to Bstrlib is fairly +straightforward, and that in general semantic capabilities are the same or +superior in Bstrlib. On the other hand the Managed String Library is either +missing semantics or changes things fairly significantly. + +Comparison with Annexia's c2lib library +--------------------------------------- + +This library is available at: +http://www.annexia.org/freeware/c2lib + +1. Still based solely on char * buffers (and therefore strlen() and strcat() + is still O(n), and there are no faster streq() comparison functions.) + Their suggestion that alternatives which wrap the string data type (such as + bstring does) imposes a difficulty in interoperating with the C langauge's + ordinary C string library is not founded. +2. Introduction of memory (and vector?) abstractions imposes a learning + curve, and some kind of memory usage policy that is outside of the strings + themselves (and therefore must be maintained by the developer.) +3. The API is massive, and filled with all sorts of trivial (pjoin) and + controvertial (pmatch -- regular expression are not sufficiently + standardized, and there is a very large difference in performance between + compiled and non-compiled, REs) functions. Bstrlib takes a decidely + minimal approach -- none of the functionality in c2lib is difficult or + challenging to implement on top of Bstrlib (except the regex stuff, which + is going to be difficult, and controvertial no matter what.) +4. Understanding why c2lib is the way it is pretty much requires a working + knowledge of Perl. bstrlib requires only knowledge of the C string library + while providing just a very select few worthwhile extras. +5. It is attached to a lot of cruft like a matrix math library (that doesn't + include any functions for getting the determinant, eigenvectors, + eigenvalues, the matrix inverse, test for singularity, test for + orthogonality, a grahm schmit orthogonlization, LU decomposition ... I + mean why bother?) + +Convincing a development house to use c2lib is likely quite difficult. It +introduces too much, while not being part of any kind of standards body. The +code must therefore be trusted, or maintained by those that use it. While +bstring offers nothing more on this front, since its so much smaller, covers +far less in terms of scope, and will typically improve string performance, +the barrier to usage should be much smaller. + +Comparison with stralloc/qmail +------------------------------ + +More information about this library can be found here: +http://www.canonical.org/~kragen/stralloc.html or here: +http://cr.yp.to/lib/stralloc.html + +1. Library is very very minimal. A little too minimal. +2. Untargetted source parameters are not declared const. +3. Slightly different expected emphasis (like _cats function which takes an + ordinary C string char buffer as a parameter.) Its clear that the + remainder of the C string library is still required to perform more + useful string operations. + +The struct declaration for their string header is essentially the same as that +for bstring. But its clear that this was a quickly written hack whose goals +are clearly a subset of what Bstrlib supplies. For anyone who is served by +stralloc, Bstrlib is complete substitute that just adds more functionality. + +stralloc actually uses the interesting policy that a NULL data pointer +indicates an empty string. In this way, non-static empty strings can be +declared without construction. This advantage is minimal, since static empty +bstrings can be declared inline without construction, and if the string needs +to be written to it should be constructed from an empty string (or its first +initializer) in any event. + +wxString class +-------------- + +This is the string class used in the wxWindows project. A description of +wxString can be found here: +http://www.wxwindows.org/manuals/2.4.2/wx368.htm#wxstring + +This C++ library is similar to CBString. However, it is littered with +trivial functions (IsAscii, UpperCase, RemoveLast etc.) + +1. There is no C implementation. +2. The memory management strategy is to allocate a bounded fixed amount of + additional space on each resize, meaning that it does not have the + log_2(n) property that Bstrlib has (it will thrash very easily, cause + massive fragmentation in common heap implementations, and can easily be a + common source of performance problems). +3. The library uses a "copy on write" strategy, meaning that it has to deal + with multithreading problems. + +Vstr +---- + +This is a highly orthogonal C string library with an emphasis on +networking/realtime programming. It can be found here: +http://www.and.org/vstr/ + +1. The convoluted internal structure does not contain a '\0' char * compatible + buffer, so interoperability with the C library a non-starter. +2. The API and implementation is very large (owing to its orthogonality) and + can lead to difficulty in understanding its exact functionality. +3. An obvious dependency on gnu tools (confusing make configure step) +4. Uses a reference counting system, meaning that it is not likely to be + thread safe. + +The implementation has an extreme emphasis on performance for nontrivial +actions (adds, inserts and deletes are all constant or roughly O(#operations) +time) following the "zero copy" principle. This trades off performance of +trivial functions (character access, char buffer access/coersion, alias +detection) which becomes significantly slower, as well as incremental +accumulative costs for its searching/parsing functions. Whether or not Vstr +wins any particular performance benchmark will depend a lot on the benchmark, +but it should handily win on some, while losing dreadfully on others. + +The learning curve for Vstr is very steep, and it doesn't come with any +obvious way to build for Windows or other platforms without gnu tools. At +least one mechanism (the iterator) introduces a new undefined scenario +(writing to a Vstr while iterating through it.) Vstr has a very large +footprint, and is very ambitious in its total functionality. Vstr has no C++ +API. + +Vstr usage requires context initialization via vstr_init() which must be run +in a thread-local context. Given the totally reference based architecture +this means that sharing Vstrings across threads is not well defined, or at +least not safe from race conditions. This API is clearly geared to the older +standard of fork() style multitasking in UNIX, and is not safely transportable +to modern shared memory multithreading available in Linux and Windows. There +is no portable external solution making the library thread safe (since it +requires a mutex around each Vstr context -- not each string.) + +In the documentation for this library, a big deal is made of its self hosted +s(n)printf-like function. This is an issue for older compilers that don't +include vsnprintf(), but also an issue because Vstr has a slow conversion to +'\0' terminated char * mechanism. That is to say, using "%s" to format data +that originates from Vstr would be slow without some sort of native function +to do so. Bstrlib sidesteps the issue by relying on what snprintf-like +functionality does exist and having a high performance conversion to a char * +compatible string so that "%s" can be used directly. + +Str Library +----------- + +This is a fairly extensive string library, that includes full unicode support +and targetted at the goal of out performing MFC and STL. The architecture, +similarly to MFC's CStrings, is a copy on write reference counting mechanism. + +http://www.utilitycode.com/str/default.aspx + +1. Commercial. +2. C++ only. + +This library, like Vstr, uses a ref counting system. There is only so deeply +I can analyze it, since I don't have a license for it. However, performance +improvements over MFC's and STL, doesn't seem like a sufficient reason to +move your source base to it. For example, in the future, Microsoft may +improve the performance CString. + +It should be pointed out that performance testing of Bstrlib has indicated +that its relative performance advantage versus MFC's CString and STL's +std::string is at least as high as that for the Str library. + +libmib astrings +--------------- + +A handful of functional extensions to the C library that add dynamic string +functionality. +http://www.mibsoftware.com/libmib/astring/ + +This package basically references strings through char ** pointers and assumes +they are pointing to the top of an allocated heap entry (or NULL, in which +case memory will be newly allocated from the heap.) So its still up to user +to mix and match the older C string functions with these functions whenever +pointer arithmetic is used (i.e., there is no leveraging of the type system +to assert semantic differences between references and base strings as Bstrlib +does since no new types are introduced.) Unlike Bstrlib, exact string length +meta data is not stored, thus requiring a strlen() call on *every* string +writing operation. The library is very small, covering only a handful of C's +functions. + +While this is better than nothing, it is clearly slower than even the +standard C library, less safe and less functional than Bstrlib. + +To explain the advantage of using libmib, their website shows an example of +how dangerous C code: + + char buf[256]; + char *pszExtraPath = ";/usr/local/bin"; + + strcpy(buf,getenv("PATH")); /* oops! could overrun! */ + strcat(buf,pszExtraPath); /* Could overrun as well! */ + + printf("Checking...%s\n",buf); /* Some printfs overrun too! */ + +is avoided using libmib: + + char *pasz = 0; /* Must initialize to 0 */ + char *paszOut = 0; + char *pszExtraPath = ";/usr/local/bin"; + + if (!astrcpy(&pasz,getenv("PATH"))) /* malloc error */ exit(-1); + if (!astrcat(&pasz,pszExtraPath)) /* malloc error */ exit(-1); + + /* Finally, a "limitless" printf! we can use */ + asprintf(&paszOut,"Checking...%s\n",pasz);fputs(paszOut,stdout); + + astrfree(&pasz); /* Can use free(pasz) also. */ + astrfree(&paszOut); + +However, compare this to Bstrlib: + + bstring b, out; + + bcatcstr (b = bfromcstr (getenv ("PATH")), ";/usr/local/bin"); + out = bformat ("Checking...%s\n", bdatae (b, "")); + /* if (out && b) */ fputs (bdatae (out, ""), stdout); + bdestroy (b); + bdestroy (out); + +Besides being shorter, we can see that error handling can be deferred right +to the very end. Also, unlike the above two versions, if getenv() returns +with NULL, the Bstrlib version will not exhibit undefined behavior. +Initialization starts with the relevant content rather than an extra +autoinitialization step. + +libclc +------ + +An attempt to add to the standard C library with a number of common useful +functions, including additional string functions. +http://libclc.sourceforge.net/ + +1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass + the responsibility to guard against aliasing to the programmer. +2. Adds no safety or memory management whatsoever. +3. Most of the supplied string functions are completely trivial. + +The goals of libclc and Bstrlib are clearly quite different. + +fireString +---------- + +http://firestuff.org/ + +1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass + the responsibility to guard against aliasing to the programmer. +2. Mixes char * and length wrapped buffers (estr) functions, doubling the API + size, with safety limited to only half of the functions. + +Firestring was originally just a wrapper of char * functionality with extra +length parameters. However, it has been augmented with the inclusion of the +estr type which has similar functionality to stralloc. But firestring does +not nearly cover the functional scope of Bstrlib. + +Safe C String Library +--------------------- + +A library written for the purpose of increasing safety and power to C's string +handling capabilities. +http://www.zork.org/safestr/safestr.html + +1. While the safestr_* functions are safe in of themselves, interoperating + with char * string has dangerous unsafe modes of operation. +2. The architecture of safestr's causes the base pointer to change. Thus, + its not practical/safe to store a safestr in multiple locations if any + single instance can be manipulated. +3. Dependent on an additional error handling library. +4. Uses reference counting, meaning that it is either not thread safe or + slow and not portable. + +I think the idea of reallocating (and hence potentially changing) the base +pointer is a serious design flaw that is fatal to this architecture. True +safety is obtained by having automatic handling of all common scenarios +without creating implicit constraints on the user. + +Because of its automatic temporary clean up system, it cannot use "const" +semantics on input arguments. Interesting anomolies such as: + + safestr_t s, t; + s = safestr_replace (t = SAFESTR_TEMP ("This is a test"), + SAFESTR_TEMP (" "), SAFESTR_TEMP (".")); + /* t is now undefined. */ + +are possible. If one defines a function which takes a safestr_t as a +parameter, then the function would not know whether or not the safestr_t is +defined after it passes it to a safestr library function. The author +recommended method for working around this problem is to examine the +attributes of the safestr_t within the function which is to modify any of +its parameters and play games with its reference count. I think, therefore, +that the whole SAFESTR_TEMP idea is also fatally broken. + +The library implements immutability, optional non-resizability, and a "trust" +flag. This trust flag is interesting, and suggests that applying any +arbitrary sequence of safestr_* function calls on any set of trusted strings +will result in a trusted string. It seems to me, however, that if one wanted +to implement a trusted string semantic, one might do so by actually creating +a different *type* and only implement the subset of string functions that are +deemed safe (i.e., user input would be excluded, for example.) This, in +essence, would allow the compiler to enforce trust propogation at compile +time rather than run time. Non-resizability is also interesting, however, +it seems marginal (i.e., to want a string that cannot be resized, yet can be +modified and yet where a fixed sized buffer is undesirable.) + +=============================================================================== + +Examples +-------- + + Dumping a line numbered file: + + FILE * fp; + int i, ret; + struct bstrList * lines; + struct tagbstring prefix = bsStatic ("-> "); + + if (NULL != (fp = fopen ("bstrlib.txt", "rb"))) { + bstring b = bread ((bNread) fread, fp); + fclose (fp); + if (NULL != (lines = bsplit (b, '\n'))) { + for (i=0; i < lines->qty; i++) { + binsert (lines->entry[i], 0, &prefix, '?'); + printf ("%04d: %s\n", i, bdatae (lines->entry[i], "NULL")); + } + bstrListDestroy (lines); + } + bdestroy (b); + } + +For numerous other examples, see bstraux.c, bstraux.h and the example archive. + +=============================================================================== + +License +------- + +The Better String Library is available under either the 3 clause BSD license +(see the accompanying license.txt) or the Gnu Public License version 2 (see +the accompanying gpl.txt) at the option of the user. + +=============================================================================== + +Acknowledgements +---------------- + +The following individuals have made significant contributions to the design +and testing of the Better String Library: + +Bjorn Augestad +Clint Olsen +Darryl Bleau +Fabian Cenedese +Graham Wideman +Ignacio Burgueno +International Business Machines Corporation +Ira Mica +John Kortink +Manuel Woelker +Marcel van Kervinck +Michael Hsieh +Richard A. Smith +Simon Ekstrom +Wayne Scott + +=============================================================================== diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/gpl.txt b/build/tools/HLSLcc/May_2014/src/cbstring/gpl.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/gpl.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/license.txt b/build/tools/HLSLcc/May_2014/src/cbstring/license.txt new file mode 100644 index 0000000..cf78a98 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/license.txt @@ -0,0 +1,29 @@ +Copyright (c) 2002-2008 Paul Hsieh +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of bstrlib nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/porting.txt b/build/tools/HLSLcc/May_2014/src/cbstring/porting.txt new file mode 100644 index 0000000..11d8d13 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/porting.txt @@ -0,0 +1,172 @@ +Better String library Porting Guide +----------------------------------- + +by Paul Hsieh + +The bstring library is an attempt to provide improved string processing +functionality to the C and C++ language. At the heart of the bstring library +is the management of "bstring"s which are a significant improvement over '\0' +terminated char buffers. See the accompanying documenation file bstrlib.txt +for more information. + +=============================================================================== + +Identifying the Compiler +------------------------ + +Bstrlib has been tested on the following compilers: + + Microsoft Visual C++ + Watcom C/C++ (32 bit flat) + Intel's C/C++ compiler (on Windows) + The GNU C/C++ compiler (on Windows/Linux on x86 and PPC64) + Borland C++ + Turbo C + +There are slight differences in these compilers which requires slight +differences in the implementation of Bstrlib. These are accomodated in the +same sources using #ifdef/#if defined() on compiler specific macros. To +port Bstrlib to a new compiler not listed above, it is recommended that the +same strategy be followed. If you are unaware of the compiler specific +identifying preprocessor macro for your compiler you might find it here: + +http://predef.sourceforge.net/precomp.html + +Note that Intel C/C++ on Windows sets the Microsoft identifier: _MSC_VER. + +16-bit vs. 32-bit vs. 64-bit Systems +------------------------------------ + +Bstrlib has been architected to deal with strings of length between 0 and +INT_MAX (inclusive). Since the values of int are never higher than size_t +there will be no issue here. Note that on most 64-bit systems int is 32-bit. + +Dependency on The C-Library +--------------------------- + +Bstrlib uses the functions memcpy, memmove, malloc, realloc, free and +vsnprintf. Many free standing C compiler implementations that have a mode in +which the C library is not available will typically not include these +functions which will make porting Bstrlib to it onerous. Bstrlib is not +designed for such bare bones compiler environments. This usually includes +compilers that target ROM environments. + +Porting Issues +-------------- + +Bstrlib has been written completely in ANSI/ISO C and ISO C++, however, there +are still a few porting issues. These are described below. + +1. The vsnprintf () function. + +Unfortunately, the earlier ANSI/ISO C standards did not include this function. +If the compiler of interest does not support this function then the +BSTRLIB_NOVSNP should be defined via something like: + + #if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP) + # if defined (__TURBOC__) || defined (__COMPILERVENDORSPECIFICMACRO__) + # define BSTRLIB_NOVSNP + # endif + #endif + +which appears at the top of bstrlib.h. Note that the bformat(a) functions +will not be declared or implemented if the BSTRLIB_NOVSNP macro is set. If +the compiler has renamed vsnprintf() to some other named function, then +search for the definition of the exvsnprintf macro in bstrlib.c file and be +sure its defined appropriately: + + #if defined (__COMPILERVENDORSPECIFICMACRO__) + # define exvsnprintf(r,b,n,f,a) {r=__compiler_specific_vsnprintf(b,n,f,a);} + #else + # define exvsnprintf(r,b,n,f,a) {r=vsnprintf(b,n,f,a);} + #endif + +Take notice of the return value being captured in the variable r. It is +assumed that r exceeds n if and only if the underlying vsnprintf function has +determined what the true maximal output length would be for output if the +buffer were large enough to hold it. Non-modern implementations must output a +lesser number (the macro can and should be modified to ensure this). + +2. Weak C++ compiler. + +C++ is a much more complicated language to implement than C. This has lead +to varying quality of compiler implementations. The weaknesses isolated in +the initial ports are inclusion of the Standard Template Library, +std::iostream and exception handling. By default it is assumed that the C++ +compiler supports all of these things correctly. If your compiler does not +support one or more of these define the corresponding macro: + + BSTRLIB_CANNOT_USE_STL + BSTRLIB_CANNOT_USE_IOSTREAM + BSTRLIB_DOESNT_THROW_EXCEPTIONS + +The compiler specific detected macro should be defined at the top of +bstrwrap.h in the Configuration defines section. Note that these disabling +macros can be overrided with the associated enabling macro if a subsequent +version of the compiler gains support. (For example, its possible to rig +up STLport to provide STL support for WATCOM C/C++, so -DBSTRLIB_CAN_USE_STL +can be passed in as a compiler option.) + +3. The bsafe module, and reserved words. + +The bsafe module is in gross violation of the ANSI/ISO C standard in the +sense that it redefines what could be implemented as reserved words on a +given compiler. The typical problem is that a compiler may inline some of the +functions and thus not be properly overridden by the definitions in the bsafe +module. It is also possible that a compiler may prohibit the redefinitions in +the bsafe module. Compiler specific action will be required to deal with +these situations. + +Platform Specific Files +----------------------- + +The makefiles for the examples are basically setup of for particular +environments for each platform. In general these makefiles are not portable +and should be constructed as necessary from scratch for each platform. + +Testing a port +-------------- + +To test that a port compiles correctly do the following: + +1. Build a sample project that includes the bstrlib, bstraux, bstrwrap, and + bsafe modules. +2. Compile bstest against the bstrlib module. +3. Run bstest and ensure that 0 errors are reported. +4. Compile test against the bstrlib and bstrwrap modules. +5. Run test and ensure that 0 errors are reported. +6. Compile each of the examples (except for the "re" example, which may be + complicated and is not a real test of bstrlib and except for the mfcbench + example which is Windows specific.) +7. Run each of the examples. + +The builds must have 0 errors, and should have the absolute minimum number of +warnings (in most cases can be reduced to 0.) The result of execution should +be essentially identical on each platform. + +Performance +----------- + +Different CPU and compilers have different capabilities in terms of +performance. It is possible for Bstrlib to assume performance +characteristics that a platform doesn't have (since it was primarily +developed on just one platform). The goal of Bstrlib is to provide very good +performance on all platforms regardless of this but without resorting to +extreme measures (such as using assembly language, or non-portable intrinsics +or library extensions.) + +There are two performance benchmarks that can be found in the example/ +directory. They are: cbench.c and cppbench.cpp. These are variations and +expansions of a benchmark for another string library. They don't cover all +string functionality, but do include the most basic functions which will be +common in most string manipulation kernels. + +............................................................................... + +Feedback +-------- + +In all cases, you may email issues found to the primary author of Bstrlib at +the email address: websnarf@users.sourceforge.net + +=============================================================================== diff --git a/build/tools/HLSLcc/May_2014/src/cbstring/security.txt b/build/tools/HLSLcc/May_2014/src/cbstring/security.txt new file mode 100644 index 0000000..9761409 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/cbstring/security.txt @@ -0,0 +1,221 @@ +Better String library Security Statement +---------------------------------------- + +by Paul Hsieh + +=============================================================================== + +Introduction +------------ + +The Better String library (hereafter referred to as Bstrlib) is an attempt to +provide improved string processing functionality to the C and C++ languages. +At the heart of the Bstrlib is the management of "bstring"s which are a +significant improvement over '\0' terminated char buffers. See the +accompanying documenation file bstrlib.txt for more information. + +DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Like any software, there is always a possibility of failure due to a flawed +implementation. Nevertheless a good faith effort has been made to minimize +such flaws in Bstrlib. Also, use of Bstrlib by itself will not make an +application secure or free from implementation failures. However, it is the +author's conviction that use of Bstrlib can greatly facilitate the creation +of software meeting the highest possible standards of security. + +Part of the reason why this document has been created, is for the purpose of +security auditing, or the creation of further "Statements on Security" for +software that is created that uses Bstrlib. An auditor may check the claims +below against Bstrlib, and use this as a basis for analysis of software which +uses Bstrlib. + +=============================================================================== + +Statement on Security +--------------------- + +This is a document intended to give consumers of the Better String Library +who are interested in security an idea of where the Better String Library +stands on various security issues. Any deviation observed in the actual +library itself from the descriptions below should be considered an +implementation error, not a design flaw. + +This statement is not an analytical proof of correctness or an outline of one +but rather an assertion similar to a scientific claim or hypothesis. By use, +testing and open independent examination (otherwise known as scientific +falsifiability), the credibility of the claims made below can rise to the +level of an established theory. + +Common security issues: +....................... + +1. Buffer Overflows + +The Bstrlib API allows the programmer a way to deal with strings without +having to deal with the buffers containing them. Ordinary usage of the +Bstrlib API itself makes buffer overflows impossible. + +Furthermore, the Bstrlib API has a superset of basic string functionality as +compared to the C library's char * functions, C++'s std::string class and +Microsoft's MFC based CString class. It also has abstracted mechanisms for +dealing with IO. This is important as it gives developers a way of migrating +all their code from a functionality point of view. + +2. Memory size overflow/wrap around attack + +Bstrlib is, by design, impervious to memory size overflow attacks. The +reason is it is resiliant to length overflows is that bstring lengths are +bounded above by INT_MAX, instead of ~(size_t)0. So length addition +overflows cause a wrap around of the integer value making them negative +causing balloc() to fail before an erroneous operation can occurr. Attempted +conversions of char * strings which may have lengths greater than INT_MAX are +detected and the conversion is aborted. + +It is unknown if this property holds on machines that don't represent +integers as 2s complement. It is recommended that Bstrlib be carefully +auditted by anyone using a system which is not 2s complement based. + +3. Constant string protection + +Bstrlib implements runtime enforced constant and read-only string semantics. +I.e., bstrings which are declared as constant via the bsStatic() macro cannot +be modified or deallocated directly through the Bstrlib API, and this cannot +be subverted by casting or other type coercion. This is independent of the +use of the const_bstring data type. + +The Bstrlib C API uses the type const_bstring to specify bstring parameters +whose contents do not change. Although the C language cannot enforce this, +this is nevertheless guaranteed by the implementation of the Bstrlib library +of C functions. The C++ API enforces the const attribute on CBString types +correctly. + +4. Aliased bstring support + +Bstrlib detects and supports aliased parameter management throughout the API. +The kind of aliasing that is allowed is the one where pointers of the same +basic type may be pointing to overlapping objects (this is the assumption the +ANSI C99 specification makes.) Each function behaves as if all read-only +parameters were copied to temporaries which are used in their stead before +the function is enacted (it rarely actually does this). No function in the +Bstrlib uses the "restrict" parameter attribute from the ANSI C99 +specification. + +5. Information leaking + +In bstraux.h, using the semantically equivalent macros bSecureDestroy() and +bSecureWriteProtect() in place of bdestroy() and bwriteprotect() respectively +will ensure that stale data does not linger in the heap's free space after +strings have been released back to memory. Created bstrings or CBStrings +are not linked to anything external to themselves, and thus cannot expose +deterministic data leaking. If a bstring is resized, the preimage may exist +as a copy that is released to the heap. Thus for sensitive data, the bstring +should be sufficiently presized before manipulated so that it is not resized. +bSecureInput() has been supplied in bstraux.c, which can be used to obtain +input securely without any risk of leaving any part of the input image in the +heap except for the allocated bstring that is returned. + +6. Memory leaking + +Bstrlib can be built using memdbg.h enabled via the BSTRLIB_MEMORY_DEBUG +macro. User generated definitions for malloc, realloc and free can then be +supplied which can implement special strategies for memory corruption +detection or memory leaking. Otherwise, bstrlib does not do anything out of +the ordinary to attempt to deal with the standard problem of memory leaking +(i.e., losing references to allocated memory) when programming in the C and +C++ languages. However, it does not compound the problem any more than exists +either, as it doesn't have any intrinsic inescapable leaks in it. Bstrlib +does not preclude the use of automatic garbage collection mechanisms such as +the Boehm garbage collector. + +7. Encryption + +Bstrlib does not present any built-in encryption mechanism. However, it +supports full binary contents in its data buffers, so any standard block +based encryption mechanism can make direct use of bstrings/CBStrings for +buffer management. + +8. Double freeing + +Freeing a pointer that is already free is an extremely rare, but nevertheless +a potentially ruthlessly corrupting operation (its possible to cause Win 98 to +reboot, by calling free mulitiple times on already freed data using the WATCOM +CRT.) Bstrlib invalidates the bstring header data before freeing, so that in +many cases a double free will be detected and an error will be reported +(though this behaviour is not guaranteed and should not be relied on). + +Using bstrFree pervasively (instead of bdestroy) can lead to somewhat +improved invalid free avoidance (it is completely safe whenever bstring +instances are only stored in unique variables). For example: + + struct tagbstring hw = bsStatic ("Hello, world"); + bstring cpHw = bstrcpy (&hw); + + #ifdef NOT_QUITE_AS_SAFE + bdestroy (cpHw); /* Never fail */ + bdestroy (cpHw); /* Error sometimes detected at runtime */ + bdestroy (&hw); /* Error detected at run time */ + #else + bstrFree (cpHw); /* Never fail */ + bstrFree (cpHw); /* Will do nothing */ + bstrFree (&hw); /* Will lead to a compile time error */ + #endif + +9. Resource based denial of service + +bSecureInput() has been supplied in bstraux.c. It has an optional upper limit +for input length. But unlike fgets(), it is also easily determined if the +buffer has been truncated early. In this way, a program can set an upper limit +on input sizes while still allowing for implementing context specific +truncation semantics (i.e., does the program consume but dump the extra +input, or does it consume it in later inputs?) + +10. Mixing char *'s and bstrings + +The bstring and char * representations are not identical. So there is a risk +when converting back and forth that data may lost. Essentially bstrings can +contain '\0' as a valid non-terminating character, while char * strings +cannot and in fact must use the character as a terminator. The risk of data +loss is very low, since: + + A) the simple method of only using bstrings in a char * semantically + compatible way is both easy to achieve and pervasively supported. + B) obtaining '\0' content in a string is either deliberate or indicative + of another, likely more serious problem in the code. + C) the library comes with various functions which deal with this issue + (namely: bfromcstr(), bstr2cstr (), and bSetCstrChar ()) + +Marginal security issues: +......................... + +11. 8-bit versus 9-bit portability + +Bstrlib uses CHAR_BIT and other limits.h constants to the maximum extent +possible to avoid portability problems. However, Bstrlib has not been tested +on any system that does not represent char as 8-bits. So whether or not it +works on 9-bit systems is an open question. It is recommended that Bstrlib be +carefully auditted by anyone using a system in which CHAR_BIT is not 8. + +12. EBCDIC/ASCII/UTF-8 data representation attacks. + +Bstrlib uses ctype.h functions to ensure that it remains portable to non- +ASCII systems. It also checks range to make sure it is well defined even for +data that ANSI does not define for the ctype functions. + +Obscure issues: +............... + +13. Data attributes + +There is no support for a Perl-like "taint" attribute, however, an example of +how to do this using C++'s type system is given as an example. + diff --git a/build/tools/HLSLcc/May_2014/src/decode.c b/build/tools/HLSLcc/May_2014/src/decode.c new file mode 100644 index 0000000..71a8be8 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/decode.c @@ -0,0 +1,1640 @@ +#include "internal_includes/tokens.h" +#include "internal_includes/structs.h" +#include "internal_includes/decode.h" +#include "stdlib.h" +#include "stdio.h" +#include "internal_includes/reflect.h" +#include "internal_includes/debug.h" +#include "internal_includes/hlslcc_malloc.h" + +#define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 )) +static enum {FOURCC_DXBC = FOURCC('D', 'X', 'B', 'C')}; //DirectX byte code +static enum {FOURCC_SHDR = FOURCC('S', 'H', 'D', 'R')}; //Shader model 4 code +static enum {FOURCC_SHEX = FOURCC('S', 'H', 'E', 'X')}; //Shader model 5 code +static enum {FOURCC_RDEF = FOURCC('R', 'D', 'E', 'F')}; //Resource definition (e.g. constant buffers) +static enum {FOURCC_ISGN = FOURCC('I', 'S', 'G', 'N')}; //Input signature +static enum {FOURCC_IFCE = FOURCC('I', 'F', 'C', 'E')}; //Interface (for dynamic linking) +static enum {FOURCC_OSGN = FOURCC('O', 'S', 'G', 'N')}; //Output signature + +static enum {FOURCC_ISG1 = FOURCC('I', 'S', 'G', '1')}; //Input signature with Stream and MinPrecision +static enum {FOURCC_OSG1 = FOURCC('O', 'S', 'G', '1')}; //Output signature with Stream and MinPrecision +static enum {FOURCC_OSG5 = FOURCC('O', 'S', 'G', '5')}; //Output signature with Stream + +typedef struct DXBCContainerHeaderTAG +{ + unsigned fourcc; + uint32_t unk[4]; + uint32_t one; + uint32_t totalSize; + uint32_t chunkCount; +} DXBCContainerHeader; + +typedef struct DXBCChunkHeaderTAG +{ + unsigned fourcc; + unsigned size; +} DXBCChunkHeader; + +#ifdef _DEBUG +static uint64_t operandID = 0; +static uint64_t instructionID = 0; +#endif + +#if defined(_WIN32) +#define osSprintf(dest, size, src) sprintf_s(dest, size, src) +#else +#define osSprintf(dest, size, src) sprintf(dest, src) +#endif + +void DecodeNameToken(const uint32_t* pui32NameToken, Operand* psOperand) +{ + const size_t MAX_BUFFER_SIZE = sizeof(psOperand->pszSpecialName); + psOperand->eSpecialName = DecodeOperandSpecialName(*pui32NameToken); + switch(psOperand->eSpecialName) + { + case NAME_UNDEFINED: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "undefined"); + break; + } + case NAME_POSITION: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "position"); + break; + } + case NAME_CLIP_DISTANCE: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "clipDistance"); + break; + } + case NAME_CULL_DISTANCE: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "cullDistance"); + break; + } + case NAME_RENDER_TARGET_ARRAY_INDEX: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "renderTargetArrayIndex"); + break; + } + case NAME_VIEWPORT_ARRAY_INDEX: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "viewportArrayIndex"); + break; + } + case NAME_VERTEX_ID: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "vertexID"); + break; + } + case NAME_PRIMITIVE_ID: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "primitiveID"); + break; + } + case NAME_INSTANCE_ID: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "instanceID"); + break; + } + case NAME_IS_FRONT_FACE: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "isFrontFace"); + break; + } + case NAME_SAMPLE_INDEX: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "sampleIndex"); + break; + } + //For the quadrilateral domain, there are 6 factors (4 sides, 2 inner). + case NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR: + case NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR: + case NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR: + case NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR: + case NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR: + case NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR: + + //For the triangular domain, there are 4 factors (3 sides, 1 inner) + case NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR: + case NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR: + case NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR: + case NAME_FINAL_TRI_INSIDE_TESSFACTOR: + + //For the isoline domain, there are 2 factors (detail and density). + case NAME_FINAL_LINE_DETAIL_TESSFACTOR: + case NAME_FINAL_LINE_DENSITY_TESSFACTOR: + { + osSprintf(psOperand->pszSpecialName, MAX_BUFFER_SIZE, "tessFactor"); + break; + } + default: + { + ASSERT(0); + break; + } + } + + return; +} + +// Find the declaration of the texture described by psTextureOperand and +// mark it as a shadow type. (e.g. accessed via sampler2DShadow rather than sampler2D) +void MarkTextureAsShadow(ShaderInfo* psShaderInfo, Declaration* psDeclList, const uint32_t ui32DeclCount, const Operand* psTextureOperand) +{ + ResourceBinding* psBinding = 0; + Declaration* psDecl = psDeclList; + uint32_t i; + + ASSERT(psTextureOperand->eType == OPERAND_TYPE_RESOURCE); + + for(i = 0; i < ui32DeclCount; ++i) + { + if(psDecl->eOpcode == OPCODE_DCL_RESOURCE) + { + if(psDecl->asOperands[0].eType == OPERAND_TYPE_RESOURCE && + psDecl->asOperands[0].ui32RegisterNumber == psTextureOperand->ui32RegisterNumber) + { + psDecl->ui32IsShadowTex = 1; + break; + } + } + psDecl++; + } +} + +uint32_t DecodeOperand (const uint32_t *pui32Tokens, Operand* psOperand) +{ + int i; + uint32_t ui32NumTokens = 1; + OPERAND_NUM_COMPONENTS eNumComponents; + +#ifdef _DEBUG + psOperand->id = operandID++; +#endif + + //Some defaults + psOperand->iWriteMaskEnabled = 1; + psOperand->iGSInput = 0; + psOperand->aeDataType[0] = SVT_FLOAT; + psOperand->aeDataType[1] = SVT_FLOAT; + psOperand->aeDataType[2] = SVT_FLOAT; + psOperand->aeDataType[3] = SVT_FLOAT; + + psOperand->iExtended = DecodeIsOperandExtended(*pui32Tokens); + + + psOperand->eModifier = OPERAND_MODIFIER_NONE; + psOperand->psSubOperand[0] = 0; + psOperand->psSubOperand[1] = 0; + psOperand->psSubOperand[2] = 0; + + /* Check if this instruction is extended. If it is, + * we need to print the information first */ + if (psOperand->iExtended) + { + /* OperandToken1 is the second token */ + ui32NumTokens++; + + if(DecodeExtendedOperandType(pui32Tokens[1]) == EXTENDED_OPERAND_MODIFIER) + { + psOperand->eModifier = DecodeExtendedOperandModifier(pui32Tokens[1]); + psOperand->eMinPrecision = DecodeOperandMinPrecision(pui32Tokens[1]); + } + + } + + psOperand->iIndexDims = DecodeOperandIndexDimension(*pui32Tokens); + psOperand->eType = DecodeOperandType(*pui32Tokens); + + psOperand->ui32RegisterNumber = 0; + + eNumComponents = DecodeOperandNumComponents(*pui32Tokens); + + switch(eNumComponents) + { + case OPERAND_1_COMPONENT: + { + psOperand->iNumComponents = 1; + break; + } + case OPERAND_4_COMPONENT: + { + psOperand->iNumComponents = 4; + break; + } + default: + { + psOperand->iNumComponents = 0; + break; + } + } + + if(psOperand->iWriteMaskEnabled && + psOperand->iNumComponents == 4) + { + psOperand->eSelMode = DecodeOperand4CompSelMode(*pui32Tokens); + + if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + psOperand->ui32CompMask = DecodeOperand4CompMask(*pui32Tokens); + } + else + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + psOperand->ui32Swizzle = DecodeOperand4CompSwizzle(*pui32Tokens); + + if(psOperand->ui32Swizzle != NO_SWIZZLE) + { + psOperand->aui32Swizzle[0] = DecodeOperand4CompSwizzleSource(*pui32Tokens, 0); + psOperand->aui32Swizzle[1] = DecodeOperand4CompSwizzleSource(*pui32Tokens, 1); + psOperand->aui32Swizzle[2] = DecodeOperand4CompSwizzleSource(*pui32Tokens, 2); + psOperand->aui32Swizzle[3] = DecodeOperand4CompSwizzleSource(*pui32Tokens, 3); + } + else + { + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_X; + psOperand->aui32Swizzle[1] = OPERAND_4_COMPONENT_Y; + psOperand->aui32Swizzle[2] = OPERAND_4_COMPONENT_Z; + psOperand->aui32Swizzle[3] = OPERAND_4_COMPONENT_W; + } + } + else + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + psOperand->aui32Swizzle[0] = DecodeOperand4CompSel1(*pui32Tokens); + } + } + + //Set externally to this function based on the instruction opcode. + psOperand->iIntegerImmediate = 0; + + if(psOperand->eType == OPERAND_TYPE_IMMEDIATE32) + { + for(i=0; i< psOperand->iNumComponents; ++i) + { + psOperand->afImmediates[i] = *((float*)(&pui32Tokens[ui32NumTokens])); + ui32NumTokens ++; + } + } + else + if(psOperand->eType == OPERAND_TYPE_IMMEDIATE64) + { + for(i=0; i< psOperand->iNumComponents; ++i) + { + psOperand->adImmediates[i] = *((double*)(&pui32Tokens[ui32NumTokens])); + ui32NumTokens +=2; + } + } + + for(i=0; i iIndexDims; ++i) + { + OPERAND_INDEX_REPRESENTATION eRep = DecodeOperandIndexRepresentation(i ,*pui32Tokens); + + psOperand->eIndexRep[i] = eRep; + + psOperand->aui32ArraySizes[i] = 0; + psOperand->ui32RegisterNumber = 0; + + switch(eRep) + { + case OPERAND_INDEX_IMMEDIATE32: + { + psOperand->ui32RegisterNumber = *(pui32Tokens+ui32NumTokens); + psOperand->aui32ArraySizes[i] = psOperand->ui32RegisterNumber; + break; + } + case OPERAND_INDEX_RELATIVE: + { + psOperand->psSubOperand[i] = hlslcc_malloc(sizeof(Operand)); + DecodeOperand(pui32Tokens+ui32NumTokens, psOperand->psSubOperand[i]); + + ui32NumTokens++; + break; + } + case OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE: + { + psOperand->ui32RegisterNumber = *(pui32Tokens+ui32NumTokens); + psOperand->aui32ArraySizes[i] = psOperand->ui32RegisterNumber; + + ui32NumTokens++; + + psOperand->psSubOperand[i] = hlslcc_malloc(sizeof(Operand)); + DecodeOperand(pui32Tokens+ui32NumTokens, psOperand->psSubOperand[i]); + + ui32NumTokens++; + break; + } + default: + { + ASSERT(0); + break; + } + } + + ui32NumTokens++; + } + + psOperand->pszSpecialName[0] ='\0'; + + return ui32NumTokens; +} + +const uint32_t* DecodeDeclaration(Shader* psShader, const uint32_t* pui32Token, Declaration* psDecl) +{ + uint32_t ui32TokenLength = DecodeInstructionLength(*pui32Token); + const uint32_t bExtended = DecodeIsOpcodeExtended(*pui32Token); + const OPCODE_TYPE eOpcode = DecodeOpcodeType(*pui32Token); + uint32_t ui32OperandOffset = 1; + + if(eOpcode < NUM_OPCODES && eOpcode >= 0) + { + psShader->aiOpcodeUsed[eOpcode] = 1; + } + + psDecl->eOpcode = eOpcode; + + psDecl->ui32IsShadowTex = 0; + + if(bExtended) + { + ui32OperandOffset = 2; + } + + switch (eOpcode) + { + case OPCODE_DCL_RESOURCE: // DCL* opcodes have + { + psDecl->value.eResourceDimension = DecodeResourceDimension(*pui32Token); + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_CONSTANT_BUFFER: // custom operand formats. + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_SAMPLER: + { + break; + } + case OPCODE_DCL_INDEX_RANGE: + { + psDecl->ui32NumOperands = 1; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + psDecl->value.ui32IndexRange = pui32Token[ui32OperandOffset]; + + if(psDecl->asOperands[0].eType == OPERAND_TYPE_INPUT) + { + uint32_t i; + const uint32_t indexRange = psDecl->value.ui32IndexRange; + const uint32_t reg = psDecl->asOperands[0].ui32RegisterNumber; + + psShader->aIndexedInput[reg] = indexRange; + psShader->aIndexedInputParents[reg] = reg; + + //-1 means don't declare this input because it falls in + //the range of an already declared array. + for(i=reg+1; iaIndexedInput[i] = -1; + psShader->aIndexedInputParents[i] = reg; + } + } + + if(psDecl->asOperands[0].eType == OPERAND_TYPE_OUTPUT) + { + psShader->aIndexedOutput[psDecl->asOperands[0].ui32RegisterNumber] = psDecl->value.ui32IndexRange; + } + break; + } + case OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: + { + psDecl->value.eOutputPrimitiveTopology = DecodeGSOutputPrimitiveTopology(*pui32Token); + break; + } + case OPCODE_DCL_GS_INPUT_PRIMITIVE: + { + psDecl->value.eInputPrimitive = DecodeGSInputPrimitive(*pui32Token); + break; + } + case OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT: + { + psDecl->value.ui32MaxOutputVertexCount = pui32Token[1]; + break; + } + case OPCODE_DCL_TESS_PARTITIONING: + { + psDecl->value.eTessPartitioning = DecodeTessPartitioning(*pui32Token); + break; + } + case OPCODE_DCL_TESS_DOMAIN: + { + psDecl->value.eTessDomain = DecodeTessDomain(*pui32Token); + break; + } + case OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: + { + psDecl->value.eTessOutPrim = DecodeTessOutPrim(*pui32Token); + break; + } + case OPCODE_DCL_THREAD_GROUP: + { + psDecl->value.aui32WorkGroupSize[0] = pui32Token[1]; + psDecl->value.aui32WorkGroupSize[1] = pui32Token[2]; + psDecl->value.aui32WorkGroupSize[2] = pui32Token[3]; + break; + } + case OPCODE_DCL_INPUT: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_INPUT_SIV: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + if(psShader->eShaderType == PIXEL_SHADER) + { + psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token); + + } + break; + } + case OPCODE_DCL_INPUT_PS: + { + psDecl->ui32NumOperands = 1; + psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token); + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_INPUT_SGV: + case OPCODE_DCL_INPUT_PS_SGV: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + DecodeNameToken(pui32Token + 3, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_INPUT_PS_SIV: + { + psDecl->ui32NumOperands = 1; + psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token); + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + DecodeNameToken(pui32Token + 3, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_OUTPUT: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_OUTPUT_SGV: + { + break; + } + case OPCODE_DCL_OUTPUT_SIV: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + DecodeNameToken(pui32Token + 3, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_TEMPS: + { + psDecl->value.ui32NumTemps = *(pui32Token+ui32OperandOffset); + break; + } + case OPCODE_DCL_INDEXABLE_TEMP: + { + psDecl->sIdxTemp.ui32RegIndex = *(pui32Token+ui32OperandOffset); + psDecl->sIdxTemp.ui32RegCount = *(pui32Token+ui32OperandOffset+1); + psDecl->sIdxTemp.ui32RegComponentSize = *(pui32Token+ui32OperandOffset+2); + break; + } + case OPCODE_DCL_GLOBAL_FLAGS: + { + psDecl->value.ui32GlobalFlags = DecodeGlobalFlags(*pui32Token); + break; + } + case OPCODE_DCL_INTERFACE: + { + uint32_t func = 0, numClassesImplementingThisInterface, arrayLen, interfaceID; + interfaceID = pui32Token[ui32OperandOffset]; + ui32OperandOffset++; + psDecl->ui32TableLength = pui32Token[ui32OperandOffset]; + ui32OperandOffset++; + + numClassesImplementingThisInterface = DecodeInterfaceTableLength(*(pui32Token+ui32OperandOffset)); + arrayLen = DecodeInterfaceArrayLength(*(pui32Token+ui32OperandOffset)); + + ui32OperandOffset++; + + psDecl->value.interface.ui32InterfaceID = interfaceID; + psDecl->value.interface.ui32NumFuncTables = numClassesImplementingThisInterface; + psDecl->value.interface.ui32ArraySize = arrayLen; + + psShader->funcPointer[interfaceID].ui32NumBodiesPerTable = psDecl->ui32TableLength; + + for(;func < numClassesImplementingThisInterface; ++func) + { + uint32_t ui32FuncTable = *(pui32Token+ui32OperandOffset); + psShader->aui32FuncTableToFuncPointer[ui32FuncTable] = interfaceID; + + psShader->funcPointer[interfaceID].aui32FuncTables[func] = ui32FuncTable; + ui32OperandOffset++; + } + + break; + } + case OPCODE_DCL_FUNCTION_BODY: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_FUNCTION_TABLE: + { + uint32_t ui32Func; + const uint32_t ui32FuncTableID = pui32Token[ui32OperandOffset++]; + const uint32_t ui32NumFuncsInTable = pui32Token[ui32OperandOffset++]; + + for(ui32Func=0; ui32Funcaui32FuncBodyToFuncTable[ui32FuncBodyID] = ui32FuncTableID; + + psShader->funcTable[ui32FuncTableID].aui32FuncBodies[ui32Func] = ui32FuncBodyID; + + } + +// OpcodeToken0 is followed by a DWORD that represents the function table +// identifier and another DWORD (TableLength) that gives the number of +// functions in the table. +// +// This is followed by TableLength DWORDs which are function body indices. +// + + break; + } + case OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: + { + break; + } + case OPCODE_HS_DECLS: + { + break; + } + case OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: + { + psDecl->value.ui32MaxOutputVertexCount = DecodeOutputControlPointCount(*pui32Token); + break; + } + case OPCODE_HS_JOIN_PHASE: + case OPCODE_HS_FORK_PHASE: + case OPCODE_HS_CONTROL_POINT_PHASE: + { + break; + } + case OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: + { + ASSERT(psShader->ui32ForkPhaseCount != 0);//Check for wrapping when we decrement. + psDecl->value.aui32HullPhaseInstanceInfo[0] = psShader->ui32ForkPhaseCount-1; + psDecl->value.aui32HullPhaseInstanceInfo[1] = pui32Token[1]; + break; + } + case OPCODE_CUSTOMDATA: + { + ui32TokenLength = pui32Token[1]; + { + int iTupleSrc = 0, iTupleDest = 0; + //const uint32_t ui32ConstCount = pui32Token[1] - 2; + //const uint32_t ui32TupleCount = (ui32ConstCount / 4); + CUSTOMDATA_CLASS eClass = DecodeCustomDataClass(pui32Token[0]); + + const uint32_t ui32NumVec4 = (ui32TokenLength - 2) / 4; + uint32_t uIdx = 0; + + ICBVec4 const *pVec4Array = (void*) (pui32Token + 2); + + //The buffer will contain at least one value, but not more than 4096 scalars/1024 vec4's. + ASSERT(ui32NumVec4 < MAX_IMMEDIATE_CONST_BUFFER_VEC4_SIZE); + + /* must be a multiple of 4 */ + ASSERT(((ui32TokenLength - 2) % 4) == 0); + + for (uIdx = 0; uIdx < ui32NumVec4; uIdx++) + { + psDecl->asImmediateConstBuffer[uIdx] = pVec4Array[uIdx]; + } + + psDecl->ui32NumOperands = ui32NumVec4; + } + break; + } + case OPCODE_DCL_HS_MAX_TESSFACTOR: + { + psDecl->value.fMaxTessFactor = *((float*)&pui32Token[1]); + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: + { + psDecl->ui32NumOperands = 2; + psDecl->value.eResourceDimension = DecodeResourceDimension(*pui32Token); + psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token); + psDecl->sUAV.bCounter = 0; + psDecl->sUAV.ui32BufferSize = 0; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + psDecl->sUAV.Type = DecodeResourceReturnType(0, pui32Token[ui32OperandOffset]); + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW: + { + ResourceBinding* psBinding = NULL; + ConstantBuffer* psBuffer = NULL; + + psDecl->ui32NumOperands = 1; + psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token); + psDecl->sUAV.bCounter = 0; + psDecl->sUAV.ui32BufferSize = 0; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + //This should be a RTYPE_UAV_RWBYTEADDRESS buffer. It is memory backed by + //a shader storage buffer whose is unknown at compile time. + psDecl->sUAV.ui32BufferSize = 0; + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: + { + ResourceBinding* psBinding = NULL; + ConstantBuffer* psBuffer = NULL; + + psDecl->ui32NumOperands = 1; + psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token); + psDecl->sUAV.bCounter = 0; + psDecl->sUAV.ui32BufferSize = 0; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + + GetResourceFromBindingPoint(RGROUP_UAV, psDecl->asOperands[0].ui32RegisterNumber, &psShader->sInfo, &psBinding); + + GetConstantBufferFromBindingPoint(RGROUP_UAV, psBinding->ui32BindPoint, &psShader->sInfo, &psBuffer); + psDecl->sUAV.ui32BufferSize = psBuffer->ui32TotalSizeInBytes; + switch(psBinding->eType) + { + case RTYPE_UAV_RWSTRUCTURED_WITH_COUNTER: + case RTYPE_UAV_APPEND_STRUCTURED: + case RTYPE_UAV_CONSUME_STRUCTURED: + psDecl->sUAV.bCounter = 1; + break; + default: + break; + } + break; + } + case OPCODE_DCL_RESOURCE_STRUCTURED: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_RESOURCE_RAW: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: + { + ResourceBinding* psBinding = NULL; + ConstantBuffer* psBuffer = NULL; + + psDecl->ui32NumOperands = 1; + psDecl->sUAV.ui32GloballyCoherentAccess = 0; + + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + + psDecl->sTGSM.ui32Stride = pui32Token[ui32OperandOffset++]; + psDecl->sTGSM.ui32Count = pui32Token[ui32OperandOffset++]; + break; + } + case OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW: + { + ResourceBinding* psBinding = NULL; + ConstantBuffer* psBuffer = NULL; + + psDecl->ui32NumOperands = 1; + psDecl->sUAV.ui32GloballyCoherentAccess = 0; + + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + + psDecl->sTGSM.ui32Stride = 4; + psDecl->sTGSM.ui32Count = pui32Token[ui32OperandOffset++]; + break; + } + case OPCODE_DCL_STREAM: + { + psDecl->ui32NumOperands = 1; + DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); + break; + } + case OPCODE_DCL_GS_INSTANCE_COUNT: + { + psDecl->ui32NumOperands = 0; + psDecl->value.ui32GSInstanceCount = pui32Token[1]; + break; + } + default: + { + //Reached end of declarations + return 0; + } + } + + return pui32Token + ui32TokenLength; +} + +const uint32_t* DeocdeInstruction(const uint32_t* pui32Token, Instruction* psInst, Shader* psShader) +{ + uint32_t ui32TokenLength = DecodeInstructionLength(*pui32Token); + const uint32_t bExtended = DecodeIsOpcodeExtended(*pui32Token); + const OPCODE_TYPE eOpcode = DecodeOpcodeType(*pui32Token); + uint32_t ui32OperandOffset = 1; + +#ifdef _DEBUG + psInst->id = instructionID++; +#endif + + psInst->eOpcode = eOpcode; + + psInst->bSaturate = DecodeInstructionSaturate(*pui32Token); + + psInst->bAddressOffset = 0; + + psInst->ui32FirstSrc = 1; + + if(bExtended) + { + do { + const uint32_t ui32ExtOpcodeToken = pui32Token[ui32OperandOffset]; + const EXTENDED_OPCODE_TYPE eExtType = DecodeExtendedOpcodeType(ui32ExtOpcodeToken); + + if(eExtType == EXTENDED_OPCODE_SAMPLE_CONTROLS) + { + struct {int i4:4;} sU; + struct {int i4:4;} sV; + struct {int i4:4;} sW; + + psInst->bAddressOffset = 1; + + sU.i4 = DecodeImmediateAddressOffset( + IMMEDIATE_ADDRESS_OFFSET_U, ui32ExtOpcodeToken); + sV.i4 = DecodeImmediateAddressOffset( + IMMEDIATE_ADDRESS_OFFSET_V, ui32ExtOpcodeToken); + sW.i4 = DecodeImmediateAddressOffset( + IMMEDIATE_ADDRESS_OFFSET_W, ui32ExtOpcodeToken); + + psInst->iUAddrOffset = sU.i4; + psInst->iVAddrOffset = sV.i4; + psInst->iWAddrOffset = sW.i4; + } + else if(eExtType == EXTENDED_OPCODE_RESOURCE_RETURN_TYPE) + { + psInst->xType = DecodeExtendedResourceReturnType(0, ui32ExtOpcodeToken); + psInst->yType = DecodeExtendedResourceReturnType(1, ui32ExtOpcodeToken); + psInst->zType = DecodeExtendedResourceReturnType(2, ui32ExtOpcodeToken); + psInst->wType = DecodeExtendedResourceReturnType(3, ui32ExtOpcodeToken); + } + else if(eExtType == EXTENDED_OPCODE_RESOURCE_DIM) + { + psInst->eResDim = DecodeExtendedResourceDimension(ui32ExtOpcodeToken); + } + + ui32OperandOffset++; + } + while(DecodeIsOpcodeExtended(pui32Token[ui32OperandOffset-1])); + } + + if(eOpcode < NUM_OPCODES && eOpcode >= 0) + { + psShader->aiOpcodeUsed[eOpcode] = 1; + } + + switch (eOpcode) + { + //no operands + case OPCODE_CUT: + case OPCODE_EMIT: + case OPCODE_EMITTHENCUT: + case OPCODE_RET: + case OPCODE_LOOP: + case OPCODE_ENDLOOP: + case OPCODE_BREAK: + case OPCODE_ELSE: + case OPCODE_ENDIF: + case OPCODE_CONTINUE: + case OPCODE_DEFAULT: + case OPCODE_ENDSWITCH: + case OPCODE_NOP: + case OPCODE_HS_CONTROL_POINT_PHASE: + case OPCODE_HS_FORK_PHASE: + case OPCODE_HS_JOIN_PHASE: + { + psInst->ui32NumOperands = 0; + psInst->ui32FirstSrc = 0; + break; + } + case OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: + { + psInst->ui32NumOperands = 0; + psInst->ui32FirstSrc = 0; + break; + } + case OPCODE_SYNC: + { + psInst->ui32NumOperands = 0; + psInst->ui32FirstSrc = 0; + psInst->ui32SyncFlags = DecodeSyncFlags(*pui32Token); + break; + } + + //1 operand + case OPCODE_EMIT_STREAM: + case OPCODE_CUT_STREAM: + case OPCODE_EMITTHENCUT_STREAM: + case OPCODE_CASE: + case OPCODE_SWITCH: + case OPCODE_LABEL: + { + psInst->ui32NumOperands = 1; + psInst->ui32FirstSrc = 0; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + + if(eOpcode == OPCODE_CASE) + { + psInst->asOperands[0].iIntegerImmediate = 1; + } + break; + } + + case OPCODE_INTERFACE_CALL: + { + psInst->ui32NumOperands = 1; + psInst->ui32FirstSrc = 0; + psInst->ui32FuncIndexWithinInterface = pui32Token[ui32OperandOffset]; + ui32OperandOffset++; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + + break; + } + + /* Floating point instruction decodes */ + + //Instructions with two operands go here + case OPCODE_MOV: + { + psInst->ui32NumOperands = 2; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + + //Mov with an integer dest. If src is an immediate then it must be encoded as an integer. + if(psInst->asOperands[0].eMinPrecision == OPERAND_MIN_PRECISION_SINT_16 || + psInst->asOperands[0].eMinPrecision == OPERAND_MIN_PRECISION_UINT_16) + { + psInst->asOperands[1].iIntegerImmediate = 1; + } + break; + } + case OPCODE_LOG: + case OPCODE_RSQ: + case OPCODE_EXP: + case OPCODE_SQRT: + case OPCODE_ROUND_PI: + case OPCODE_ROUND_NI: + case OPCODE_ROUND_Z: + case OPCODE_ROUND_NE: + case OPCODE_FRC: + case OPCODE_FTOU: + case OPCODE_FTOI: + case OPCODE_UTOF: + case OPCODE_ITOF: + case OPCODE_INEG: + case OPCODE_IMM_ATOMIC_ALLOC: + case OPCODE_IMM_ATOMIC_CONSUME: + case OPCODE_DMOV: + case OPCODE_DTOF: + case OPCODE_FTOD: + case OPCODE_DRCP: + case OPCODE_COUNTBITS: + case OPCODE_FIRSTBIT_HI: + case OPCODE_FIRSTBIT_LO: + case OPCODE_FIRSTBIT_SHI: + case OPCODE_BFREV: + case OPCODE_F32TOF16: + case OPCODE_F16TOF32: + case OPCODE_RCP: + case OPCODE_DERIV_RTX: + case OPCODE_DERIV_RTY: + case OPCODE_DERIV_RTX_COARSE: + case OPCODE_DERIV_RTX_FINE: + case OPCODE_DERIV_RTY_COARSE: + case OPCODE_DERIV_RTY_FINE: + case OPCODE_NOT: + { + psInst->ui32NumOperands = 2; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + break; + } + + //Instructions with three operands go here + case OPCODE_SINCOS: + { + psInst->ui32FirstSrc = 2; + //Intentional fall-through + } + case OPCODE_IMIN: + case OPCODE_MIN: + case OPCODE_IMAX: + case OPCODE_MAX: + case OPCODE_MUL: + case OPCODE_DIV: + case OPCODE_ADD: + case OPCODE_DP2: + case OPCODE_DP3: + case OPCODE_DP4: + case OPCODE_NE: + case OPCODE_OR: + case OPCODE_XOR: + case OPCODE_LT: + case OPCODE_IEQ: + case OPCODE_IADD: + case OPCODE_AND: + case OPCODE_GE: + case OPCODE_IGE: + case OPCODE_EQ: + case OPCODE_USHR: + case OPCODE_ISHL: + case OPCODE_ISHR: + case OPCODE_LD: + case OPCODE_ILT: + case OPCODE_INE: + case OPCODE_UGE: + case OPCODE_ULT: + case OPCODE_ATOMIC_AND: + case OPCODE_ATOMIC_IADD: + case OPCODE_ATOMIC_OR: + case OPCODE_ATOMIC_XOR: + case OPCODE_ATOMIC_IMAX: + case OPCODE_ATOMIC_IMIN: + case OPCODE_ATOMIC_UMAX: + case OPCODE_ATOMIC_UMIN: + case OPCODE_DADD: + case OPCODE_DMAX: + case OPCODE_DMIN: + case OPCODE_DMUL: + case OPCODE_DEQ: + case OPCODE_DGE: + case OPCODE_DLT: + case OPCODE_DNE: + case OPCODE_DDIV: + { + psInst->ui32NumOperands = 3; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + break; + } + //Instructions with four operands go here + case OPCODE_MAD: + case OPCODE_MOVC: + case OPCODE_IMAD: + case OPCODE_UDIV: + case OPCODE_LOD: + case OPCODE_SAMPLE: + case OPCODE_GATHER4: + case OPCODE_LD_MS: + case OPCODE_UBFE: + case OPCODE_IBFE: + case OPCODE_ATOMIC_CMP_STORE: + case OPCODE_IMM_ATOMIC_IADD: + case OPCODE_IMM_ATOMIC_AND: + case OPCODE_IMM_ATOMIC_OR: + case OPCODE_IMM_ATOMIC_XOR: + case OPCODE_IMM_ATOMIC_EXCH: + case OPCODE_IMM_ATOMIC_IMAX: + case OPCODE_IMM_ATOMIC_IMIN: + case OPCODE_IMM_ATOMIC_UMAX: + case OPCODE_IMM_ATOMIC_UMIN: + case OPCODE_DMOVC: + case OPCODE_DFMA: + case OPCODE_IMUL: + { + psInst->ui32NumOperands = 4; + + if(eOpcode == OPCODE_IMUL) + { + psInst->ui32FirstSrc = 2; + } + + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[3]); + break; + } + case OPCODE_GATHER4_PO: + case OPCODE_SAMPLE_L: + case OPCODE_BFI: + case OPCODE_SWAPC: + case OPCODE_IMM_ATOMIC_CMP_EXCH: + { + psInst->ui32NumOperands = 5; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[3]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[4]); + break; + } + case OPCODE_GATHER4_C: + case OPCODE_SAMPLE_C: + case OPCODE_SAMPLE_C_LZ: + case OPCODE_SAMPLE_B: + { + psInst->ui32NumOperands = 5; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[3]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[4]); + + MarkTextureAsShadow(&psShader->sInfo, psShader->psDecl, psShader->ui32DeclCount, &psInst->asOperands[2]); + break; + } + case OPCODE_GATHER4_PO_C: + case OPCODE_SAMPLE_D: + { + psInst->ui32NumOperands = 6; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[3]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[4]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[5]); + + MarkTextureAsShadow(&psShader->sInfo, psShader->psDecl, psShader->ui32DeclCount, &psInst->asOperands[2]); + break; + } + case OPCODE_IF: + case OPCODE_BREAKC: + case OPCODE_CONTINUEC: + case OPCODE_RETC: + case OPCODE_DISCARD: + { + psInst->eBooleanTestType = DecodeInstrTestBool(*pui32Token); + psInst->ui32NumOperands = 1; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + break; + } + case OPCODE_CALLC: + { + psInst->eBooleanTestType = DecodeInstrTestBool(*pui32Token); + psInst->ui32NumOperands = 2; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + break; + } + case OPCODE_CUSTOMDATA: + { + psInst->ui32NumOperands = 0; + ui32TokenLength = pui32Token[1]; + break; + } + case OPCODE_EVAL_CENTROID: + { + psInst->ui32NumOperands = 2; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + break; + } + case OPCODE_EVAL_SAMPLE_INDEX: + case OPCODE_EVAL_SNAPPED: + case OPCODE_STORE_UAV_TYPED: + case OPCODE_LD_UAV_TYPED: + case OPCODE_LD_RAW: + case OPCODE_STORE_RAW: + { + psInst->ui32NumOperands = 3; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + break; + } + case OPCODE_STORE_STRUCTURED: + case OPCODE_LD_STRUCTURED: + { + psInst->ui32NumOperands = 4; + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[3]); + break; + } + case OPCODE_RESINFO: + { + psInst->ui32NumOperands = 3; + + psInst->eResInfoReturnType = DecodeResInfoReturnType(pui32Token[0]); + + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[0]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[1]); + ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psInst->asOperands[2]); + break; + } + case OPCODE_MSAD: + default: + { + ASSERT(0); + break; + } + } + + UpdateOperandReferences(psShader, psInst); + + return pui32Token + ui32TokenLength; +} + +void UpdateOperandReferences(Shader* psShader, Instruction* psInst) +{ + uint32_t ui32Operand; + const uint32_t ui32NumOperands = psInst->ui32NumOperands; + for(ui32Operand = 0; ui32Operand < ui32NumOperands; ++ui32Operand) + { + Operand* psOperand = &psInst->asOperands[ui32Operand]; + if(psOperand->eType == OPERAND_TYPE_INPUT || + psOperand->eType == OPERAND_TYPE_INPUT_CONTROL_POINT) + { + if(psOperand->iIndexDims == INDEX_2D) + { + if(psOperand->aui32ArraySizes[1] != 0)//gl_in[].gl_Position + { + psShader->abInputReferencedByInstruction[psOperand->ui32RegisterNumber] = 1; + } + } + else + { + psShader->abInputReferencedByInstruction[psOperand->ui32RegisterNumber] = 1; + } + } + } +} + +const uint32_t* DecodeHullShaderJoinPhase(const uint32_t* pui32Tokens, Shader* psShader) +{ + const uint32_t* pui32CurrentToken = pui32Tokens; + const uint32_t ui32ShaderLength = psShader->ui32ShaderLength; + + Instruction* psInst; + +//Declarations + Declaration* psDecl; + psDecl = hlslcc_malloc(sizeof(Declaration) * ui32ShaderLength); + psShader->psHSJoinPhaseDecl = psDecl; + psShader->ui32HSJoinDeclCount = 0; + + while(1) //Keep going until we reach the first non-declaration token, or the end of the shader. + { + const uint32_t* pui32Result = DecodeDeclaration(psShader, pui32CurrentToken, psDecl); + + if(pui32Result) + { + pui32CurrentToken = pui32Result; + psShader->ui32HSJoinDeclCount++; + psDecl++; + + if(pui32CurrentToken >= (psShader->pui32FirstToken + ui32ShaderLength)) + { + break; + } + } + else + { + break; + } + } + + +//Instructions + psInst = hlslcc_malloc(sizeof(Instruction) * ui32ShaderLength); + psShader->psHSJoinPhaseInstr = psInst; + psShader->ui32HSJoinInstrCount = 0; + + while (pui32CurrentToken < (psShader->pui32FirstToken + ui32ShaderLength)) + { + const uint32_t* nextInstr = DeocdeInstruction(pui32CurrentToken, psInst, psShader); + +#ifdef _DEBUG + if(nextInstr == pui32CurrentToken) + { + ASSERT(0); + break; + } +#endif + + pui32CurrentToken = nextInstr; + psShader->ui32HSJoinInstrCount++; + + psInst++; + } + + return pui32CurrentToken; +} + +const uint32_t* DecodeHullShaderForkPhase(const uint32_t* pui32Tokens, Shader* psShader) +{ + const uint32_t* pui32CurrentToken = pui32Tokens; + const uint32_t ui32ShaderLength = psShader->ui32ShaderLength; + const uint32_t ui32ForkPhaseIndex = psShader->ui32ForkPhaseCount; + + Instruction* psInst; + +//Declarations + Declaration* psDecl; + psDecl = hlslcc_malloc(sizeof(Declaration) * ui32ShaderLength); + + ASSERT(ui32ForkPhaseIndex < MAX_FORK_PHASES); + + psShader->ui32ForkPhaseCount++; + + psShader->apsHSForkPhaseDecl[ui32ForkPhaseIndex] = psDecl; + psShader->aui32HSForkDeclCount[ui32ForkPhaseIndex] = 0; + + while(1) //Keep going until we reach the first non-declaration token, or the end of the shader. + { + const uint32_t* pui32Result = DecodeDeclaration(psShader, pui32CurrentToken, psDecl); + + if(pui32Result) + { + pui32CurrentToken = pui32Result; + psShader->aui32HSForkDeclCount[ui32ForkPhaseIndex]++; + psDecl++; + + if(pui32CurrentToken >= (psShader->pui32FirstToken + ui32ShaderLength)) + { + break; + } + } + else + { + break; + } + } + + +//Instructions + psInst = hlslcc_malloc(sizeof(Instruction) * ui32ShaderLength); + psShader->apsHSForkPhaseInstr[ui32ForkPhaseIndex] = psInst; + psShader->aui32HSForkInstrCount[ui32ForkPhaseIndex] = 0; + + while (pui32CurrentToken < (psShader->pui32FirstToken + ui32ShaderLength)) + { + const uint32_t* nextInstr = DeocdeInstruction(pui32CurrentToken, psInst, psShader); + +#ifdef _DEBUG + if(nextInstr == pui32CurrentToken) + { + ASSERT(0); + break; + } +#endif + + pui32CurrentToken = nextInstr; + + if(psInst->eOpcode == OPCODE_HS_FORK_PHASE) + { + pui32CurrentToken = DecodeHullShaderForkPhase(pui32CurrentToken, psShader); + return pui32CurrentToken; + } + + psShader->aui32HSForkInstrCount[ui32ForkPhaseIndex]++; + psInst++; + } + + return pui32CurrentToken; +} + +const uint32_t* DecodeHullShaderControlPointPhase(const uint32_t* pui32Tokens, Shader* psShader) +{ + const uint32_t* pui32CurrentToken = pui32Tokens; + const uint32_t ui32ShaderLength = psShader->ui32ShaderLength; + + Instruction* psInst; + +//TODO one block of memory for instructions and declarions to reduce memory usage and number of allocs. +//hlscc_malloc max(sizeof(declaration), sizeof(instruction) * shader length; or sizeof(DeclInst) - unifying both structs. + +//Declarations + Declaration* psDecl; + psDecl = hlslcc_malloc(sizeof(Declaration) * ui32ShaderLength); + psShader->psHSControlPointPhaseDecl = psDecl; + psShader->ui32HSControlPointDeclCount = 0; + + while(1) //Keep going until we reach the first non-declaration token, or the end of the shader. + { + const uint32_t* pui32Result = DecodeDeclaration(psShader, pui32CurrentToken, psDecl); + + if(pui32Result) + { + pui32CurrentToken = pui32Result; + psShader->ui32HSControlPointDeclCount++; + psDecl++; + + if(pui32CurrentToken >= (psShader->pui32FirstToken + ui32ShaderLength)) + { + break; + } + } + else + { + break; + } + } + + +//Instructions + psInst = hlslcc_malloc(sizeof(Instruction) * ui32ShaderLength); + psShader->psHSControlPointPhaseInstr = psInst; + psShader->ui32HSControlPointInstrCount = 0; + + while (pui32CurrentToken < (psShader->pui32FirstToken + ui32ShaderLength)) + { + const uint32_t* nextInstr = DeocdeInstruction(pui32CurrentToken, psInst, psShader); + +#ifdef _DEBUG + if(nextInstr == pui32CurrentToken) + { + ASSERT(0); + break; + } +#endif + + pui32CurrentToken = nextInstr; + + if(psInst->eOpcode == OPCODE_HS_FORK_PHASE) + { + pui32CurrentToken = DecodeHullShaderForkPhase(pui32CurrentToken, psShader); + return pui32CurrentToken; + } + if(psInst->eOpcode == OPCODE_HS_JOIN_PHASE) + { + pui32CurrentToken = DecodeHullShaderJoinPhase(pui32CurrentToken, psShader); + return pui32CurrentToken; + } + psInst++; + psShader->ui32HSControlPointInstrCount++; + } + + return pui32CurrentToken; +} + +const uint32_t* DecodeHullShader(const uint32_t* pui32Tokens, Shader* psShader) +{ + const uint32_t* pui32CurrentToken = pui32Tokens; + const uint32_t ui32ShaderLength = psShader->ui32ShaderLength; + Declaration* psDecl; + psDecl = hlslcc_malloc(sizeof(Declaration) * ui32ShaderLength); + psShader->psHSDecl = psDecl; + psShader->ui32HSDeclCount = 0; + + while(1) //Keep going until we reach the first non-declaration token, or the end of the shader. + { + const uint32_t* pui32Result = DecodeDeclaration(psShader, pui32CurrentToken, psDecl); + + if(pui32Result) + { + pui32CurrentToken = pui32Result; + + if(psDecl->eOpcode == OPCODE_HS_CONTROL_POINT_PHASE) + { + pui32CurrentToken = DecodeHullShaderControlPointPhase(pui32CurrentToken, psShader); + return pui32CurrentToken; + } + if(psDecl->eOpcode == OPCODE_HS_FORK_PHASE) + { + pui32CurrentToken = DecodeHullShaderForkPhase(pui32CurrentToken, psShader); + return pui32CurrentToken; + } + if(psDecl->eOpcode == OPCODE_HS_JOIN_PHASE) + { + pui32CurrentToken = DecodeHullShaderJoinPhase(pui32CurrentToken, psShader); + return pui32CurrentToken; + } + + psDecl++; + psShader->ui32HSDeclCount++; + + if(pui32CurrentToken >= (psShader->pui32FirstToken + ui32ShaderLength)) + { + break; + } + } + else + { + break; + } + } + + return pui32CurrentToken; +} + +void Decode(const uint32_t* pui32Tokens, Shader* psShader) +{ + const uint32_t* pui32CurrentToken = pui32Tokens; + const uint32_t ui32ShaderLength = pui32Tokens[1]; + Instruction* psInst; + Declaration* psDecl; + + psShader->ui32MajorVersion = DecodeProgramMajorVersion(*pui32CurrentToken); + psShader->ui32MinorVersion = DecodeProgramMinorVersion(*pui32CurrentToken); + psShader->eShaderType = DecodeShaderType(*pui32CurrentToken); + + pui32CurrentToken++;//Move to shader length + psShader->ui32ShaderLength = ui32ShaderLength; + pui32CurrentToken++;//Move to after shader length (usually a declaration) + + psShader->pui32FirstToken = pui32Tokens; + + if(psShader->eShaderType == HULL_SHADER) + { + pui32CurrentToken = DecodeHullShader(pui32CurrentToken, psShader); + return; + } + + //Using ui32ShaderLength as the instruction count + //will allocate more than enough memory. Avoids having to + //traverse the entire shader just to get the real instruction count. + psInst = hlslcc_malloc(sizeof(Instruction) * ui32ShaderLength); + psShader->psInst = psInst; + psShader->ui32InstCount = 0; + + psDecl = hlslcc_malloc(sizeof(Declaration) * ui32ShaderLength); + psShader->psDecl = psDecl; + psShader->ui32DeclCount = 0; + + while(1) //Keep going until we reach the first non-declaration token, or the end of the shader. + { + const uint32_t* pui32Result = DecodeDeclaration(psShader, pui32CurrentToken, psDecl); + + if(pui32Result) + { + pui32CurrentToken = pui32Result; + psShader->ui32DeclCount++; + psDecl++; + + if(pui32CurrentToken >= (psShader->pui32FirstToken + ui32ShaderLength)) + { + break; + } + } + else + { + break; + } + } + + while (pui32CurrentToken < (psShader->pui32FirstToken + ui32ShaderLength)) + { + const uint32_t* nextInstr = DeocdeInstruction(pui32CurrentToken, psInst, psShader); + +#ifdef _DEBUG + if(nextInstr == pui32CurrentToken) + { + ASSERT(0); + break; + } +#endif + + pui32CurrentToken = nextInstr; + psShader->ui32InstCount++; + psInst++; + } +} + +Shader* DecodeDXBC(uint32_t* data) +{ + Shader* psShader; + DXBCContainerHeader* header = (DXBCContainerHeader*)data; + uint32_t i; + uint32_t chunkCount; + uint32_t* chunkOffsets; + ReflectionChunks refChunks; + uint32_t* shaderChunk = 0; + + if(header->fourcc != FOURCC_DXBC) + { + //Could be SM1/2/3. If the shader type token + //looks valid then we continue + uint32_t type = DecodeShaderTypeDX9(data[0]); + + if(type != INVALID_SHADER) + { + return DecodeDX9BC(data); + } + return 0; + } + + refChunks.pui32Inputs = NULL; + refChunks.pui32Interfaces = NULL; + refChunks.pui32Outputs = NULL; + refChunks.pui32Resources = NULL; + refChunks.pui32Inputs11 = NULL; + refChunks.pui32Outputs11 = NULL; + refChunks.pui32OutputsWithStreams = NULL; + + chunkOffsets = (uint32_t*)(header + 1); + + chunkCount = header->chunkCount; + + for(i = 0; i < chunkCount; ++i) + { + uint32_t offset = chunkOffsets[i]; + + DXBCChunkHeader* chunk = (DXBCChunkHeader*)((char*)data + offset); + + switch(chunk->fourcc) + { + case FOURCC_ISGN: + { + refChunks.pui32Inputs = (uint32_t*)(chunk + 1); + break; + } + case FOURCC_ISG1: + { + refChunks.pui32Inputs11 = (uint32_t*)(chunk + 1); + break; + } + case FOURCC_RDEF: + { + refChunks.pui32Resources = (uint32_t*)(chunk + 1); + break; + } + case FOURCC_IFCE: + { + refChunks.pui32Interfaces = (uint32_t*)(chunk + 1); + break; + } + case FOURCC_OSGN: + { + refChunks.pui32Outputs = (uint32_t*)(chunk + 1); + break; + } + case FOURCC_OSG1: + { + refChunks.pui32Outputs11 = (uint32_t*)(chunk + 1); + break; + } + case FOURCC_OSG5: + { + refChunks.pui32OutputsWithStreams = (uint32_t*)(chunk + 1); + break; + } + case FOURCC_SHDR: + case FOURCC_SHEX: + { + shaderChunk = (uint32_t*)(chunk + 1); + break; + } + default: + { + break; + } + } + } + + if(shaderChunk) + { + uint32_t ui32MajorVersion; + uint32_t ui32MinorVersion; + + psShader = hlslcc_calloc(1, sizeof(Shader)); + + ui32MajorVersion = DecodeProgramMajorVersion(*shaderChunk); + ui32MinorVersion = DecodeProgramMinorVersion(*shaderChunk); + + LoadShaderInfo(ui32MajorVersion, + ui32MinorVersion, + &refChunks, + &psShader->sInfo); + + Decode(shaderChunk, psShader); + + return psShader; + } + + return 0; +} + diff --git a/build/tools/HLSLcc/May_2014/src/decodeDX9.c b/build/tools/HLSLcc/May_2014/src/decodeDX9.c new file mode 100644 index 0000000..4106b60 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/decodeDX9.c @@ -0,0 +1,1146 @@ + +#include "internal_includes/tokens.h" +#include "internal_includes/structs.h" +#include "internal_includes/decode.h" +#include "stdlib.h" +#include "stdio.h" +#include "internal_includes/reflect.h" +#include "internal_includes/debug.h" +#include "internal_includes/hlslcc_malloc.h" + +#define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 )) +static enum {FOURCC_CTAB = FOURCC('C', 'T', 'A', 'B')}; //Constant table + +#ifdef _DEBUG +static uint64_t operandID = 0; +static uint64_t instructionID = 0; +#endif + +static uint32_t aui32ImmediateConst[256]; +static uint32_t ui32MaxTemp = 0; + +uint32_t DX9_DECODE_OPERAND_IS_SRC = 0x1; +uint32_t DX9_DECODE_OPERAND_IS_DEST = 0x2; +uint32_t DX9_DECODE_OPERAND_IS_DECL = 0x4; + +uint32_t DX9_DECODE_OPERAND_IS_CONST = 0x8; +uint32_t DX9_DECODE_OPERAND_IS_ICONST = 0x10; +uint32_t DX9_DECODE_OPERAND_IS_BCONST = 0x20; + +#define MAX_INPUTS 64 + +static DECLUSAGE_DX9 aeInputUsage[MAX_INPUTS]; +static uint32_t aui32InputUsageIndex[MAX_INPUTS]; + +static void DecodeOperandDX9(const Shader* psShader, + const uint32_t ui32Token, + const uint32_t ui32Token1, + uint32_t ui32Flags, + Operand *psOperand) +{ + const uint32_t ui32RegNum = DecodeOperandRegisterNumberDX9(ui32Token); + const uint32_t ui32RegType = DecodeOperandTypeDX9(ui32Token); + const uint32_t bRelativeAddr = DecodeOperandIsRelativeAddressModeDX9(ui32Token); + + const uint32_t ui32WriteMask = DecodeDestWriteMaskDX9(ui32Token); + const uint32_t ui32Swizzle = DecodeOperandSwizzleDX9(ui32Token); + + SHADER_VARIABLE_TYPE ConstType; + + psOperand->ui32RegisterNumber = ui32RegNum; + + psOperand->iNumComponents = 4; + +#ifdef _DEBUG + psOperand->id = operandID++; +#endif + + psOperand->iWriteMaskEnabled = 0; + psOperand->iGSInput = 0; + psOperand->iExtended = 0; + psOperand->psSubOperand[0] = 0; + psOperand->psSubOperand[1] = 0; + psOperand->psSubOperand[2] = 0; + + psOperand->iIndexDims = INDEX_0D; + + psOperand->iIntegerImmediate = 0; + + psOperand->pszSpecialName[0] ='\0'; + + + psOperand->eModifier = OPERAND_MODIFIER_NONE; + if(ui32Flags & DX9_DECODE_OPERAND_IS_SRC) + { + uint32_t ui32Modifier = DecodeSrcModifierDX9(ui32Token); + + switch(ui32Modifier) + { + case SRCMOD_DX9_NONE: + { + break; + } + case SRCMOD_DX9_NEG: + { + psOperand->eModifier = OPERAND_MODIFIER_NEG; + break; + } + case SRCMOD_DX9_ABS: + { + psOperand->eModifier = OPERAND_MODIFIER_ABS; + break; + } + case SRCMOD_DX9_ABSNEG: + { + psOperand->eModifier = OPERAND_MODIFIER_ABSNEG; + break; + } + default: + { + ASSERT(0); + break; + } + } + } + + if((ui32Flags & DX9_DECODE_OPERAND_IS_DECL)==0) + { + if(ui32Flags & DX9_DECODE_OPERAND_IS_DEST) + { + if(ui32WriteMask != DX9_WRITEMASK_ALL) + { + psOperand->iWriteMaskEnabled = 1; + psOperand->eSelMode = OPERAND_4_COMPONENT_MASK_MODE; + + if(ui32WriteMask & DX9_WRITEMASK_0) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_X; + } + if(ui32WriteMask & DX9_WRITEMASK_1) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_Y; + } + if(ui32WriteMask & DX9_WRITEMASK_2) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_Z; + } + if(ui32WriteMask & DX9_WRITEMASK_3) + { + psOperand->ui32CompMask |= OPERAND_4_COMPONENT_MASK_W; + } + } + } + else + if(ui32Swizzle != NO_SWIZZLE_DX9) + { + uint32_t component; + + psOperand->iWriteMaskEnabled = 1; + psOperand->eSelMode = OPERAND_4_COMPONENT_SWIZZLE_MODE; + + psOperand->ui32Swizzle = 1; + + /* Add the swizzle */ + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(0)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_X; + } + else + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(1)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_Y; + } + else + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(2)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_Z; + } + else + if(ui32Swizzle == REPLICATE_SWIZZLE_DX9(3)) + { + psOperand->eSelMode = OPERAND_4_COMPONENT_SELECT_1_MODE; + psOperand->aui32Swizzle[0] = OPERAND_4_COMPONENT_W; + } + else + { + for (component = 0; component < 4; component++) + { + uint32_t ui32CompSwiz = + ui32Swizzle & (3 << (DX9_SWIZZLE_SHIFT+(component*2))); + ui32CompSwiz >>= (DX9_SWIZZLE_SHIFT+(component*2)); + + if (ui32CompSwiz == 0) + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_X; + } + else if (ui32CompSwiz == 1) + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_Y; + } + else if (ui32CompSwiz == 2) + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_Z; + } + else + { + psOperand->aui32Swizzle[component] = OPERAND_4_COMPONENT_W; + } + } + } + } + + if(bRelativeAddr) + { + psOperand->psSubOperand[0] = hlslcc_malloc(sizeof(Operand)); + DecodeOperandDX9(psShader, ui32Token1, 0, ui32Flags, psOperand->psSubOperand[0]); + + psOperand->iIndexDims = INDEX_1D; + + psOperand->eIndexRep[0] = OPERAND_INDEX_RELATIVE; + + psOperand->aui32ArraySizes[0] = 0; + } + } + + if(ui32RegType == OPERAND_TYPE_DX9_CONSTBOOL) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_BCONST; + ConstType = SVT_BOOL; + } + else if(ui32RegType == OPERAND_TYPE_DX9_CONSTINT) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_ICONST; + ConstType = SVT_INT; + } + else if(ui32RegType == OPERAND_TYPE_DX9_CONST) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_CONST; + ConstType = SVT_FLOAT; + } + + switch(ui32RegType) + { + case OPERAND_TYPE_DX9_TEMP: + { + psOperand->eType = OPERAND_TYPE_TEMP; + + if(ui32MaxTemp < ui32RegNum+1) + { + ui32MaxTemp = ui32RegNum+1; + } + break; + } + case OPERAND_TYPE_DX9_INPUT: + { + psOperand->eType = OPERAND_TYPE_INPUT; + + ASSERT(ui32RegNum < MAX_INPUTS); + + if(psShader->eShaderType == PIXEL_SHADER) + { + if(aeInputUsage[ui32RegNum] == DECLUSAGE_TEXCOORD) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_TEXCOORD; + psOperand->ui32RegisterNumber = aui32InputUsageIndex[ui32RegNum]; + } + else + //0 = base colour, 1 = offset colour. + if(ui32RegNum == 0) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTBASECOLOUR; + } + else + { + ASSERT(ui32RegNum == 1); + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR; + } + } + break; + } + //Same value as OPERAND_TYPE_DX9_TEXCRDOUT + //OPERAND_TYPE_DX9_TEXCRDOUT is the pre-SM3 equivalent + case OPERAND_TYPE_DX9_OUTPUT: + { + psOperand->eType = OPERAND_TYPE_OUTPUT; + + if(psShader->eShaderType == VERTEX_SHADER) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_TEXCOORD; + } + break; + } + case OPERAND_TYPE_DX9_RASTOUT: + { + //RegNum: + //0=POSIION + //1=FOG + //2=POINTSIZE + psOperand->eType = OPERAND_TYPE_OUTPUT; + switch(ui32RegNum) + { + case 0: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_POSITION; + break; + } + case 1: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_FOG; + break; + } + case 2: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_POINTSIZE; + psOperand->iNumComponents = 1; + break; + } + } + break; + } + case OPERAND_TYPE_DX9_ATTROUT: + { + ASSERT(psShader->eShaderType == VERTEX_SHADER); + + psOperand->eType = OPERAND_TYPE_OUTPUT; + + //0 = base colour, 1 = offset colour. + if(ui32RegNum == 0) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTBASECOLOUR; + } + else + { + ASSERT(ui32RegNum == 1); + psOperand->eType = OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR; + } + + break; + } + case OPERAND_TYPE_DX9_COLOROUT: + { + ASSERT(psShader->eShaderType == PIXEL_SHADER); + psOperand->eType = OPERAND_TYPE_OUTPUT; + break; + } + case OPERAND_TYPE_DX9_CONSTBOOL: + case OPERAND_TYPE_DX9_CONSTINT: + case OPERAND_TYPE_DX9_CONST: + { + //c# = constant float + //i# = constant int + //b# = constant bool + + //c0 might be an immediate while i0 is in the constant buffer + if(aui32ImmediateConst[ui32RegNum] & ui32Flags) + { + if(ConstType != SVT_FLOAT) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_IMMCONSTINT; + } + else + { + psOperand->eType = OPERAND_TYPE_SPECIAL_IMMCONST; + } + } + else + { + psOperand->eType = OPERAND_TYPE_CONSTANT_BUFFER; + psOperand->aui32ArraySizes[1] = psOperand->ui32RegisterNumber; + } + break; + } + case OPERAND_TYPE_DX9_ADDR: + { + //Vertex shader: address register (only have one of these) + //Pixel shader: texture coordinate register (a few of these) + if(psShader->eShaderType == PIXEL_SHADER) + { + psOperand->eType = OPERAND_TYPE_SPECIAL_TEXCOORD; + } + else + { + psOperand->eType = OPERAND_TYPE_SPECIAL_ADDRESS; + } + break; + } + case OPERAND_TYPE_DX9_SAMPLER: + { + psOperand->eType = OPERAND_TYPE_RESOURCE; + break; + } + case OPERAND_TYPE_DX9_LOOP: + { + psOperand->eType = OPERAND_TYPE_SPECIAL_LOOPCOUNTER; + break; + } + default: + { + ASSERT(0); + break; + } + } +} + +static void DeclareNumTemps(Shader* psShader, + const uint32_t ui32NumTemps, + Declaration* psDecl) +{ + psDecl->eOpcode = OPCODE_DCL_TEMPS; + psDecl->value.ui32NumTemps = ui32NumTemps; +} + +static void SetupRegisterUsage(const Shader* psShader, + const uint32_t ui32Token0, + const uint32_t ui32Token1) +{ + DECLUSAGE_DX9 eUsage = DecodeUsageDX9(ui32Token0); + uint32_t ui32UsageIndex = DecodeUsageIndexDX9(ui32Token0); + uint32_t ui32RegNum = DecodeOperandRegisterNumberDX9(ui32Token1); + uint32_t ui32RegType = DecodeOperandTypeDX9(ui32Token1); + + if(ui32RegType == OPERAND_TYPE_DX9_INPUT) + { + ASSERT(ui32RegNum < MAX_INPUTS); + aeInputUsage[ui32RegNum] = eUsage; + aui32InputUsageIndex[ui32RegNum] = ui32UsageIndex; + } +} + +//Declaring one constant from a constant buffer will cause all constants in the buffer decalared. +//In dx9 there is only one constant buffer per shader. +static void DeclareConstantBuffer(const Shader* psShader, + Declaration* psDecl) +{ + DECLUSAGE_DX9 eUsage = (DECLUSAGE_DX9)0; + uint32_t ui32UsageIndex = 0; + //Pick any constant register in the table. Might not start at c0 (e.g. when register(cX) is used). + uint32_t ui32RegNum = psShader->sInfo.psConstantBuffers->asVars[0].ui32StartOffset / 16; + OPERAND_TYPE_DX9 ui32RegType = OPERAND_TYPE_DX9_CONST; + + if(psShader->sInfo.psConstantBuffers->asVars[0].sType.Type == SVT_INT) + { + ui32RegType = OPERAND_TYPE_DX9_CONSTINT; + } + else if(psShader->sInfo.psConstantBuffers->asVars[0].sType.Type == SVT_BOOL) + { + ui32RegType = OPERAND_TYPE_DX9_CONSTBOOL; + } + + if(psShader->eShaderType == VERTEX_SHADER) + { + psDecl->eOpcode = OPCODE_DCL_INPUT; + } + else + { + psDecl->eOpcode = OPCODE_DCL_INPUT_PS; + } + psDecl->ui32NumOperands = 1; + + DecodeOperandDX9(psShader, CreateOperandTokenDX9(ui32RegNum, ui32RegType), 0, DX9_DECODE_OPERAND_IS_DECL, &psDecl->asOperands[0]); + + ASSERT(psDecl->asOperands[0].eType == OPERAND_TYPE_CONSTANT_BUFFER); + + psDecl->eOpcode = OPCODE_DCL_CONSTANT_BUFFER; + + ASSERT(psShader->sInfo.ui32NumConstantBuffers); + + psDecl->asOperands[0].aui32ArraySizes[0] = 0;//Const buffer index + psDecl->asOperands[0].aui32ArraySizes[1] = psShader->sInfo.psConstantBuffers[0].ui32TotalSizeInBytes / 16;//Number of vec4 constants. +} + +static void DecodeDeclarationDX9(const Shader* psShader, + const uint32_t ui32Token0, + const uint32_t ui32Token1, + Declaration* psDecl) +{ + DECLUSAGE_DX9 eUsage = DecodeUsageDX9(ui32Token0); + uint32_t ui32UsageIndex = DecodeUsageIndexDX9(ui32Token0); + uint32_t ui32RegNum = DecodeOperandRegisterNumberDX9(ui32Token1); + uint32_t ui32RegType = DecodeOperandTypeDX9(ui32Token1); + + if(psShader->eShaderType == VERTEX_SHADER) + { + psDecl->eOpcode = OPCODE_DCL_INPUT; + } + else + { + psDecl->eOpcode = OPCODE_DCL_INPUT_PS; + } + psDecl->ui32NumOperands = 1; + DecodeOperandDX9(psShader, ui32Token1, 0, DX9_DECODE_OPERAND_IS_DECL, &psDecl->asOperands[0]); + + if(ui32RegType == OPERAND_TYPE_DX9_SAMPLER) + { + const RESOURCE_DIMENSION eResDim = DecodeTextureTypeMaskDX9(ui32Token0); + psDecl->value.eResourceDimension = eResDim; + psDecl->ui32IsShadowTex = 0; + psDecl->eOpcode = OPCODE_DCL_RESOURCE; + } + + if(psDecl->asOperands[0].eType == OPERAND_TYPE_OUTPUT) + { + psDecl->eOpcode = OPCODE_DCL_OUTPUT; + + if(psDecl->asOperands[0].ui32RegisterNumber==0 && psShader->eShaderType == VERTEX_SHADER) + { + psDecl->eOpcode = OPCODE_DCL_OUTPUT_SIV; + //gl_Position + psDecl->asOperands[0].eSpecialName = NAME_POSITION; + } + } + else + if(psDecl->asOperands[0].eType == OPERAND_TYPE_CONSTANT_BUFFER) + { + psDecl->eOpcode = OPCODE_DCL_CONSTANT_BUFFER; + + ASSERT(psShader->sInfo.ui32NumConstantBuffers); + + psDecl->asOperands[0].aui32ArraySizes[0] = 0;//Const buffer index + psDecl->asOperands[0].aui32ArraySizes[1] = psShader->sInfo.psConstantBuffers[0].ui32TotalSizeInBytes / 16;//Number of vec4 constants. + } +} + +static void DefineDX9(Shader* psShader, + const uint32_t ui32RegNum, + const uint32_t ui32Flags, + const uint32_t c0, + const uint32_t c1, + const uint32_t c2, + const uint32_t c3, + Declaration* psDecl) +{ + psDecl->eOpcode = OPCODE_SPECIAL_DCL_IMMCONST; + psDecl->ui32NumOperands = 2; + + memset(&psDecl->asOperands[0], 0, sizeof(Operand)); + psDecl->asOperands[0].eType = OPERAND_TYPE_SPECIAL_IMMCONST; + + psDecl->asOperands[0].ui32RegisterNumber = ui32RegNum; + + if(ui32Flags & (DX9_DECODE_OPERAND_IS_ICONST|DX9_DECODE_OPERAND_IS_BCONST)) + { + psDecl->asOperands[0].eType = OPERAND_TYPE_SPECIAL_IMMCONSTINT; + } + + aui32ImmediateConst[ui32RegNum] |= ui32Flags; + + memset(&psDecl->asOperands[1], 0, sizeof(Operand)); + psDecl->asOperands[1].eType = OPERAND_TYPE_IMMEDIATE32; + psDecl->asOperands[1].iNumComponents = 4; + psDecl->asOperands[1].iIntegerImmediate = (ui32Flags & (DX9_DECODE_OPERAND_IS_ICONST|DX9_DECODE_OPERAND_IS_BCONST)) ? 1 : 0; + psDecl->asOperands[1].afImmediates[0] = *((float*)&c0); + psDecl->asOperands[1].afImmediates[1] = *((float*)&c1); + psDecl->asOperands[1].afImmediates[2] = *((float*)&c2); + psDecl->asOperands[1].afImmediates[3] = *((float*)&c3); +} + +static void CreateD3D10Instruction( + Shader* psShader, + Instruction* psInst, + const OPCODE_TYPE eType, + const uint32_t bHasDest, + const uint32_t ui32SrcCount, + const uint32_t* pui32Tokens) +{ + uint32_t ui32Src; + uint32_t ui32Offset = 1; + + memset(psInst, 0, sizeof(Instruction)); + +#ifdef _DEBUG + psInst->id = instructionID++; +#endif + + psInst->eOpcode = eType; + psInst->ui32NumOperands = ui32SrcCount; + + if(bHasDest) + { + ++psInst->ui32NumOperands; + + DecodeOperandDX9(psShader, + pui32Tokens[ui32Offset], + pui32Tokens[ui32Offset+1], + DX9_DECODE_OPERAND_IS_DEST, + &psInst->asOperands[0]); + + if(DecodeDestModifierDX9(pui32Tokens[ui32Offset]) & DESTMOD_DX9_SATURATE) + { + psInst->bSaturate = 1; + } + + ui32Offset++; + psInst->ui32FirstSrc = 1; + } + + for(ui32Src=0; ui32Src < ui32SrcCount; ++ui32Src) + { + DecodeOperandDX9(psShader, + pui32Tokens[ui32Offset], + pui32Tokens[ui32Offset+1], + DX9_DECODE_OPERAND_IS_SRC, + &psInst->asOperands[bHasDest+ui32Src]); + + ui32Offset++; + } +} + +Shader* DecodeDX9BC(const uint32_t* pui32Tokens) +{ + const uint32_t* pui32CurrentToken = pui32Tokens; + uint32_t ui32NumInstructions = 0; + uint32_t ui32NumDeclarations = 0; + Instruction* psInst; + Declaration* psDecl; + uint32_t decl, inst; + uint32_t bDeclareConstantTable = 0; + Shader* psShader = hlslcc_calloc(1, sizeof(Shader)); + + memset(aui32ImmediateConst, 0, 256); + + psShader->ui32MajorVersion = DecodeProgramMajorVersionDX9(*pui32CurrentToken); + psShader->ui32MinorVersion = DecodeProgramMinorVersionDX9(*pui32CurrentToken); + psShader->eShaderType = DecodeShaderTypeDX9(*pui32CurrentToken); + + pui32CurrentToken++; + + //Work out how many instructions and declarations we need to allocate memory for. + while (1) + { + OPCODE_TYPE_DX9 eOpcode = DecodeOpcodeTypeDX9(pui32CurrentToken[0]); + uint32_t ui32InstLen = DecodeInstructionLengthDX9(pui32CurrentToken[0]); + + if(eOpcode == OPCODE_DX9_END) + { + //SM4+ always end with RET. + //Insert a RET instruction on END to + //replicate this behaviour. + ++ui32NumInstructions; + break; + } + else if(eOpcode == OPCODE_DX9_COMMENT) + { + ui32InstLen = DecodeCommentLengthDX9(pui32CurrentToken[0]); + if(pui32CurrentToken[1] == FOURCC_CTAB) + { + LoadD3D9ConstantTable((char*)(&pui32CurrentToken[2]), &psShader->sInfo); + + ASSERT(psShader->sInfo.ui32NumConstantBuffers); + + if(psShader->sInfo.psConstantBuffers[0].ui32NumVars) + { + ++ui32NumDeclarations; + bDeclareConstantTable = 1; + } + } + } + else if((eOpcode == OPCODE_DX9_DEF)||(eOpcode == OPCODE_DX9_DEFI)||(eOpcode == OPCODE_DX9_DEFB)) + { + ++ui32NumDeclarations; + } + else if(eOpcode == OPCODE_DX9_DCL) + { + const OPERAND_TYPE_DX9 eType = DecodeOperandTypeDX9(pui32CurrentToken[2]); + uint32_t ignoreDCL = 0; + + //Inputs and outputs are declared in AddVersionDependentCode + if(psShader->eShaderType == PIXEL_SHADER && (OPERAND_TYPE_DX9_CONST != eType && OPERAND_TYPE_DX9_SAMPLER != eType)) + { + ignoreDCL = 1; + } + if(!ignoreDCL) + { + ++ui32NumDeclarations; + } + } + else + { + switch(eOpcode) + { + case OPCODE_DX9_NRM: + { + //Emulate with dp4 and rsq + ui32NumInstructions += 2; + break; + } + default: + { + ++ui32NumInstructions; + break; + } + } + } + + pui32CurrentToken += ui32InstLen + 1; + } + + psInst = hlslcc_malloc(sizeof(Instruction) * ui32NumInstructions); + psShader->psInst = psInst; + psShader->ui32InstCount = ui32NumInstructions; + + if(psShader->eShaderType == VERTEX_SHADER) + { + //Declare gl_Position. vs_3_0 does declare it, SM1/2 do not + ui32NumDeclarations++; + } + + //For declaring temps. + ui32NumDeclarations++; + + psDecl = hlslcc_malloc(sizeof(Declaration) * ui32NumDeclarations); + psShader->psDecl = psDecl; + psShader->ui32DeclCount = ui32NumDeclarations; + + pui32CurrentToken = pui32Tokens + 1; + + inst=0; + decl=0; + while (1) + { + OPCODE_TYPE_DX9 eOpcode = DecodeOpcodeTypeDX9(pui32CurrentToken[0]); + uint32_t ui32InstLen = DecodeInstructionLengthDX9(pui32CurrentToken[0]); + + if(eOpcode == OPCODE_DX9_END) + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RET, 0, 0, pui32CurrentToken); + inst++; + break; + } + else if(eOpcode == OPCODE_DX9_COMMENT) + { + ui32InstLen = DecodeCommentLengthDX9(pui32CurrentToken[0]); + } + else if(eOpcode == OPCODE_DX9_DCL) + { + const OPERAND_TYPE_DX9 eType = DecodeOperandTypeDX9(pui32CurrentToken[2]); + uint32_t ignoreDCL = 0; + //Inputs and outputs are declared in AddVersionDependentCode + if(psShader->eShaderType == PIXEL_SHADER && (OPERAND_TYPE_DX9_CONST != eType && OPERAND_TYPE_DX9_SAMPLER != eType)) + { + ignoreDCL = 1; + } + + SetupRegisterUsage(psShader, pui32CurrentToken[1], pui32CurrentToken[2]); + + if(!ignoreDCL) + { + DecodeDeclarationDX9(psShader, pui32CurrentToken[1], pui32CurrentToken[2], &psDecl[decl]); + decl++; + } + } + else if((eOpcode == OPCODE_DX9_DEF)||(eOpcode == OPCODE_DX9_DEFI)||(eOpcode == OPCODE_DX9_DEFB)) + { + const uint32_t ui32Const0 = *(pui32CurrentToken+2); + const uint32_t ui32Const1 = *(pui32CurrentToken+3); + const uint32_t ui32Const2 = *(pui32CurrentToken+4); + const uint32_t ui32Const3 = *(pui32CurrentToken+5); + uint32_t ui32Flags = 0; + + if(eOpcode == OPCODE_DX9_DEF) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_CONST; + } + else if(eOpcode == OPCODE_DX9_DEFI) + { + ui32Flags |= DX9_DECODE_OPERAND_IS_ICONST; + } + else + { + ui32Flags |= DX9_DECODE_OPERAND_IS_BCONST; + } + + + DefineDX9(psShader, + DecodeOperandRegisterNumberDX9(pui32CurrentToken[1]), + ui32Flags, + ui32Const0, + ui32Const1, + ui32Const2, + ui32Const3, + &psDecl[decl]); + decl++; + } + else + { + switch(eOpcode) + { + case OPCODE_DX9_MOV: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MOV, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_LIT: + { + /*Dest.x = 1 + Dest.y = (Src0.x > 0) ? Src0.x : 0 + Dest.z = (Src0.x > 0 && Src0.y > 0) ? pow(Src0.y, Src0.w) : 0 + Dest.w = 1 + */ + ASSERT(0); + break; + } + case OPCODE_DX9_ADD: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ADD, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_SUB: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ADD, 1, 2, pui32CurrentToken); + ASSERT(psInst[inst].asOperands[2].eModifier == OPERAND_MODIFIER_NONE); + psInst[inst].asOperands[2].eModifier = OPERAND_MODIFIER_NEG; + break; + } + case OPCODE_DX9_MAD: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MAD, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_MUL: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MUL, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_RCP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RCP, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_RSQ: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RSQ, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_DP3: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP3, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_DP4: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP4, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_MIN: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MIN, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_MAX: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MAX, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_SLT: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LT, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_SGE: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_GE, 1, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_EXP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_EXP, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_LOG: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LOG, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_NRM: + { + //Convert NRM RESULT, SRCA into: + //dp4 RESULT, SRCA, SRCA + //rsq RESULT, RESULT + + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP4, 1, 1, pui32CurrentToken); + memcpy(&psInst[inst].asOperands[2],&psInst[inst].asOperands[1], sizeof(Operand)); + ++inst; + + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RSQ, 0, 0, pui32CurrentToken); + memcpy(&psInst[inst].asOperands[0],&psInst[inst-1].asOperands[0], sizeof(Operand)); + break; + } + case OPCODE_DX9_SINCOS: + { + //Before SM3, SINCOS has 2 extra constant sources -D3DSINCOSCONST1 and D3DSINCOSCONST2. + //Ignore them. + + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SINCOS, 1, 1, pui32CurrentToken); + //Pre-SM4: + //If the write mask is .x: dest.x = cos( V ) + //If the write mask is .y: dest.y = sin( V ) + //If the write mask is .xy: + //dest.x = cos( V ) + //dest.y = sin( V ) + + //SM4+ + //destSin destCos Angle + + psInst[inst].ui32NumOperands = 3; + + //Set the angle + memcpy(&psInst[inst].asOperands[2],&psInst[inst].asOperands[1], sizeof(Operand)); + + //Set the cosine dest + memcpy(&psInst[inst].asOperands[1],&psInst[inst].asOperands[0], sizeof(Operand)); + + //Set write masks + psInst[inst].asOperands[0].ui32CompMask &= ~OPERAND_4_COMPONENT_MASK_Y; + if(psInst[inst].asOperands[0].ui32CompMask & OPERAND_4_COMPONENT_MASK_X) + { + //Need cosine + } + else + { + psInst[inst].asOperands[0].eType = OPERAND_TYPE_NULL; + } + psInst[inst].asOperands[1].ui32CompMask &= ~OPERAND_4_COMPONENT_MASK_X; + if(psInst[inst].asOperands[1].ui32CompMask & OPERAND_4_COMPONENT_MASK_Y) + { + //Need sine + } + else + { + psInst[inst].asOperands[1].eType = OPERAND_TYPE_NULL; + } + + break; + } + case OPCODE_DX9_FRC: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_FRC, 1, 1, pui32CurrentToken); + break; + } + + case OPCODE_DX9_MOVA: + { + //MOVA preforms RoundToNearest on the src data. + //The only rounding functions available in all GLSL version are ceil and floor. + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ROUND_NI, 1, 1, pui32CurrentToken); + break; + } + + case OPCODE_DX9_TEX: + { + //texld r0, t0, s0 + // srcAddress[.swizzle], srcResource[.swizzle], srcSampler + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SAMPLE, 1, 2, pui32CurrentToken); + psInst[inst].asOperands[2].ui32RegisterNumber = 0; + + + break; + } + case OPCODE_DX9_TEXLDL: + { + //texld r0, t0, s0 + // srcAddress[.swizzle], srcResource[.swizzle], srcSampler + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SAMPLE_L, 1, 2, pui32CurrentToken); + psInst[inst].asOperands[2].ui32RegisterNumber = 0; + + //Lod comes from fourth coordinate of address. + memcpy(&psInst[inst].asOperands[4], &psInst[inst].asOperands[1], sizeof(Operand)); + + psInst[inst].ui32NumOperands = 5; + + break; + } + + case OPCODE_DX9_IF: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_IF, 0, 1, pui32CurrentToken); + psInst[inst].eDX9TestType = D3DSPC_BOOLEAN; + break; + } + + case OPCODE_DX9_IFC: + { + const COMPARISON_DX9 eCmpOp = DecodeComparisonDX9(pui32CurrentToken[0]); + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_IF, 0, 2, pui32CurrentToken); + psInst[inst].eDX9TestType = eCmpOp; + break; + } + case OPCODE_DX9_ELSE: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ELSE, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_CMP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_MOVC, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_REP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_REP, 0, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_ENDREP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ENDREP, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_BREAKC: + { + const COMPARISON_DX9 eCmpOp = DecodeComparisonDX9(pui32CurrentToken[0]); + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_BREAKC, 0, 2, pui32CurrentToken); + psInst[inst].eDX9TestType = eCmpOp; + break; + } + + case OPCODE_DX9_DSX: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DERIV_RTX, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_DSY: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DERIV_RTY, 1, 1, pui32CurrentToken); + break; + } + case OPCODE_DX9_TEXKILL: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DISCARD, 1, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_TEXLDD: + { + // texldd, dst, src0, src1, src2, src3 + // srcAddress[.swizzle], srcResource[.swizzle], srcSampler, XGradient, YGradient + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_SAMPLE_D, 1, 4, pui32CurrentToken); + psInst[inst].asOperands[2].ui32RegisterNumber = 0; + break; + } + case OPCODE_DX9_LRP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LRP, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_DP2ADD: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_DP2ADD, 1, 3, pui32CurrentToken); + break; + } + case OPCODE_DX9_POW: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_POW, 1, 2, pui32CurrentToken); + break; + } + + case OPCODE_DX9_DST: + case OPCODE_DX9_M4x4: + case OPCODE_DX9_M4x3: + case OPCODE_DX9_M3x4: + case OPCODE_DX9_M3x3: + case OPCODE_DX9_M3x2: + case OPCODE_DX9_CALL: + case OPCODE_DX9_CALLNZ: + case OPCODE_DX9_LABEL: + + case OPCODE_DX9_CRS: + case OPCODE_DX9_SGN: + case OPCODE_DX9_ABS: + + case OPCODE_DX9_TEXCOORD: + case OPCODE_DX9_TEXBEM: + case OPCODE_DX9_TEXBEML: + case OPCODE_DX9_TEXREG2AR: + case OPCODE_DX9_TEXREG2GB: + case OPCODE_DX9_TEXM3x2PAD: + case OPCODE_DX9_TEXM3x2TEX: + case OPCODE_DX9_TEXM3x3PAD: + case OPCODE_DX9_TEXM3x3TEX: + case OPCODE_DX9_TEXM3x3SPEC: + case OPCODE_DX9_TEXM3x3VSPEC: + case OPCODE_DX9_EXPP: + case OPCODE_DX9_LOGP: + case OPCODE_DX9_CND: + case OPCODE_DX9_TEXREG2RGB: + case OPCODE_DX9_TEXDP3TEX: + case OPCODE_DX9_TEXM3x2DEPTH: + case OPCODE_DX9_TEXDP3: + case OPCODE_DX9_TEXM3x3: + case OPCODE_DX9_TEXDEPTH: + case OPCODE_DX9_BEM: + case OPCODE_DX9_SETP: + case OPCODE_DX9_BREAKP: + { + ASSERT(0); + break; + } + case OPCODE_DX9_NOP: + case OPCODE_DX9_PHASE: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_NOP, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_LOOP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_LOOP, 0, 2, pui32CurrentToken); + break; + } + case OPCODE_DX9_RET: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_RET, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_ENDLOOP: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ENDLOOP, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_ENDIF: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_ENDIF, 0, 0, pui32CurrentToken); + break; + } + case OPCODE_DX9_BREAK: + { + CreateD3D10Instruction(psShader, &psInst[inst], OPCODE_BREAK, 0, 0, pui32CurrentToken); + break; + } + default: + { + ASSERT(0); + break; + } + } + + UpdateOperandReferences(psShader, &psInst[inst]); + + inst++; + } + + pui32CurrentToken += ui32InstLen + 1; + } + + DeclareNumTemps(psShader, ui32MaxTemp, &psDecl[decl]); + ++decl; + + if(psShader->eShaderType == VERTEX_SHADER) + { + //Declare gl_Position. vs_3_0 does declare it, SM1/2 do not + if(bDeclareConstantTable) + { + DecodeDeclarationDX9(psShader, 0, CreateOperandTokenDX9(0, OPERAND_TYPE_DX9_RASTOUT), &psDecl[decl+1]); + } + else + { + DecodeDeclarationDX9(psShader, 0, CreateOperandTokenDX9(0, OPERAND_TYPE_DX9_RASTOUT), &psDecl[decl]); + } + } + + if(bDeclareConstantTable) + { + DeclareConstantBuffer(psShader, &psDecl[decl]); + } + + return psShader; +} diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/debug.h b/build/tools/HLSLcc/May_2014/src/internal_includes/debug.h new file mode 100644 index 0000000..759f4f0 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/debug.h @@ -0,0 +1,18 @@ +#ifndef DEBUG_H_ +#define DEBUG_H_ + +#ifdef _DEBUG +#include "assert.h" +#define ASSERT(expr) CustomAssert(expr) +static void CustomAssert(int expression) +{ + if(!expression) + { + assert(0); + } +} +#else +#define ASSERT(expr) +#endif + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/decode.h b/build/tools/HLSLcc/May_2014/src/internal_includes/decode.h new file mode 100644 index 0000000..e43c84c --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/decode.h @@ -0,0 +1,15 @@ +#ifndef DECODE_H +#define DECODE_H + +#include "internal_includes/structs.h" + +Shader* DecodeDXBC(uint32_t* data); + +//You don't need to call this directly because DecodeDXBC +//will call DecodeDX9BC if the shader looks +//like it is SM1/2/3. +Shader* DecodeDX9BC(const uint32_t* pui32Tokens); + +void UpdateOperandReferences(Shader* psShader, Instruction* psInst); + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.c b/build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.c new file mode 100644 index 0000000..71ddeac --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.c @@ -0,0 +1,6 @@ +#include + +void* (*hlslcc_malloc)(size_t size) = malloc; +void* (*hlslcc_calloc)(size_t num,size_t size) = calloc; +void (*hlslcc_free)(void *p) = free; +void* (*hlslcc_realloc)(void *p,size_t size) = realloc; \ No newline at end of file diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.h b/build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.h new file mode 100644 index 0000000..aa67402 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/hlslcc_malloc.h @@ -0,0 +1,12 @@ +#ifndef __HLSCC_MALLOC_H +#define __HLSCC_MALLOC_H + +extern void* (*hlslcc_malloc)(size_t size); +extern void* (*hlslcc_calloc)(size_t num,size_t size); +extern void (*hlslcc_free)(void *p); +extern void* (*hlslcc_realloc)(void *p,size_t size); + +#define bstr__alloc hlslcc_malloc +#define bstr__free hlslcc_free +#define bstr__realloc hlslcc_realloc +#endif \ No newline at end of file diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/languages.h b/build/tools/HLSLcc/May_2014/src/internal_includes/languages.h new file mode 100644 index 0000000..e564767 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/languages.h @@ -0,0 +1,202 @@ +#ifndef LANGUAGES_H +#define LANGUAGES_H + +#include "hlslcc.h" + +static int InOutSupported(const GLLang eLang) +{ + if(eLang == LANG_ES_100 || eLang == LANG_120) + { + return 0; + } + return 1; +} + +static int WriteToFragData(const GLLang eLang) +{ + if(eLang == LANG_ES_100 || eLang == LANG_120) + { + return 1; + } + return 0; +} + +static int ShaderBitEncodingSupported(const GLLang eLang) +{ + if( eLang != LANG_ES_300 && + eLang != LANG_ES_310 && + eLang < LANG_330) + { + return 0; + } + return 1; +} + +static int HaveOverloadedTextureFuncs(const GLLang eLang) +{ + if(eLang == LANG_ES_100 || eLang == LANG_120) + { + return 0; + } + return 1; +} + +//Only enable for ES. +//Not present in 120, ignored in other desktop languages. +static int HavePrecisionQualifers(const GLLang eLang) +{ + if(eLang >= LANG_ES_100 && eLang <= LANG_ES_310) + { + return 1; + } + return 0; +} + +//Only on vertex inputs and pixel outputs. +static int HaveLimitedInOutLocationQualifier(const GLLang eLang) +{ + if(eLang >= LANG_330 || eLang == LANG_ES_300 || eLang == LANG_ES_310) + { + return 1; + } + return 0; +} + +static int HaveInOutLocationQualifier(const GLLang eLang,const struct GlExtensions *extensions) +{ + if(eLang >= LANG_410 || eLang == LANG_ES_310 || (extensions && ((GlExtensions*)extensions)->ARB_explicit_attrib_location)) + { + return 1; + } + return 0; +} + +//layout(binding = X) uniform {uniformA; uniformB;} +//layout(location = X) uniform uniform_name; +static int HaveUniformBindingsAndLocations(const GLLang eLang,const struct GlExtensions *extensions) +{ + if(eLang >= LANG_430 || eLang == LANG_ES_310 || (extensions && ((GlExtensions*)extensions)->ARB_explicit_uniform_location)) + { + return 1; + } + return 0; +} + +static int DualSourceBlendSupported(const GLLang eLang) +{ + if(eLang >= LANG_330) + { + return 1; + } + return 0; +} + +static int SubroutinesSupported(const GLLang eLang) +{ + if(eLang >= LANG_400) + { + return 1; + } + return 0; +} + +//Before 430, flat/smooth/centroid/noperspective must match +//between fragment and its previous stage. +//HLSL bytecode only tells us the interpolation in pixel shader. +static int PixelInterpDependency(const GLLang eLang) +{ + if(eLang < LANG_430) + { + return 1; + } + return 0; +} + +static int HaveUVec(const GLLang eLang) +{ + switch(eLang) + { + case LANG_ES_100: + case LANG_120: + return 0; + default: + break; + } + return 1; +} + +static int HaveGather(const GLLang eLang) +{ + if(eLang >= LANG_400 || eLang == LANG_ES_310) + { + return 1; + } + return 0; +} + +static int HaveGatherNonConstOffset(const GLLang eLang) +{ + if(eLang >= LANG_420 || eLang == LANG_ES_310) + { + return 1; + } + return 0; +} + + +static int HaveQueryLod(const GLLang eLang) +{ + if(eLang >= LANG_400) + { + return 1; + } + return 0; +} + +static int HaveQueryLevels(const GLLang eLang) +{ + if(eLang >= LANG_430) + { + return 1; + } + return 0; +} + + +static int HaveAtomicCounter(const GLLang eLang) +{ + if(eLang >= LANG_420 || eLang == LANG_ES_310) + { + return 1; + } + return 0; +} + +static int HaveAtomicMem(const GLLang eLang) +{ + if(eLang >= LANG_430) + { + return 1; + } + return 0; +} + +static int HaveCompute(const GLLang eLang) +{ + if(eLang >= LANG_430 || eLang == LANG_ES_310) + { + return 1; + } + return 0; +} + +static int HaveImageLoadStore(const GLLang eLang) +{ + if(eLang >= LANG_420 || eLang == LANG_ES_310) + { + return 1; + } + return 0; +} + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/reflect.h b/build/tools/HLSLcc/May_2014/src/internal_includes/reflect.h new file mode 100644 index 0000000..db93a31 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/reflect.h @@ -0,0 +1,67 @@ +#ifndef REFLECT_H +#define REFLECT_H + +#include "hlslcc.h" + +ResourceGroup ResourceTypeToResourceGroup(ResourceType); + +int GetResourceFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ShaderInfo* psShaderInfo, ResourceBinding** ppsOutBinding); + +void GetConstantBufferFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ShaderInfo* psShaderInfo, ConstantBuffer** ppsConstBuf); + +int GetInterfaceVarFromOffset(uint32_t ui32Offset, ShaderInfo* psShaderInfo, ShaderVar** ppsShaderVar); + +int GetInputSignatureFromRegister(const uint32_t ui32Register, const ShaderInfo* psShaderInfo, InOutSignature** ppsOut); +int GetOutputSignatureFromRegister(const uint32_t ui32Register, + const uint32_t ui32Stream, + const uint32_t ui32CompMask, + ShaderInfo* psShaderInfo, + InOutSignature** ppsOut); + +int GetOutputSignatureFromSystemValue(SPECIAL_NAME eSystemValueType, uint32_t ui32SemanticIndex, ShaderInfo* psShaderInfo, InOutSignature** ppsOut); + +int GetShaderVarFromOffset(const uint32_t ui32Vec4Offset, + const uint32_t* pui32Swizzle, + ConstantBuffer* psCBuf, + ShaderVarType** ppsShaderVar, + int32_t* pi32Index, + int32_t* pi32Rebase); + +typedef struct +{ + uint32_t* pui32Inputs; + uint32_t* pui32Outputs; + uint32_t* pui32Resources; + uint32_t* pui32Interfaces; + uint32_t* pui32Inputs11; + uint32_t* pui32Outputs11; + uint32_t* pui32OutputsWithStreams; +} ReflectionChunks; + +void LoadShaderInfo(const uint32_t ui32MajorVersion, + const uint32_t ui32MinorVersion, + const ReflectionChunks* psChunks, + ShaderInfo* psInfo); + +void LoadD3D9ConstantTable(const char* data, + ShaderInfo* psInfo); + +void FreeShaderInfo(ShaderInfo* psShaderInfo); + +#if 0 +//--- Utility functions --- + +//Returns 0 if not found, 1 otherwise. +int GetResourceFromName(const char* name, ShaderInfo* psShaderInfo, ResourceBinding* psBinding); + +//These call into OpenGL and modify the uniforms of the currently bound program. +void SetResourceValueF(ResourceBinding* psBinding, float* value); +void SetResourceValueI(ResourceBinding* psBinding, int* value); +void SetResourceValueStr(ResourceBinding* psBinding, char* value); //Used for interfaces/subroutines. Also for constant buffers? + +void CreateUniformBufferObjectFromResource(ResourceBinding* psBinding, uint32_t* ui32GLHandle); +//------------------------ +#endif + +#endif + diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/shaderLimits.h b/build/tools/HLSLcc/May_2014/src/internal_includes/shaderLimits.h new file mode 100644 index 0000000..bc21f3f --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/shaderLimits.h @@ -0,0 +1,13 @@ + +#ifndef HLSLCC_SHADER_LIMITS_H +#define HLSLCC_SHADER_LIMITS_H + +static enum {MAX_SHADER_VEC4_OUTPUT = 512}; +static enum {MAX_SHADER_VEC4_INPUT = 512}; +static enum {MAX_TEXTURES = 128}; +static enum {MAX_FORK_PHASES = 2}; +static enum {MAX_FUNCTION_BODIES = 1024}; +static enum {MAX_CLASS_TYPES = 1024}; +static enum {MAX_FUNCTION_POINTERS = 128}; + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/structs.h b/build/tools/HLSLcc/May_2014/src/internal_includes/structs.h new file mode 100644 index 0000000..c5dc009 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/structs.h @@ -0,0 +1,273 @@ +#ifndef STRUCTS_H +#define STRUCTS_H + +#include "hlslcc.h" +#include "bstrlib.h" + +#include "internal_includes/tokens.h" +#include "internal_includes/reflect.h" + +enum{ MAX_SUB_OPERANDS = 3}; + +typedef struct Operand_TAG +{ + int iExtended; + OPERAND_TYPE eType; + OPERAND_MODIFIER eModifier; + OPERAND_MIN_PRECISION eMinPrecision; + int iIndexDims; + int indexRepresentation[4]; + int writeMask; + int iGSInput; + int iWriteMaskEnabled; + + int iNumComponents; + + OPERAND_4_COMPONENT_SELECTION_MODE eSelMode; + uint32_t ui32CompMask; + uint32_t ui32Swizzle; + uint32_t aui32Swizzle[4]; + + uint32_t aui32ArraySizes[3]; + uint32_t ui32RegisterNumber; + //If eType is OPERAND_TYPE_IMMEDIATE32 + float afImmediates[4]; + //If eType is OPERAND_TYPE_IMMEDIATE64 + double adImmediates[4]; + + int iIntegerImmediate; + + SPECIAL_NAME eSpecialName; + char pszSpecialName[64]; + + OPERAND_INDEX_REPRESENTATION eIndexRep[3]; + + struct Operand_TAG* psSubOperand[MAX_SUB_OPERANDS]; + + //One type for each component. + SHADER_VARIABLE_TYPE aeDataType[4]; + +#ifdef _DEBUG + uint64_t id; +#endif +} Operand; + +typedef struct Instruction_TAG +{ + OPCODE_TYPE eOpcode; + INSTRUCTION_TEST_BOOLEAN eBooleanTestType; + COMPARISON_DX9 eDX9TestType; + uint32_t ui32SyncFlags; + uint32_t ui32NumOperands; + uint32_t ui32FirstSrc; + Operand asOperands[6]; + uint32_t bSaturate; + uint32_t ui32FuncIndexWithinInterface; + RESINFO_RETURN_TYPE eResInfoReturnType; + + int bAddressOffset; + int8_t iUAddrOffset; + int8_t iVAddrOffset; + int8_t iWAddrOffset; + RESOURCE_RETURN_TYPE xType, yType, zType, wType; + RESOURCE_DIMENSION eResDim; + +#ifdef _DEBUG + uint64_t id; +#endif +} Instruction; + +static enum{ MAX_IMMEDIATE_CONST_BUFFER_VEC4_SIZE = 1024}; + +typedef struct ICBVec4_TAG { + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; +} ICBVec4; + +typedef struct Declaration_TAG +{ + OPCODE_TYPE eOpcode; + + uint32_t ui32NumOperands; + + Operand asOperands[2]; + + ICBVec4 asImmediateConstBuffer[MAX_IMMEDIATE_CONST_BUFFER_VEC4_SIZE]; + //The declaration can set one of these + //values depending on the opcode. + union { + uint32_t ui32GlobalFlags; + uint32_t ui32NumTemps; + RESOURCE_DIMENSION eResourceDimension; + INTERPOLATION_MODE eInterpolation; + PRIMITIVE_TOPOLOGY eOutputPrimitiveTopology; + PRIMITIVE eInputPrimitive; + uint32_t ui32MaxOutputVertexCount; + TESSELLATOR_DOMAIN eTessDomain; + TESSELLATOR_PARTITIONING eTessPartitioning; + TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim; + uint32_t aui32WorkGroupSize[3]; + //Fork phase index followed by the instance count. + uint32_t aui32HullPhaseInstanceInfo[2]; + float fMaxTessFactor; + uint32_t ui32IndexRange; + uint32_t ui32GSInstanceCount; + + struct Interface_TAG + { + uint32_t ui32InterfaceID; + uint32_t ui32NumFuncTables; + uint32_t ui32ArraySize; + } interface; + } value; + + struct UAV_TAG + { + uint32_t ui32GloballyCoherentAccess; + uint32_t ui32BufferSize; + uint8_t bCounter; + RESOURCE_RETURN_TYPE Type; + } sUAV; + + struct TGSM_TAG + { + uint32_t ui32Stride; + uint32_t ui32Count; + } sTGSM; + + struct IndexableTemp_TAG + { + uint32_t ui32RegIndex; + uint32_t ui32RegCount; + uint32_t ui32RegComponentSize; + } sIdxTemp; + + uint32_t ui32TableLength; + + uint32_t ui32IsShadowTex; +} Declaration; + +static enum {MAX_TEMP_VEC4 = 512}; + +static enum {MAX_GROUPSHARED = 8}; + +static enum {MAX_DX9_IMMCONST = 256}; + +typedef struct Shader_TAG +{ + uint32_t ui32MajorVersion; + uint32_t ui32MinorVersion; + SHADER_TYPE eShaderType; + + GLLang eTargetLanguage; + const struct GlExtensions *extensions; + + int fp64; + + //DWORDs in program code, including version and length tokens. + uint32_t ui32ShaderLength; + + uint32_t ui32DeclCount; + Declaration* psDecl; + + //Instruction* functions;//non-main subroutines + + uint32_t aui32FuncTableToFuncPointer[MAX_FUNCTION_TABLES];//FIXME dynamic alloc + uint32_t aui32FuncBodyToFuncTable[MAX_FUNCTION_BODIES]; + + struct { + uint32_t aui32FuncBodies[MAX_FUNCTION_BODIES]; + }funcTable[MAX_FUNCTION_TABLES]; + + struct { + uint32_t aui32FuncTables[MAX_FUNCTION_TABLES]; + uint32_t ui32NumBodiesPerTable; + }funcPointer[MAX_FUNCTION_POINTERS]; + + uint32_t ui32NextClassFuncName[MAX_CLASS_TYPES]; + + uint32_t ui32InstCount; + Instruction* psInst; + + const uint32_t* pui32FirstToken;//Reference for calculating current position in token stream. + + //Hull shader declarations and instructions. + //psDecl, psInst are null for hull shaders. + uint32_t ui32HSDeclCount; + Declaration* psHSDecl; + + uint32_t ui32HSControlPointDeclCount; + Declaration* psHSControlPointPhaseDecl; + + uint32_t ui32HSControlPointInstrCount; + Instruction* psHSControlPointPhaseInstr; + + uint32_t ui32ForkPhaseCount; + + uint32_t aui32HSForkDeclCount[MAX_FORK_PHASES]; + Declaration* apsHSForkPhaseDecl[MAX_FORK_PHASES]; + + uint32_t aui32HSForkInstrCount[MAX_FORK_PHASES]; + Instruction* apsHSForkPhaseInstr[MAX_FORK_PHASES]; + + uint32_t ui32HSJoinDeclCount; + Declaration* psHSJoinPhaseDecl; + + uint32_t ui32HSJoinInstrCount; + Instruction* psHSJoinPhaseInstr; + + ShaderInfo sInfo; + + int abScalarInput[MAX_SHADER_VEC4_INPUT]; + + int aIndexedOutput[MAX_SHADER_VEC4_OUTPUT]; + + int aIndexedInput[MAX_SHADER_VEC4_INPUT]; + int aIndexedInputParents[MAX_SHADER_VEC4_INPUT]; + + RESOURCE_DIMENSION aeResourceDims[MAX_TEXTURES]; + + int aiInputDeclaredSize[MAX_SHADER_VEC4_INPUT]; + + int aiOutputDeclared[MAX_SHADER_VEC4_OUTPUT]; + + //Does not track built-in inputs. + int abInputReferencedByInstruction[MAX_SHADER_VEC4_INPUT]; + + int aiOpcodeUsed[NUM_OPCODES]; + + uint32_t ui32CurrentVertexOutputStream; + + uint32_t ui32NumDx9ImmConst; + uint32_t aui32Dx9ImmConstArrayRemap[MAX_DX9_IMMCONST]; + + ShaderVarType sGroupSharedVarType[MAX_GROUPSHARED]; + +} Shader; + +static const uint32_t MAIN_PHASE = 0; +static const uint32_t HS_FORK_PHASE = 1; +static const uint32_t HS_CTRL_POINT_PHASE = 2; +static const uint32_t HS_JOIN_PHASE = 3; +static enum{ NUM_PHASES = 4}; + +typedef struct HLSLCrossCompilerContext_TAG +{ + bstring glsl; + bstring earlyMain;//Code to be inserted at the start of main() + bstring postShaderCode[NUM_PHASES];//End of main or before emit() + + bstring* currentGLSLString;//either glsl or earlyMain + + int havePostShaderCode[NUM_PHASES]; + uint32_t currentPhase; + + int indent; + unsigned int flags; + Shader* psShader; + GLSLCrossDependencyData* psDependencies; +} HLSLCrossCompilerContext; + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLDeclaration.h b/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLDeclaration.h new file mode 100644 index 0000000..bf6c6bc --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLDeclaration.h @@ -0,0 +1,16 @@ +#ifndef TO_GLSL_DECLARATION_H +#define TO_GLSL_DECLARATION_H + +#include "internal_includes/structs.h" + +void TranslateDeclaration(HLSLCrossCompilerContext* psContext, const Declaration* psDecl); + +const char* GetDeclaredInputName(const HLSLCrossCompilerContext* psContext, const SHADER_TYPE eShaderType, const Operand* psOperand); +const char* GetDeclaredOutputName(const HLSLCrossCompilerContext* psContext, const SHADER_TYPE eShaderType, const Operand* psOperand, int* stream); + +//Hull shaders have multiple phases. +//Each phase has its own temps. +//Convert to global temps for GLSL. +void ConsolidateHullTempVars(Shader* psShader); + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLInstruction.h b/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLInstruction.h new file mode 100644 index 0000000..3437267 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLInstruction.h @@ -0,0 +1,15 @@ +#ifndef TO_GLSL_INSTRUCTION_H +#define TO_GLSL_INSTRUCTION_H + +#include "internal_includes/structs.h" + +void TranslateInstruction(HLSLCrossCompilerContext* psContext, Instruction* psInst); + +//For each MOV temp, immediate; check to see if the next instruction +//using that temp has an integer opcode. If so then the immediate value +//is flaged as having an integer encoding. +void MarkIntegerImmediates(HLSLCrossCompilerContext* psContext); + +void SetDataTypes(HLSLCrossCompilerContext* psContext, Instruction* psInst, const int32_t i32InstCount); + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLOperand.h b/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLOperand.h new file mode 100644 index 0000000..6f4d0ae --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/toGLSLOperand.h @@ -0,0 +1,31 @@ +#ifndef TO_GLSL_OPERAND_H +#define TO_GLSL_OPERAND_H + +#include "internal_includes/structs.h" + +#define TO_FLAG_NONE 0x0 +#define TO_FLAG_INTEGER 0x1 +#define TO_FLAG_NAME_ONLY 0x2 +#define TO_FLAG_DECLARATION_NAME 0x4 +#define TO_FLAG_DESTINATION 0x8 //Operand is being written to by assignment. +#define TO_FLAG_UNSIGNED_INTEGER 0x10 +#define TO_FLAG_DOUBLE 0x20 +void TranslateOperand(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag); + +int GetMaxComponentFromComponentMask(const Operand* psOperand); +void TranslateOperandIndex(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index); +void TranslateOperandIndexMAD(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index, uint32_t multiply, uint32_t add); +void TranslateOperandSwizzle(HLSLCrossCompilerContext* psContext, const Operand* psOperand); +uint32_t GetNumSwizzleElements(const Operand* psOperand); +void AddSwizzleUsingElementCount(HLSLCrossCompilerContext* psContext, uint32_t count); +int GetFirstOperandSwizzle(HLSLCrossCompilerContext* psContext, const Operand* psOperand); +uint32_t IsSwizzleReplacated(const Operand* psOperand); + +void TextureName(HLSLCrossCompilerContext* psContext, const uint32_t ui32RegisterNumber, const int bZCompare); + +//Non-zero means the components overlap +int CompareOperandSwizzles(const Operand* psOperandA, const Operand* psOperandB); + +SHADER_VARIABLE_TYPE GetOperandDataType(HLSLCrossCompilerContext* psContext, const Operand* psOperand); + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/tokens.h b/build/tools/HLSLcc/May_2014/src/internal_includes/tokens.h new file mode 100644 index 0000000..11cb542 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/tokens.h @@ -0,0 +1,798 @@ +#ifndef TOKENS_H +#define TOKENS_H + +#include "hlslcc.h" + +typedef enum +{ + INVALID_SHADER = -1, + PIXEL_SHADER, + VERTEX_SHADER, + GEOMETRY_SHADER, + HULL_SHADER, + DOMAIN_SHADER, + COMPUTE_SHADER, +} SHADER_TYPE; + +static SHADER_TYPE DecodeShaderType(uint32_t ui32Token) +{ + return (SHADER_TYPE)((ui32Token & 0xffff0000) >> 16); +} + +static uint32_t DecodeProgramMajorVersion(uint32_t ui32Token) +{ + return (ui32Token & 0x000000f0) >> 4; +} + +static uint32_t DecodeProgramMinorVersion(uint32_t ui32Token) +{ + return (ui32Token & 0x0000000f); +} + +static uint32_t DecodeInstructionLength(uint32_t ui32Token) +{ + return (ui32Token & 0x7f000000) >> 24; +} + +static uint32_t DecodeIsOpcodeExtended(uint32_t ui32Token) +{ + return (ui32Token & 0x80000000) >> 31; +} + +typedef enum EXTENDED_OPCODE_TYPE +{ + EXTENDED_OPCODE_EMPTY = 0, + EXTENDED_OPCODE_SAMPLE_CONTROLS = 1, + EXTENDED_OPCODE_RESOURCE_DIM = 2, + EXTENDED_OPCODE_RESOURCE_RETURN_TYPE = 3, +} EXTENDED_OPCODE_TYPE; + +static EXTENDED_OPCODE_TYPE DecodeExtendedOpcodeType(uint32_t ui32Token) +{ + return (EXTENDED_OPCODE_TYPE)(ui32Token & 0x0000003f); +} + +typedef enum RESOURCE_RETURN_TYPE +{ + RETURN_TYPE_UNORM = 1, + RETURN_TYPE_SNORM = 2, + RETURN_TYPE_SINT = 3, + RETURN_TYPE_UINT = 4, + RETURN_TYPE_FLOAT = 5, + RETURN_TYPE_MIXED = 6, + RETURN_TYPE_DOUBLE = 7, + RETURN_TYPE_CONTINUED = 8, + RETURN_TYPE_UNUSED = 9, +} RESOURCE_RETURN_TYPE; + +static RESOURCE_RETURN_TYPE DecodeResourceReturnType(uint32_t ui32Coord, uint32_t ui32Token) +{ + return (RESOURCE_RETURN_TYPE)((ui32Token>>(ui32Coord * 4))&0xF); +} + +static RESOURCE_RETURN_TYPE DecodeExtendedResourceReturnType(uint32_t ui32Coord, uint32_t ui32Token) +{ + return (RESOURCE_RETURN_TYPE)((ui32Token>>(ui32Coord * 4 + 6))&0xF); +} + +typedef enum +{ + //For DX9 + OPCODE_POW = -6, + OPCODE_DP2ADD = -5, + OPCODE_LRP = -4, + OPCODE_ENDREP = -3, + OPCODE_REP = -2, + OPCODE_SPECIAL_DCL_IMMCONST = -1, + + OPCODE_ADD, + OPCODE_AND, + OPCODE_BREAK, + OPCODE_BREAKC, + OPCODE_CALL, + OPCODE_CALLC, + OPCODE_CASE, + OPCODE_CONTINUE, + OPCODE_CONTINUEC, + OPCODE_CUT, + OPCODE_DEFAULT, + OPCODE_DERIV_RTX, + OPCODE_DERIV_RTY, + OPCODE_DISCARD, + OPCODE_DIV, + OPCODE_DP2, + OPCODE_DP3, + OPCODE_DP4, + OPCODE_ELSE, + OPCODE_EMIT, + OPCODE_EMITTHENCUT, + OPCODE_ENDIF, + OPCODE_ENDLOOP, + OPCODE_ENDSWITCH, + OPCODE_EQ, + OPCODE_EXP, + OPCODE_FRC, + OPCODE_FTOI, + OPCODE_FTOU, + OPCODE_GE, + OPCODE_IADD, + OPCODE_IF, + OPCODE_IEQ, + OPCODE_IGE, + OPCODE_ILT, + OPCODE_IMAD, + OPCODE_IMAX, + OPCODE_IMIN, + OPCODE_IMUL, + OPCODE_INE, + OPCODE_INEG, + OPCODE_ISHL, + OPCODE_ISHR, + OPCODE_ITOF, + OPCODE_LABEL, + OPCODE_LD, + OPCODE_LD_MS, + OPCODE_LOG, + OPCODE_LOOP, + OPCODE_LT, + OPCODE_MAD, + OPCODE_MIN, + OPCODE_MAX, + OPCODE_CUSTOMDATA, + OPCODE_MOV, + OPCODE_MOVC, + OPCODE_MUL, + OPCODE_NE, + OPCODE_NOP, + OPCODE_NOT, + OPCODE_OR, + OPCODE_RESINFO, + OPCODE_RET, + OPCODE_RETC, + OPCODE_ROUND_NE, + OPCODE_ROUND_NI, + OPCODE_ROUND_PI, + OPCODE_ROUND_Z, + OPCODE_RSQ, + OPCODE_SAMPLE, + OPCODE_SAMPLE_C, + OPCODE_SAMPLE_C_LZ, + OPCODE_SAMPLE_L, + OPCODE_SAMPLE_D, + OPCODE_SAMPLE_B, + OPCODE_SQRT, + OPCODE_SWITCH, + OPCODE_SINCOS, + OPCODE_UDIV, + OPCODE_ULT, + OPCODE_UGE, + OPCODE_UMUL, + OPCODE_UMAD, + OPCODE_UMAX, + OPCODE_UMIN, + OPCODE_USHR, + OPCODE_UTOF, + OPCODE_XOR, + OPCODE_DCL_RESOURCE, // DCL* opcodes have + OPCODE_DCL_CONSTANT_BUFFER, // custom operand formats. + OPCODE_DCL_SAMPLER, + OPCODE_DCL_INDEX_RANGE, + OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY, + OPCODE_DCL_GS_INPUT_PRIMITIVE, + OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT, + OPCODE_DCL_INPUT, + OPCODE_DCL_INPUT_SGV, + OPCODE_DCL_INPUT_SIV, + OPCODE_DCL_INPUT_PS, + OPCODE_DCL_INPUT_PS_SGV, + OPCODE_DCL_INPUT_PS_SIV, + OPCODE_DCL_OUTPUT, + OPCODE_DCL_OUTPUT_SGV, + OPCODE_DCL_OUTPUT_SIV, + OPCODE_DCL_TEMPS, + OPCODE_DCL_INDEXABLE_TEMP, + OPCODE_DCL_GLOBAL_FLAGS, + +// ----------------------------------------------- + + OPCODE_RESERVED_10, + +// ---------- DX 10.1 op codes--------------------- + + OPCODE_LOD, + OPCODE_GATHER4, + OPCODE_SAMPLE_POS, + OPCODE_SAMPLE_INFO, + +// ----------------------------------------------- + + // This should be 10.1's version of NUM_OPCODES + OPCODE_RESERVED_10_1, + +// ---------- DX 11 op codes--------------------- + OPCODE_HS_DECLS, // token marks beginning of HS sub-shader + OPCODE_HS_CONTROL_POINT_PHASE, // token marks beginning of HS sub-shader + OPCODE_HS_FORK_PHASE, // token marks beginning of HS sub-shader + OPCODE_HS_JOIN_PHASE, // token marks beginning of HS sub-shader + + OPCODE_EMIT_STREAM, + OPCODE_CUT_STREAM, + OPCODE_EMITTHENCUT_STREAM, + OPCODE_INTERFACE_CALL, + + OPCODE_BUFINFO, + OPCODE_DERIV_RTX_COARSE, + OPCODE_DERIV_RTX_FINE, + OPCODE_DERIV_RTY_COARSE, + OPCODE_DERIV_RTY_FINE, + OPCODE_GATHER4_C, + OPCODE_GATHER4_PO, + OPCODE_GATHER4_PO_C, + OPCODE_RCP, + OPCODE_F32TOF16, + OPCODE_F16TOF32, + OPCODE_UADDC, + OPCODE_USUBB, + OPCODE_COUNTBITS, + OPCODE_FIRSTBIT_HI, + OPCODE_FIRSTBIT_LO, + OPCODE_FIRSTBIT_SHI, + OPCODE_UBFE, + OPCODE_IBFE, + OPCODE_BFI, + OPCODE_BFREV, + OPCODE_SWAPC, + + OPCODE_DCL_STREAM, + OPCODE_DCL_FUNCTION_BODY, + OPCODE_DCL_FUNCTION_TABLE, + OPCODE_DCL_INTERFACE, + + OPCODE_DCL_INPUT_CONTROL_POINT_COUNT, + OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT, + OPCODE_DCL_TESS_DOMAIN, + OPCODE_DCL_TESS_PARTITIONING, + OPCODE_DCL_TESS_OUTPUT_PRIMITIVE, + OPCODE_DCL_HS_MAX_TESSFACTOR, + OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT, + OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, + + OPCODE_DCL_THREAD_GROUP, + OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED, + OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW, + OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED, + OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW, + OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED, + OPCODE_DCL_RESOURCE_RAW, + OPCODE_DCL_RESOURCE_STRUCTURED, + OPCODE_LD_UAV_TYPED, + OPCODE_STORE_UAV_TYPED, + OPCODE_LD_RAW, + OPCODE_STORE_RAW, + OPCODE_LD_STRUCTURED, + OPCODE_STORE_STRUCTURED, + OPCODE_ATOMIC_AND, + OPCODE_ATOMIC_OR, + OPCODE_ATOMIC_XOR, + OPCODE_ATOMIC_CMP_STORE, + OPCODE_ATOMIC_IADD, + OPCODE_ATOMIC_IMAX, + OPCODE_ATOMIC_IMIN, + OPCODE_ATOMIC_UMAX, + OPCODE_ATOMIC_UMIN, + OPCODE_IMM_ATOMIC_ALLOC, + OPCODE_IMM_ATOMIC_CONSUME, + OPCODE_IMM_ATOMIC_IADD, + OPCODE_IMM_ATOMIC_AND, + OPCODE_IMM_ATOMIC_OR, + OPCODE_IMM_ATOMIC_XOR, + OPCODE_IMM_ATOMIC_EXCH, + OPCODE_IMM_ATOMIC_CMP_EXCH, + OPCODE_IMM_ATOMIC_IMAX, + OPCODE_IMM_ATOMIC_IMIN, + OPCODE_IMM_ATOMIC_UMAX, + OPCODE_IMM_ATOMIC_UMIN, + OPCODE_SYNC, + + OPCODE_DADD, + OPCODE_DMAX, + OPCODE_DMIN, + OPCODE_DMUL, + OPCODE_DEQ, + OPCODE_DGE, + OPCODE_DLT, + OPCODE_DNE, + OPCODE_DMOV, + OPCODE_DMOVC, + OPCODE_DTOF, + OPCODE_FTOD, + + OPCODE_EVAL_SNAPPED, + OPCODE_EVAL_SAMPLE_INDEX, + OPCODE_EVAL_CENTROID, + + OPCODE_DCL_GS_INSTANCE_COUNT, + + OPCODE_ABORT, + OPCODE_DEBUG_BREAK, + +// ----------------------------------------------- + + // This marks the end of D3D11.0 opcodes + OPCODE_RESERVED_11, + + OPCODE_DDIV, + OPCODE_DFMA, + OPCODE_DRCP, + + OPCODE_MSAD, + + OPCODE_DTOI, + OPCODE_DTOU, + OPCODE_ITOD, + OPCODE_UTOD, + +// ----------------------------------------------- + + // This marks the end of D3D11.1 opcodes + OPCODE_RESERVED_11_1, + + NUM_OPCODES, + OPCODE_INVAILD = NUM_OPCODES, +} OPCODE_TYPE; + +static OPCODE_TYPE DecodeOpcodeType(uint32_t ui32Token) +{ + return (OPCODE_TYPE)(ui32Token & 0x00007ff); +} + +typedef enum +{ + INDEX_0D, + INDEX_1D, + INDEX_2D, + INDEX_3D, +} OPERAND_INDEX_DIMENSION; + +static OPERAND_INDEX_DIMENSION DecodeOperandIndexDimension(uint32_t ui32Token) +{ + return (OPERAND_INDEX_DIMENSION)((ui32Token & 0x00300000) >> 20); +} + +typedef enum OPERAND_TYPE +{ + OPERAND_TYPE_SPECIAL_LOOPCOUNTER = -10, + OPERAND_TYPE_SPECIAL_IMMCONSTINT = -9, + OPERAND_TYPE_SPECIAL_TEXCOORD = -8, + OPERAND_TYPE_SPECIAL_POSITION = -7, + OPERAND_TYPE_SPECIAL_FOG = -6, + OPERAND_TYPE_SPECIAL_POINTSIZE = -5, + OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR = -4, + OPERAND_TYPE_SPECIAL_OUTBASECOLOUR = -3, + OPERAND_TYPE_SPECIAL_ADDRESS = -2, + OPERAND_TYPE_SPECIAL_IMMCONST = -1, + OPERAND_TYPE_TEMP = 0, // Temporary Register File + OPERAND_TYPE_INPUT = 1, // General Input Register File + OPERAND_TYPE_OUTPUT = 2, // General Output Register File + OPERAND_TYPE_INDEXABLE_TEMP = 3, // Temporary Register File (indexable) + OPERAND_TYPE_IMMEDIATE32 = 4, // 32bit/component immediate value(s) + // If for example, operand token bits + // [01:00]==OPERAND_4_COMPONENT, + // this means that the operand type: + // OPERAND_TYPE_IMMEDIATE32 + // results in 4 additional 32bit + // DWORDS present for the operand. + OPERAND_TYPE_IMMEDIATE64 = 5, // 64bit/comp.imm.val(s)HI:LO + OPERAND_TYPE_SAMPLER = 6, // Reference to sampler state + OPERAND_TYPE_RESOURCE = 7, // Reference to memory resource (e.g. texture) + OPERAND_TYPE_CONSTANT_BUFFER= 8, // Reference to constant buffer + OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER= 9, // Reference to immediate constant buffer + OPERAND_TYPE_LABEL = 10, // Label + OPERAND_TYPE_INPUT_PRIMITIVEID = 11, // Input primitive ID + OPERAND_TYPE_OUTPUT_DEPTH = 12, // Output Depth + OPERAND_TYPE_NULL = 13, // Null register, used to discard results of operations + // Below Are operands new in DX 10.1 + OPERAND_TYPE_RASTERIZER = 14, // DX10.1 Rasterizer register, used to denote the depth/stencil and render target resources + OPERAND_TYPE_OUTPUT_COVERAGE_MASK = 15, // DX10.1 PS output MSAA coverage mask (scalar) + // Below Are operands new in DX 11 + OPERAND_TYPE_STREAM = 16, // Reference to GS stream output resource + OPERAND_TYPE_FUNCTION_BODY = 17, // Reference to a function definition + OPERAND_TYPE_FUNCTION_TABLE = 18, // Reference to a set of functions used by a class + OPERAND_TYPE_INTERFACE = 19, // Reference to an interface + OPERAND_TYPE_FUNCTION_INPUT = 20, // Reference to an input parameter to a function + OPERAND_TYPE_FUNCTION_OUTPUT = 21, // Reference to an output parameter to a function + OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID = 22, // HS Control Point phase input saying which output control point ID this is + OPERAND_TYPE_INPUT_FORK_INSTANCE_ID = 23, // HS Fork Phase input instance ID + OPERAND_TYPE_INPUT_JOIN_INSTANCE_ID = 24, // HS Join Phase input instance ID + OPERAND_TYPE_INPUT_CONTROL_POINT = 25, // HS Fork+Join, DS phase input control points (array of them) + OPERAND_TYPE_OUTPUT_CONTROL_POINT = 26, // HS Fork+Join phase output control points (array of them) + OPERAND_TYPE_INPUT_PATCH_CONSTANT = 27, // DS+HSJoin Input Patch Constants (array of them) + OPERAND_TYPE_INPUT_DOMAIN_POINT = 28, // DS Input Domain point + OPERAND_TYPE_THIS_POINTER = 29, // Reference to an interface this pointer + OPERAND_TYPE_UNORDERED_ACCESS_VIEW = 30, // Reference to UAV u# + OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY = 31, // Reference to Thread Group Shared Memory g# + OPERAND_TYPE_INPUT_THREAD_ID = 32, // Compute Shader Thread ID + OPERAND_TYPE_INPUT_THREAD_GROUP_ID = 33, // Compute Shader Thread Group ID + OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP = 34, // Compute Shader Thread ID In Thread Group + OPERAND_TYPE_INPUT_COVERAGE_MASK = 35, // Pixel shader coverage mask input + OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED = 36, // Compute Shader Thread ID In Group Flattened to a 1D value. + OPERAND_TYPE_INPUT_GS_INSTANCE_ID = 37, // Input GS instance ID + OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL = 38, // Output Depth, forced to be greater than or equal than current depth + OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL = 39, // Output Depth, forced to be less than or equal to current depth + OPERAND_TYPE_CYCLE_COUNTER = 40, // Cycle counter +} OPERAND_TYPE; + +static OPERAND_TYPE DecodeOperandType(uint32_t ui32Token) +{ + return (OPERAND_TYPE)((ui32Token & 0x000ff000) >> 12); +} + +static SPECIAL_NAME DecodeOperandSpecialName(uint32_t ui32Token) +{ + return (SPECIAL_NAME)(ui32Token & 0x0000ffff); +} + +typedef enum OPERAND_INDEX_REPRESENTATION +{ + OPERAND_INDEX_IMMEDIATE32 = 0, // Extra DWORD + OPERAND_INDEX_IMMEDIATE64 = 1, // 2 Extra DWORDs + // (HI32:LO32) + OPERAND_INDEX_RELATIVE = 2, // Extra operand + OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE = 3, // Extra DWORD followed by + // extra operand + OPERAND_INDEX_IMMEDIATE64_PLUS_RELATIVE = 4, // 2 Extra DWORDS + // (HI32:LO32) followed + // by extra operand +} OPERAND_INDEX_REPRESENTATION; + +static OPERAND_INDEX_REPRESENTATION DecodeOperandIndexRepresentation(uint32_t ui32Dimension, uint32_t ui32Token) +{ + return (OPERAND_INDEX_REPRESENTATION)((ui32Token & (0x3<<(22+3*((ui32Dimension)&3)))) >> (22+3*((ui32Dimension)&3))); +} + +typedef enum OPERAND_NUM_COMPONENTS +{ + OPERAND_0_COMPONENT = 0, + OPERAND_1_COMPONENT = 1, + OPERAND_4_COMPONENT = 2, + OPERAND_N_COMPONENT = 3 // unused for now +} OPERAND_NUM_COMPONENTS; + +static OPERAND_NUM_COMPONENTS DecodeOperandNumComponents(uint32_t ui32Token) +{ + return (OPERAND_NUM_COMPONENTS)(ui32Token & 0x00000003); +} + +typedef enum OPERAND_4_COMPONENT_SELECTION_MODE +{ + OPERAND_4_COMPONENT_MASK_MODE = 0, // mask 4 components + OPERAND_4_COMPONENT_SWIZZLE_MODE = 1, // swizzle 4 components + OPERAND_4_COMPONENT_SELECT_1_MODE = 2, // select 1 of 4 components +} OPERAND_4_COMPONENT_SELECTION_MODE; + +static OPERAND_4_COMPONENT_SELECTION_MODE DecodeOperand4CompSelMode(uint32_t ui32Token) +{ + return (OPERAND_4_COMPONENT_SELECTION_MODE)((ui32Token & 0x0000000c) >> 2); +} + +#define OPERAND_4_COMPONENT_MASK_X 0x00000001 +#define OPERAND_4_COMPONENT_MASK_Y 0x00000002 +#define OPERAND_4_COMPONENT_MASK_Z 0x00000004 +#define OPERAND_4_COMPONENT_MASK_W 0x00000008 +#define OPERAND_4_COMPONENT_MASK_R OPERAND_4_COMPONENT_MASK_X +#define OPERAND_4_COMPONENT_MASK_G OPERAND_4_COMPONENT_MASK_Y +#define OPERAND_4_COMPONENT_MASK_B OPERAND_4_COMPONENT_MASK_Z +#define OPERAND_4_COMPONENT_MASK_A OPERAND_4_COMPONENT_MASK_W +#define OPERAND_4_COMPONENT_MASK_ALL 0x0000000f + +static uint32_t DecodeOperand4CompMask(uint32_t ui32Token) +{ + return (uint32_t)((ui32Token & 0x000000f0) >> 4); +} + +static uint32_t DecodeOperand4CompSwizzle(uint32_t ui32Token) +{ + return (uint32_t)((ui32Token & 0x00000ff0) >> 4); +} + +static uint32_t DecodeOperand4CompSel1(uint32_t ui32Token) +{ + return (uint32_t)((ui32Token & 0x00000030) >> 4); +} + +#define OPERAND_4_COMPONENT_X 0 +#define OPERAND_4_COMPONENT_Y 1 +#define OPERAND_4_COMPONENT_Z 2 +#define OPERAND_4_COMPONENT_W 3 + +static uint32_t NO_SWIZZLE = (( (OPERAND_4_COMPONENT_X) | (OPERAND_4_COMPONENT_Y<<2) | (OPERAND_4_COMPONENT_Z << 4) | (OPERAND_4_COMPONENT_W << 6))/*<<4*/); + +static uint32_t XXXX_SWIZZLE = (((OPERAND_4_COMPONENT_X) | (OPERAND_4_COMPONENT_X<<2) | (OPERAND_4_COMPONENT_X << 4) | (OPERAND_4_COMPONENT_X << 6))); +static uint32_t YYYY_SWIZZLE = (((OPERAND_4_COMPONENT_Y) | (OPERAND_4_COMPONENT_Y<<2) | (OPERAND_4_COMPONENT_Y << 4) | (OPERAND_4_COMPONENT_Y << 6))); +static uint32_t ZZZZ_SWIZZLE = (((OPERAND_4_COMPONENT_Z) | (OPERAND_4_COMPONENT_Z<<2) | (OPERAND_4_COMPONENT_Z << 4) | (OPERAND_4_COMPONENT_Z << 6))); +static uint32_t WWWW_SWIZZLE = (((OPERAND_4_COMPONENT_W) | (OPERAND_4_COMPONENT_W<<2) | (OPERAND_4_COMPONENT_W << 4) | (OPERAND_4_COMPONENT_W << 6))); + +static uint32_t DecodeOperand4CompSwizzleSource(uint32_t ui32Token, uint32_t comp) +{ + return (uint32_t)(((ui32Token)>>(4+2*((comp)&3)))&3); +} + +typedef enum RESOURCE_DIMENSION +{ + RESOURCE_DIMENSION_UNKNOWN = 0, + RESOURCE_DIMENSION_BUFFER = 1, + RESOURCE_DIMENSION_TEXTURE1D = 2, + RESOURCE_DIMENSION_TEXTURE2D = 3, + RESOURCE_DIMENSION_TEXTURE2DMS = 4, + RESOURCE_DIMENSION_TEXTURE3D = 5, + RESOURCE_DIMENSION_TEXTURECUBE = 6, + RESOURCE_DIMENSION_TEXTURE1DARRAY = 7, + RESOURCE_DIMENSION_TEXTURE2DARRAY = 8, + RESOURCE_DIMENSION_TEXTURE2DMSARRAY = 9, + RESOURCE_DIMENSION_TEXTURECUBEARRAY = 10, + RESOURCE_DIMENSION_RAW_BUFFER = 11, + RESOURCE_DIMENSION_STRUCTURED_BUFFER = 12, +} RESOURCE_DIMENSION; + +static RESOURCE_DIMENSION DecodeResourceDimension(uint32_t ui32Token) +{ + return (RESOURCE_DIMENSION)((ui32Token & 0x0000f800) >> 11); +} + +static RESOURCE_DIMENSION DecodeExtendedResourceDimension(uint32_t ui32Token) +{ + return (RESOURCE_DIMENSION)((ui32Token & 0x000007C0) >> 6); +} + +typedef enum INSTRUCTION_TEST_BOOLEAN +{ + INSTRUCTION_TEST_ZERO = 0, + INSTRUCTION_TEST_NONZERO = 1 +} INSTRUCTION_TEST_BOOLEAN; + +static INSTRUCTION_TEST_BOOLEAN DecodeInstrTestBool(uint32_t ui32Token) +{ + return (INSTRUCTION_TEST_BOOLEAN)((ui32Token & 0x00040000) >> 18); +} + +static uint32_t DecodeIsOperandExtended(uint32_t ui32Token) +{ + return (ui32Token & 0x80000000) >> 31; +} + +typedef enum EXTENDED_OPERAND_TYPE +{ + EXTENDED_OPERAND_EMPTY = 0, + EXTENDED_OPERAND_MODIFIER = 1, +} EXTENDED_OPERAND_TYPE; + +static EXTENDED_OPERAND_TYPE DecodeExtendedOperandType(uint32_t ui32Token) +{ + return (EXTENDED_OPERAND_TYPE)(ui32Token & 0x0000003f); +} + +typedef enum OPERAND_MODIFIER +{ + OPERAND_MODIFIER_NONE = 0, + OPERAND_MODIFIER_NEG = 1, + OPERAND_MODIFIER_ABS = 2, + OPERAND_MODIFIER_ABSNEG = 3, +} OPERAND_MODIFIER; + +static OPERAND_MODIFIER DecodeExtendedOperandModifier(uint32_t ui32Token) +{ + return (OPERAND_MODIFIER)((ui32Token & 0x00003fc0) >> 6); +} + +static const uint32_t GLOBAL_FLAG_REFACTORING_ALLOWED = (1<<11); +static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_PRECISION_FLOAT_OPS = (1<<12); +static const uint32_t GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL = (1<<13); +static const uint32_t GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS = (1<<14); +static const uint32_t GLOBAL_FLAG_SKIP_OPTIMIZATION = (1<<15); +static const uint32_t GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION = (1<<16); +static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_EXTENSIONS = (1<<17); +static const uint32_t GLOBAL_FLAG_ENABLE_SHADER_EXTENSIONS = (1<<18); + +static uint32_t DecodeGlobalFlags(uint32_t ui32Token) +{ + return (uint32_t)(ui32Token & 0x00fff800); +} + +static INTERPOLATION_MODE DecodeInterpolationMode(uint32_t ui32Token) +{ + return (INTERPOLATION_MODE)((ui32Token & 0x00007800) >> 11); +} + + +typedef enum PRIMITIVE_TOPOLOGY +{ + PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + PRIMITIVE_TOPOLOGY_POINTLIST = 1, + PRIMITIVE_TOPOLOGY_LINELIST = 2, + PRIMITIVE_TOPOLOGY_LINESTRIP = 3, + PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4, + PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5, + // 6 is reserved for legacy triangle fans + // Adjacency values should be equal to (0x8 & non-adjacency): + PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11, + PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12, + PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13, +} PRIMITIVE_TOPOLOGY; + +static PRIMITIVE_TOPOLOGY DecodeGSOutputPrimitiveTopology(uint32_t ui32Token) +{ + return (PRIMITIVE_TOPOLOGY)((ui32Token & 0x0001f800) >> 11); +} + +typedef enum PRIMITIVE +{ + PRIMITIVE_UNDEFINED = 0, + PRIMITIVE_POINT = 1, + PRIMITIVE_LINE = 2, + PRIMITIVE_TRIANGLE = 3, + // Adjacency values should be equal to (0x4 & non-adjacency): + PRIMITIVE_LINE_ADJ = 6, + PRIMITIVE_TRIANGLE_ADJ = 7, + PRIMITIVE_1_CONTROL_POINT_PATCH = 8, + PRIMITIVE_2_CONTROL_POINT_PATCH = 9, + PRIMITIVE_3_CONTROL_POINT_PATCH = 10, + PRIMITIVE_4_CONTROL_POINT_PATCH = 11, + PRIMITIVE_5_CONTROL_POINT_PATCH = 12, + PRIMITIVE_6_CONTROL_POINT_PATCH = 13, + PRIMITIVE_7_CONTROL_POINT_PATCH = 14, + PRIMITIVE_8_CONTROL_POINT_PATCH = 15, + PRIMITIVE_9_CONTROL_POINT_PATCH = 16, + PRIMITIVE_10_CONTROL_POINT_PATCH = 17, + PRIMITIVE_11_CONTROL_POINT_PATCH = 18, + PRIMITIVE_12_CONTROL_POINT_PATCH = 19, + PRIMITIVE_13_CONTROL_POINT_PATCH = 20, + PRIMITIVE_14_CONTROL_POINT_PATCH = 21, + PRIMITIVE_15_CONTROL_POINT_PATCH = 22, + PRIMITIVE_16_CONTROL_POINT_PATCH = 23, + PRIMITIVE_17_CONTROL_POINT_PATCH = 24, + PRIMITIVE_18_CONTROL_POINT_PATCH = 25, + PRIMITIVE_19_CONTROL_POINT_PATCH = 26, + PRIMITIVE_20_CONTROL_POINT_PATCH = 27, + PRIMITIVE_21_CONTROL_POINT_PATCH = 28, + PRIMITIVE_22_CONTROL_POINT_PATCH = 29, + PRIMITIVE_23_CONTROL_POINT_PATCH = 30, + PRIMITIVE_24_CONTROL_POINT_PATCH = 31, + PRIMITIVE_25_CONTROL_POINT_PATCH = 32, + PRIMITIVE_26_CONTROL_POINT_PATCH = 33, + PRIMITIVE_27_CONTROL_POINT_PATCH = 34, + PRIMITIVE_28_CONTROL_POINT_PATCH = 35, + PRIMITIVE_29_CONTROL_POINT_PATCH = 36, + PRIMITIVE_30_CONTROL_POINT_PATCH = 37, + PRIMITIVE_31_CONTROL_POINT_PATCH = 38, + PRIMITIVE_32_CONTROL_POINT_PATCH = 39, +} PRIMITIVE; + +static PRIMITIVE DecodeGSInputPrimitive(uint32_t ui32Token) +{ + return (PRIMITIVE)((ui32Token & 0x0001f800) >> 11); +} + +static TESSELLATOR_PARTITIONING DecodeTessPartitioning(uint32_t ui32Token) +{ + return (TESSELLATOR_PARTITIONING)((ui32Token & 0x00003800) >> 11); +} + +typedef enum TESSELLATOR_DOMAIN +{ + TESSELLATOR_DOMAIN_UNDEFINED = 0, + TESSELLATOR_DOMAIN_ISOLINE = 1, + TESSELLATOR_DOMAIN_TRI = 2, + TESSELLATOR_DOMAIN_QUAD = 3 +} TESSELLATOR_DOMAIN; + +static TESSELLATOR_DOMAIN DecodeTessDomain(uint32_t ui32Token) +{ + return (TESSELLATOR_DOMAIN)((ui32Token & 0x00001800) >> 11); +} + +static TESSELLATOR_OUTPUT_PRIMITIVE DecodeTessOutPrim(uint32_t ui32Token) +{ + return (TESSELLATOR_OUTPUT_PRIMITIVE)((ui32Token & 0x00003800) >> 11); +} + +static const uint32_t SYNC_THREADS_IN_GROUP = 0x00000800; +static const uint32_t SYNC_THREAD_GROUP_SHARED_MEMORY = 0x00001000; +static const uint32_t SYNC_UNORDERED_ACCESS_VIEW_MEMORY_GROUP = 0x00002000; +static const uint32_t SYNC_UNORDERED_ACCESS_VIEW_MEMORY_GLOBAL = 0x00004000; + +static uint32_t DecodeSyncFlags(uint32_t ui32Token) +{ + return ui32Token & 0x00007800; +} + +// The number of types that implement this interface +static uint32_t DecodeInterfaceTableLength(uint32_t ui32Token) +{ + return (uint32_t)((ui32Token & 0x0000ffff) >> 0); +} + +// The number of interfaces that are defined in this array. +static uint32_t DecodeInterfaceArrayLength(uint32_t ui32Token) +{ + return (uint32_t)((ui32Token & 0xffff0000) >> 16); +} + +typedef enum CUSTOMDATA_CLASS +{ + CUSTOMDATA_COMMENT = 0, + CUSTOMDATA_DEBUGINFO, + CUSTOMDATA_OPAQUE, + CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER, + CUSTOMDATA_SHADER_MESSAGE, +} CUSTOMDATA_CLASS; + +static CUSTOMDATA_CLASS DecodeCustomDataClass(uint32_t ui32Token) +{ + return (CUSTOMDATA_CLASS)((ui32Token & 0xfffff800) >> 11); +} + +static uint32_t DecodeInstructionSaturate(uint32_t ui32Token) +{ + return (ui32Token & 0x00002000) ? 1 : 0; +} + +typedef enum OPERAND_MIN_PRECISION +{ + OPERAND_MIN_PRECISION_DEFAULT = 0, // Default precision + // for the shader model + OPERAND_MIN_PRECISION_FLOAT_16 = 1, // Min 16 bit/component float + OPERAND_MIN_PRECISION_FLOAT_2_8 = 2, // Min 10(2.8)bit/comp. float + OPERAND_MIN_PRECISION_SINT_16 = 4, // Min 16 bit/comp. signed integer + OPERAND_MIN_PRECISION_UINT_16 = 5, // Min 16 bit/comp. unsigned integer +} OPERAND_MIN_PRECISION; + +static uint32_t DecodeOperandMinPrecision(uint32_t ui32Token) +{ + return (ui32Token & 0x0001C000) >> 14; +} + +static uint32_t DecodeOutputControlPointCount(uint32_t ui32Token) +{ + return ((ui32Token & 0x0001f800) >> 11); +} + +typedef enum IMMEDIATE_ADDRESS_OFFSET_COORD +{ + IMMEDIATE_ADDRESS_OFFSET_U = 0, + IMMEDIATE_ADDRESS_OFFSET_V = 1, + IMMEDIATE_ADDRESS_OFFSET_W = 2, +} IMMEDIATE_ADDRESS_OFFSET_COORD; + + +#define IMMEDIATE_ADDRESS_OFFSET_SHIFT(Coord) (9+4*((Coord)&3)) +#define IMMEDIATE_ADDRESS_OFFSET_MASK(Coord) (0x0000000f<>(IMMEDIATE_ADDRESS_OFFSET_SHIFT(eCoord)))); +} + +// UAV access scope flags +static const uint32_t GLOBALLY_COHERENT_ACCESS = 0x00010000; +static uint32_t DecodeAccessCoherencyFlags(uint32_t ui32Token) +{ + return ui32Token & 0x00010000; +} + + +typedef enum RESINFO_RETURN_TYPE +{ + RESINFO_INSTRUCTION_RETURN_FLOAT = 0, + RESINFO_INSTRUCTION_RETURN_RCPFLOAT = 1, + RESINFO_INSTRUCTION_RETURN_UINT = 2 +} RESINFO_RETURN_TYPE; + +static RESINFO_RETURN_TYPE DecodeResInfoReturnType(uint32_t ui32Token) +{ + return (RESINFO_RETURN_TYPE)((ui32Token & 0x00001800) >> 11); +} + +#include "tokensDX9.h" + +#endif diff --git a/build/tools/HLSLcc/May_2014/src/internal_includes/tokensDX9.h b/build/tools/HLSLcc/May_2014/src/internal_includes/tokensDX9.h new file mode 100644 index 0000000..a6f2196 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/internal_includes/tokensDX9.h @@ -0,0 +1,301 @@ +#include "debug.h" + +static const uint32_t D3D9SHADER_TYPE_VERTEX = 0xFFFE0000; +static const uint32_t D3D9SHADER_TYPE_PIXEL = 0xFFFF0000; + +static SHADER_TYPE DecodeShaderTypeDX9(const uint32_t ui32Token) +{ + uint32_t ui32Type = ui32Token & 0xFFFF0000; + if(ui32Type == D3D9SHADER_TYPE_VERTEX) + return VERTEX_SHADER; + + if(ui32Type == D3D9SHADER_TYPE_PIXEL) + return PIXEL_SHADER; + + return INVALID_SHADER; +} + +static uint32_t DecodeProgramMajorVersionDX9(const uint32_t ui32Token) +{ + return ((ui32Token)>>8)&0xFF; +} + +static uint32_t DecodeProgramMinorVersionDX9(const uint32_t ui32Token) +{ + return ui32Token & 0xFF; +} + +typedef enum +{ + OPCODE_DX9_NOP = 0, + OPCODE_DX9_MOV , + OPCODE_DX9_ADD , + OPCODE_DX9_SUB , + OPCODE_DX9_MAD , + OPCODE_DX9_MUL , + OPCODE_DX9_RCP , + OPCODE_DX9_RSQ , + OPCODE_DX9_DP3 , + OPCODE_DX9_DP4 , + OPCODE_DX9_MIN , + OPCODE_DX9_MAX , + OPCODE_DX9_SLT , + OPCODE_DX9_SGE , + OPCODE_DX9_EXP , + OPCODE_DX9_LOG , + OPCODE_DX9_LIT , + OPCODE_DX9_DST , + OPCODE_DX9_LRP , + OPCODE_DX9_FRC , + OPCODE_DX9_M4x4 , + OPCODE_DX9_M4x3 , + OPCODE_DX9_M3x4 , + OPCODE_DX9_M3x3 , + OPCODE_DX9_M3x2 , + OPCODE_DX9_CALL , + OPCODE_DX9_CALLNZ , + OPCODE_DX9_LOOP , + OPCODE_DX9_RET , + OPCODE_DX9_ENDLOOP , + OPCODE_DX9_LABEL , + OPCODE_DX9_DCL , + OPCODE_DX9_POW , + OPCODE_DX9_CRS , + OPCODE_DX9_SGN , + OPCODE_DX9_ABS , + OPCODE_DX9_NRM , + OPCODE_DX9_SINCOS , + OPCODE_DX9_REP , + OPCODE_DX9_ENDREP , + OPCODE_DX9_IF , + OPCODE_DX9_IFC , + OPCODE_DX9_ELSE , + OPCODE_DX9_ENDIF , + OPCODE_DX9_BREAK , + OPCODE_DX9_BREAKC , + OPCODE_DX9_MOVA , + OPCODE_DX9_DEFB , + OPCODE_DX9_DEFI , + + OPCODE_DX9_TEXCOORD = 64, + OPCODE_DX9_TEXKILL , + OPCODE_DX9_TEX , + OPCODE_DX9_TEXBEM , + OPCODE_DX9_TEXBEML , + OPCODE_DX9_TEXREG2AR , + OPCODE_DX9_TEXREG2GB , + OPCODE_DX9_TEXM3x2PAD , + OPCODE_DX9_TEXM3x2TEX , + OPCODE_DX9_TEXM3x3PAD , + OPCODE_DX9_TEXM3x3TEX , + OPCODE_DX9_RESERVED0 , + OPCODE_DX9_TEXM3x3SPEC , + OPCODE_DX9_TEXM3x3VSPEC , + OPCODE_DX9_EXPP , + OPCODE_DX9_LOGP , + OPCODE_DX9_CND , + OPCODE_DX9_DEF , + OPCODE_DX9_TEXREG2RGB , + OPCODE_DX9_TEXDP3TEX , + OPCODE_DX9_TEXM3x2DEPTH , + OPCODE_DX9_TEXDP3 , + OPCODE_DX9_TEXM3x3 , + OPCODE_DX9_TEXDEPTH , + OPCODE_DX9_CMP , + OPCODE_DX9_BEM , + OPCODE_DX9_DP2ADD , + OPCODE_DX9_DSX , + OPCODE_DX9_DSY , + OPCODE_DX9_TEXLDD , + OPCODE_DX9_SETP , + OPCODE_DX9_TEXLDL , + OPCODE_DX9_BREAKP , + + OPCODE_DX9_PHASE = 0xFFFD, + OPCODE_DX9_COMMENT = 0xFFFE, + OPCODE_DX9_END = 0xFFFF, + + OPCODE_DX9_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} OPCODE_TYPE_DX9; + +static OPCODE_TYPE_DX9 DecodeOpcodeTypeDX9(const uint32_t ui32Token) +{ + return (OPCODE_TYPE_DX9)(ui32Token & 0x0000FFFF); +} + +static uint32_t DecodeInstructionLengthDX9(const uint32_t ui32Token) +{ + return (ui32Token & 0x0F000000)>>24; +} + +static uint32_t DecodeCommentLengthDX9(const uint32_t ui32Token) +{ + return (ui32Token & 0x7FFF0000)>>16; +} + +static uint32_t DecodeOperandRegisterNumberDX9(const uint32_t ui32Token) +{ + return ui32Token & 0x000007FF; +} + +typedef enum +{ + OPERAND_TYPE_DX9_TEMP = 0, // Temporary Register File + OPERAND_TYPE_DX9_INPUT = 1, // Input Register File + OPERAND_TYPE_DX9_CONST = 2, // Constant Register File + OPERAND_TYPE_DX9_ADDR = 3, // Address Register (VS) + OPERAND_TYPE_DX9_TEXTURE = 3, // Texture Register File (PS) + OPERAND_TYPE_DX9_RASTOUT = 4, // Rasterizer Register File + OPERAND_TYPE_DX9_ATTROUT = 5, // Attribute Output Register File + OPERAND_TYPE_DX9_TEXCRDOUT = 6, // Texture Coordinate Output Register File + OPERAND_TYPE_DX9_OUTPUT = 6, // Output register file for VS3.0+ + OPERAND_TYPE_DX9_CONSTINT = 7, // Constant Integer Vector Register File + OPERAND_TYPE_DX9_COLOROUT = 8, // Color Output Register File + OPERAND_TYPE_DX9_DEPTHOUT = 9, // Depth Output Register File + OPERAND_TYPE_DX9_SAMPLER = 10, // Sampler State Register File + OPERAND_TYPE_DX9_CONST2 = 11, // Constant Register File 2048 - 4095 + OPERAND_TYPE_DX9_CONST3 = 12, // Constant Register File 4096 - 6143 + OPERAND_TYPE_DX9_CONST4 = 13, // Constant Register File 6144 - 8191 + OPERAND_TYPE_DX9_CONSTBOOL = 14, // Constant Boolean register file + OPERAND_TYPE_DX9_LOOP = 15, // Loop counter register file + OPERAND_TYPE_DX9_TEMPFLOAT16 = 16, // 16-bit float temp register file + OPERAND_TYPE_DX9_MISCTYPE = 17, // Miscellaneous (single) registers. + OPERAND_TYPE_DX9_LABEL = 18, // Label + OPERAND_TYPE_DX9_PREDICATE = 19, // Predicate register + OPERAND_TYPE_DX9_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} OPERAND_TYPE_DX9; + +static OPERAND_TYPE_DX9 DecodeOperandTypeDX9(const uint32_t ui32Token) +{ + return (OPERAND_TYPE_DX9)(((ui32Token & 0x70000000) >> 28) | + ((ui32Token & 0x00001800) >> 8)); +} + +static uint32_t CreateOperandTokenDX9(const uint32_t ui32RegNum, const OPERAND_TYPE_DX9 eType) +{ + uint32_t ui32Token = ui32RegNum; + ASSERT(ui32RegNum <2048); + ui32Token |= (eType <<28) & 0x70000000; + ui32Token |= (eType <<8) & 0x00001800; + return ui32Token; +} + +typedef enum { + DECLUSAGE_POSITION = 0, + DECLUSAGE_BLENDWEIGHT = 1, + DECLUSAGE_BLENDINDICES = 2, + DECLUSAGE_NORMAL = 3, + DECLUSAGE_PSIZE = 4, + DECLUSAGE_TEXCOORD = 5, + DECLUSAGE_TANGENT = 6, + DECLUSAGE_BINORMAL = 7, + DECLUSAGE_TESSFACTOR = 8, + DECLUSAGE_POSITIONT = 9, + DECLUSAGE_COLOR = 10, + DECLUSAGE_FOG = 11, + DECLUSAGE_DEPTH = 12, + DECLUSAGE_SAMPLE = 13 +} DECLUSAGE_DX9; + +static DECLUSAGE_DX9 DecodeUsageDX9(const uint32_t ui32Token) +{ + return (DECLUSAGE_DX9) (ui32Token & 0x0000000f); +} + +static uint32_t DecodeUsageIndexDX9(const uint32_t ui32Token) +{ + return (ui32Token & 0x000f0000)>>16; +} + +static uint32_t DecodeOperandIsRelativeAddressModeDX9(const uint32_t ui32Token) +{ + return ui32Token & (1<<13); +} + +static const uint32_t DX9_SWIZZLE_SHIFT = 16; +#define NO_SWIZZLE_DX9 ((0<>16); +} diff --git a/build/tools/HLSLcc/May_2014/src/reflect.c b/build/tools/HLSLcc/May_2014/src/reflect.c new file mode 100644 index 0000000..297f19f --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/reflect.c @@ -0,0 +1,1085 @@ + +#include "internal_includes/reflect.h" +#include "internal_includes/debug.h" +#include "internal_includes/decode.h" +#include "internal_includes/hlslcc_malloc.h" +#include "bstrlib.h" +#include +#include + +static void FormatVariableName(char* Name) +{ + /* MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/bb944006(v=vs.85).aspx + The uniform function parameters appear in the + constant table prepended with a dollar sign ($), + unlike the global variables. The dollar sign is + required to avoid name collisions between local + uniform inputs and global variables of the same name.*/ + + /* Leave $ThisPointer, $Element and $Globals as-is. + Otherwise remove $ character ($ is not a valid character for GLSL variable names). */ + if(Name[0] == '$') + { + if(strcmp(Name, "$Element") !=0 && + strcmp(Name, "$Globals") != 0 && + strcmp(Name, "$ThisPointer") != 0) + { + Name[0] = '_'; + } + } +} + +static void FormatConstantName(char* Name, char* cbName, int varIndex) +{ + _snprintf(Name, MAX_REFLECT_STRING_LENGTH, "%s_%d", cbName, varIndex); +} + +static void ReadStringFromTokenStream(const uint32_t* tokens, char* str) +{ + char* charTokens = (char*) tokens; + char nextCharacter = *charTokens++; + int length = 0; + + //Add each individual character until + //a terminator is found. + while(nextCharacter != 0) { + + str[length++] = nextCharacter; + + if(length > MAX_REFLECT_STRING_LENGTH) + { + str[length-1] = '\0'; + return; + } + + nextCharacter = *charTokens++; + } + + str[length] = '\0'; +} + +static void ReadInputSignatures(const uint32_t* pui32Tokens, + ShaderInfo* psShaderInfo, + const int extended) +{ + uint32_t i; + + InOutSignature* psSignatures; + const uint32_t* pui32FirstSignatureToken = pui32Tokens; + const uint32_t ui32ElementCount = *pui32Tokens++; + const uint32_t ui32Key = *pui32Tokens++; + + psSignatures = hlslcc_malloc(sizeof(InOutSignature) * ui32ElementCount); + psShaderInfo->psInputSignatures = psSignatures; + psShaderInfo->ui32NumInputSignatures = ui32ElementCount; + + for(i=0; iui32Stream = 0; + psCurrentSignature->eMinPrec = D3D_MIN_PRECISION_DEFAULT; + + if(extended) + psCurrentSignature->ui32Stream = *pui32Tokens++; + + ui32SemanticNameOffset = *pui32Tokens++; + psCurrentSignature->ui32SemanticIndex = *pui32Tokens++; + psCurrentSignature->eSystemValueType = (SPECIAL_NAME) *pui32Tokens++; + psCurrentSignature->eComponentType = (INOUT_COMPONENT_TYPE) *pui32Tokens++; + psCurrentSignature->ui32Register = *pui32Tokens++; + + ui32ComponentMasks = *pui32Tokens++; + psCurrentSignature->ui32Mask = ui32ComponentMasks & 0x7F; + //Shows which components are read + psCurrentSignature->ui32ReadWriteMask = (ui32ComponentMasks & 0x7F00) >> 8; + + if(extended) + psCurrentSignature->eMinPrec = *pui32Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken+ui32SemanticNameOffset), psCurrentSignature->SemanticName); + } +} + +static void ReadOutputSignatures(const uint32_t* pui32Tokens, + ShaderInfo* psShaderInfo, + const int minPrec, + const int streams) +{ + uint32_t i; + + InOutSignature* psSignatures; + const uint32_t* pui32FirstSignatureToken = pui32Tokens; + const uint32_t ui32ElementCount = *pui32Tokens++; + const uint32_t ui32Key = *pui32Tokens++; + + psSignatures = hlslcc_malloc(sizeof(InOutSignature) * ui32ElementCount); + psShaderInfo->psOutputSignatures = psSignatures; + psShaderInfo->ui32NumOutputSignatures = ui32ElementCount; + + for(i=0; iui32Stream = 0; + psCurrentSignature->eMinPrec = D3D_MIN_PRECISION_DEFAULT; + + if(streams) + psCurrentSignature->ui32Stream = *pui32Tokens++; + + ui32SemanticNameOffset = *pui32Tokens++; + psCurrentSignature->ui32SemanticIndex = *pui32Tokens++; + psCurrentSignature->eSystemValueType = (SPECIAL_NAME)*pui32Tokens++; + psCurrentSignature->eComponentType = (INOUT_COMPONENT_TYPE) *pui32Tokens++; + psCurrentSignature->ui32Register = *pui32Tokens++; + + ui32ComponentMasks = *pui32Tokens++; + psCurrentSignature->ui32Mask = ui32ComponentMasks & 0x7F; + //Shows which components are NEVER written. + psCurrentSignature->ui32ReadWriteMask = (ui32ComponentMasks & 0x7F00) >> 8; + + if(minPrec) + psCurrentSignature->eMinPrec = *pui32Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken+ui32SemanticNameOffset), psCurrentSignature->SemanticName); + } +} + +static const uint32_t* ReadResourceBinding(const uint32_t* pui32FirstResourceToken, const uint32_t* pui32Tokens, ResourceBinding* psBinding) +{ + uint32_t ui32NameOffset = *pui32Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstResourceToken+ui32NameOffset), psBinding->Name); + FormatVariableName(psBinding->Name); + + psBinding->eType = *pui32Tokens++; + psBinding->ui32ReturnType = *pui32Tokens++; + psBinding->eDimension = (REFLECT_RESOURCE_DIMENSION)*pui32Tokens++; + psBinding->ui32NumSamples = *pui32Tokens++; + psBinding->ui32BindPoint = *pui32Tokens++; + psBinding->ui32BindCount = *pui32Tokens++; + psBinding->ui32Flags = *pui32Tokens++; + + return pui32Tokens; +} + +//Read D3D11_SHADER_TYPE_DESC +static void ReadShaderVariableType(const uint32_t ui32MajorVersion, + const uint32_t* pui32FirstConstBufToken, + const uint32_t* pui32tokens, ShaderVarType* varType) +{ + const uint16_t* pui16Tokens = (const uint16_t*) pui32tokens; + uint16_t ui32MemberCount; + uint32_t ui32MemberOffset; + const uint32_t* pui32MemberTokens; + uint32_t i; + + varType->Class = (SHADER_VARIABLE_CLASS)pui16Tokens[0]; + varType->Type = (SHADER_VARIABLE_TYPE)pui16Tokens[1]; + varType->Rows = pui16Tokens[2]; + varType->Columns = pui16Tokens[3]; + varType->Elements = pui16Tokens[4]; + + varType->MemberCount = ui32MemberCount = pui16Tokens[5]; + varType->Members = 0; + + if(varType->ParentCount) + { + ASSERT( (strlen(varType->Parent->FullName) + 1 + strlen(varType->Name) + 1 + 2) < MAX_REFLECT_STRING_LENGTH); + + strcpy(varType->FullName, varType->Parent->FullName); + strcat(varType->FullName, "."); + strcat(varType->FullName, varType->Name); + } + + if(ui32MemberCount) + { + varType->Members = (ShaderVarType*)hlslcc_malloc(sizeof(ShaderVarType)*ui32MemberCount); + + ui32MemberOffset = pui32tokens[3]; + + pui32MemberTokens = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32MemberOffset); + + for(i=0; i< ui32MemberCount; ++i) + { + uint32_t ui32NameOffset = *pui32MemberTokens++; + uint32_t ui32MemberTypeOffset = *pui32MemberTokens++; + + varType->Members[i].Parent = varType; + varType->Members[i].ParentCount = varType->ParentCount + 1; + + varType->Members[i].Offset = *pui32MemberTokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken+ui32NameOffset), varType->Members[i].Name); + + ReadShaderVariableType(ui32MajorVersion, pui32FirstConstBufToken, + (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32MemberTypeOffset), &varType->Members[i]); + } + } +} + +static const uint32_t* ReadConstantBuffer(ShaderInfo* psShaderInfo, + const uint32_t* pui32FirstConstBufToken, const uint32_t* pui32Tokens, ConstantBuffer* psBuffer) +{ + uint32_t i; + uint32_t ui32NameOffset = *pui32Tokens++; + uint32_t ui32VarCount = *pui32Tokens++; + uint32_t ui32VarOffset = *pui32Tokens++; + const uint32_t* pui32VarToken = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32VarOffset); + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken+ui32NameOffset), psBuffer->Name); + FormatVariableName(psBuffer->Name); + + psBuffer->ui32NumVars = ui32VarCount; + + for(i=0; iasVars[i]; + + uint32_t ui32Flags; + uint32_t ui32TypeOffset; + uint32_t ui32DefaultValueOffset; + + ui32NameOffset = *pui32VarToken++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken+ui32NameOffset), psVar->Name); + //FormatVariableName(psVar->Name); + FormatConstantName(psVar->Name, psBuffer->Name, i); + + psVar->ui32StartOffset = *pui32VarToken++; + psVar->ui32Size = *pui32VarToken++; + ui32Flags = *pui32VarToken++; + ui32TypeOffset = *pui32VarToken++; + + strcpy(psVar->sType.Name, psVar->Name); + strcpy(psVar->sType.FullName, psVar->Name); + psVar->sType.Parent = 0; + psVar->sType.ParentCount = 0; + psVar->sType.Offset = 0; + + ReadShaderVariableType(psShaderInfo->ui32MajorVersion, pui32FirstConstBufToken, + (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32TypeOffset), &psVar->sType); + + ui32DefaultValueOffset = *pui32VarToken++; + + + if (psShaderInfo->ui32MajorVersion >= 5) + { + uint32_t StartTexture = *pui32VarToken++; + uint32_t TextureSize = *pui32VarToken++; + uint32_t StartSampler = *pui32VarToken++; + uint32_t SamplerSize = *pui32VarToken++; + } + + psVar->haveDefaultValue = 0; + + if(ui32DefaultValueOffset) + { + uint32_t i = 0; + const uint32_t ui32NumDefaultValues = psVar->ui32Size / 4; + const uint32_t* pui32DefaultValToken = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32DefaultValueOffset); + + //Always a sequence of 4-bytes at the moment. + //bool const becomes 0 or 0xFFFFFFFF int, int & float are 4-bytes. + ASSERT(psVar->ui32Size%4 == 0); + + psVar->haveDefaultValue = 1; + + psVar->pui32DefaultValues = hlslcc_malloc(psVar->ui32Size); + + for(i=0; ipui32DefaultValues[i] = pui32DefaultValToken[i]; + } + } + } + + + { + uint32_t ui32Flags; + uint32_t ui32BufferType; + + psBuffer->ui32TotalSizeInBytes = *pui32Tokens++; + ui32Flags = *pui32Tokens++; + ui32BufferType = *pui32Tokens++; + } + + return pui32Tokens; +} + +static void ReadResources(const uint32_t* pui32Tokens,//in + ShaderInfo* psShaderInfo)//out +{ + ResourceBinding* psResBindings; + ConstantBuffer* psConstantBuffers; + const uint32_t* pui32ConstantBuffers; + const uint32_t* pui32ResourceBindings; + const uint32_t* pui32FirstToken = pui32Tokens; + uint32_t i; + + const uint32_t ui32NumConstantBuffers = *pui32Tokens++; + const uint32_t ui32ConstantBufferOffset = *pui32Tokens++; + + uint32_t ui32NumResourceBindings = *pui32Tokens++; + uint32_t ui32ResourceBindingOffset = *pui32Tokens++; + uint32_t ui32ShaderModel = *pui32Tokens++; + uint32_t ui32CompileFlags = *pui32Tokens++;//D3DCompile flags? http://msdn.microsoft.com/en-us/library/gg615083(v=vs.85).aspx + + //Resources + pui32ResourceBindings = (const uint32_t*)((const char*)pui32FirstToken + ui32ResourceBindingOffset); + + psResBindings = hlslcc_malloc(sizeof(ResourceBinding)*ui32NumResourceBindings); + + psShaderInfo->ui32NumResourceBindings = ui32NumResourceBindings; + psShaderInfo->psResourceBindings = psResBindings; + + for(i=0; i < ui32NumResourceBindings; ++i) + { + pui32ResourceBindings = ReadResourceBinding(pui32FirstToken, pui32ResourceBindings, psResBindings+i); + ASSERT(psResBindings[i].ui32BindPoint < MAX_RESOURCE_BINDINGS); + } + + //Constant buffers + pui32ConstantBuffers = (const uint32_t*)((const char*)pui32FirstToken + ui32ConstantBufferOffset); + + psConstantBuffers = hlslcc_malloc(sizeof(ConstantBuffer) * ui32NumConstantBuffers); + + psShaderInfo->ui32NumConstantBuffers = ui32NumConstantBuffers; + psShaderInfo->psConstantBuffers = psConstantBuffers; + + for(i=0; i < ui32NumConstantBuffers; ++i) + { + pui32ConstantBuffers = ReadConstantBuffer(psShaderInfo, pui32FirstToken, pui32ConstantBuffers, psConstantBuffers+i); + } + + + //Map resource bindings to constant buffers + if(psShaderInfo->ui32NumConstantBuffers) + { + for(i=0; i < ui32NumResourceBindings; ++i) + { + ResourceGroup eRGroup; + uint32_t cbufIndex = 0; + + eRGroup = ResourceTypeToResourceGroup(psResBindings[i].eType); + + //Find the constant buffer whose name matches the resource at the given resource binding point + for(cbufIndex=0; cbufIndex < psShaderInfo->ui32NumConstantBuffers; cbufIndex++) + { + if(strcmp(psConstantBuffers[cbufIndex].Name, psResBindings[i].Name) == 0) + { + psShaderInfo->aui32ResourceMap[eRGroup][psResBindings[i].ui32BindPoint] = cbufIndex; + } + } + } + } +} + +static const uint16_t* ReadClassType(const uint32_t* pui32FirstInterfaceToken, const uint16_t* pui16Tokens, ClassType* psClassType) +{ + const uint32_t* pui32Tokens = (const uint32_t*)pui16Tokens; + uint32_t ui32NameOffset = *pui32Tokens; + pui16Tokens+= 2; + + psClassType->ui16ID = *pui16Tokens++; + psClassType->ui16ConstBufStride = *pui16Tokens++; + psClassType->ui16Texture = *pui16Tokens++; + psClassType->ui16Sampler = *pui16Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken+ui32NameOffset), psClassType->Name); + + return pui16Tokens; +} + +static const uint16_t* ReadClassInstance(const uint32_t* pui32FirstInterfaceToken, const uint16_t* pui16Tokens, ClassInstance* psClassInstance) +{ + uint32_t ui32NameOffset = *pui16Tokens++ << 16; + ui32NameOffset |= *pui16Tokens++; + + psClassInstance->ui16ID = *pui16Tokens++; + psClassInstance->ui16ConstBuf = *pui16Tokens++; + psClassInstance->ui16ConstBufOffset = *pui16Tokens++; + psClassInstance->ui16Texture = *pui16Tokens++; + psClassInstance->ui16Sampler = *pui16Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken+ui32NameOffset), psClassInstance->Name); + + return pui16Tokens; +} + + +static void ReadInterfaces(const uint32_t* pui32Tokens, + ShaderInfo* psShaderInfo) +{ + uint32_t i; + uint32_t ui32StartSlot; + const uint32_t* pui32FirstInterfaceToken = pui32Tokens; + const uint32_t ui32ClassInstanceCount = *pui32Tokens++; + const uint32_t ui32ClassTypeCount = *pui32Tokens++; + const uint32_t ui32InterfaceSlotRecordCount = *pui32Tokens++; + const uint32_t ui32InterfaceSlotCount = *pui32Tokens++; + const uint32_t ui32ClassInstanceOffset = *pui32Tokens++; + const uint32_t ui32ClassTypeOffset = *pui32Tokens++; + const uint32_t ui32InterfaceSlotOffset = *pui32Tokens++; + + const uint16_t* pui16ClassTypes = (const uint16_t*)((const char*)pui32FirstInterfaceToken + ui32ClassTypeOffset); + const uint16_t* pui16ClassInstances = (const uint16_t*)((const char*)pui32FirstInterfaceToken + ui32ClassInstanceOffset); + const uint32_t* pui32InterfaceSlots = (const uint32_t*)((const char*)pui32FirstInterfaceToken + ui32InterfaceSlotOffset); + + const uint32_t* pui32InterfaceSlotTokens = pui32InterfaceSlots; + + ClassType* psClassTypes; + ClassInstance* psClassInstances; + + psClassTypes = hlslcc_malloc(sizeof(ClassType) * ui32ClassTypeCount); + for(i=0; iaui32TableIDToTypeID[*pui32TableID++] = *pui16TypeID++; + } + + ui32StartSlot += ui32SlotSpan; + } + + psShaderInfo->ui32NumClassInstances = ui32ClassInstanceCount; + psShaderInfo->psClassInstances = psClassInstances; + + psShaderInfo->ui32NumClassTypes = ui32ClassTypeCount; + psShaderInfo->psClassTypes = psClassTypes; +} + +void GetConstantBufferFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ShaderInfo* psShaderInfo, ConstantBuffer** ppsConstBuf) +{ + if(psShaderInfo->ui32MajorVersion > 3) + { + *ppsConstBuf = psShaderInfo->psConstantBuffers + psShaderInfo->aui32ResourceMap[eGroup][ui32BindPoint]; + } + else + { + ASSERT(psShaderInfo->ui32NumConstantBuffers == 1); + *ppsConstBuf = psShaderInfo->psConstantBuffers; + } +} + +int GetResourceFromBindingPoint(const ResourceGroup eGroup, uint32_t const ui32BindPoint, const ShaderInfo* psShaderInfo, ResourceBinding** ppsOutBinding) +{ + uint32_t i; + const uint32_t ui32NumBindings = psShaderInfo->ui32NumResourceBindings; + ResourceBinding* psBindings = psShaderInfo->psResourceBindings; + + for(i=0; i= psBindings[i].ui32BindPoint && ui32BindPoint < (psBindings[i].ui32BindPoint + psBindings[i].ui32BindCount)) + { + *ppsOutBinding = psBindings + i; + return 1; + } + } + } + return 0; +} + +int GetInterfaceVarFromOffset(uint32_t ui32Offset, ShaderInfo* psShaderInfo, ShaderVar** ppsShaderVar) +{ + uint32_t i; + ConstantBuffer* psThisPointerConstBuffer = psShaderInfo->psThisPointerConstBuffer; + + const uint32_t ui32NumVars = psThisPointerConstBuffer->ui32NumVars; + + for(i=0; i= psThisPointerConstBuffer->asVars[i].ui32StartOffset && + ui32Offset < (psThisPointerConstBuffer->asVars[i].ui32StartOffset + psThisPointerConstBuffer->asVars[i].ui32Size)) + { + *ppsShaderVar = &psThisPointerConstBuffer->asVars[i]; + return 1; + } + } + return 0; +} + +int GetInputSignatureFromRegister(const uint32_t ui32Register, const ShaderInfo* psShaderInfo, InOutSignature** ppsOut) +{ + uint32_t i; + const uint32_t ui32NumVars = psShaderInfo->ui32NumInputSignatures; + + for(i=0; ipsInputSignatures; + if(ui32Register == psInputSignatures[i].ui32Register) + { + *ppsOut = psInputSignatures+i; + return 1; + } + } + return 0; +} + +int GetOutputSignatureFromRegister(const uint32_t ui32Register, + const uint32_t ui32CompMask, + const uint32_t ui32Stream, + ShaderInfo* psShaderInfo, + InOutSignature** ppsOut) +{ + uint32_t i; + const uint32_t ui32NumVars = psShaderInfo->ui32NumOutputSignatures; + + for(i=0; ipsOutputSignatures; + if(ui32Register == psOutputSignatures[i].ui32Register && + (ui32CompMask & psOutputSignatures[i].ui32Mask) && + ui32Stream == psOutputSignatures[i].ui32Stream) + { + *ppsOut = psOutputSignatures+i; + return 1; + } + } + return 0; +} + +int GetOutputSignatureFromSystemValue(SPECIAL_NAME eSystemValueType, uint32_t ui32SemanticIndex, ShaderInfo* psShaderInfo, InOutSignature** ppsOut) +{ + uint32_t i; + const uint32_t ui32NumVars = psShaderInfo->ui32NumOutputSignatures; + + for(i=0; ipsOutputSignatures; + if(eSystemValueType == psOutputSignatures[i].eSystemValueType && + ui32SemanticIndex == psOutputSignatures[i].ui32SemanticIndex) + { + *ppsOut = psOutputSignatures+i; + return 1; + } + } + return 0; +} + +static int IsOffsetInType(ShaderVarType* psType, + uint32_t parentOffset, + uint32_t offsetToFind, + const uint32_t* pui32Swizzle, + int32_t* pi32Index, + int32_t* pi32Rebase) +{ + uint32_t thisOffset = parentOffset + psType->Offset; + uint32_t thisSize = psType->Columns * psType->Rows * 4; + + if(psType->Elements) + { + thisSize *= psType->Elements; + } + + //Swizzle can point to another variable. In the example below + //cbUIUpdates.g_uMaxFaces would be cb1[2].z. The scalars are combined + //into vectors. psCBuf->ui32NumVars will be 3. + + // cbuffer cbUIUpdates + // { + // + // float g_fLifeSpan; // Offset: 0 Size: 4 + // float g_fLifeSpanVar; // Offset: 4 Size: 4 [unused] + // float g_fRadiusMin; // Offset: 8 Size: 4 [unused] + // float g_fRadiusMax; // Offset: 12 Size: 4 [unused] + // float g_fGrowTime; // Offset: 16 Size: 4 [unused] + // float g_fStepSize; // Offset: 20 Size: 4 + // float g_fTurnRate; // Offset: 24 Size: 4 + // float g_fTurnSpeed; // Offset: 28 Size: 4 [unused] + // float g_fLeafRate; // Offset: 32 Size: 4 + // float g_fShrinkTime; // Offset: 36 Size: 4 [unused] + // uint g_uMaxFaces; // Offset: 40 Size: 4 + // + // } + + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // cbUIUpdates cbuffer NA NA 1 1 + + if(pui32Swizzle[0] == OPERAND_4_COMPONENT_Y) + { + offsetToFind += 4; + } + else + if(pui32Swizzle[0] == OPERAND_4_COMPONENT_Z) + { + offsetToFind += 8; + } + else + if(pui32Swizzle[0] == OPERAND_4_COMPONENT_W) + { + offsetToFind += 12; + } + + if((offsetToFind >= thisOffset) && + offsetToFind < (thisOffset + thisSize)) + { + + if(psType->Class == SVC_MATRIX_ROWS || + psType->Class == SVC_MATRIX_COLUMNS) + { + //Matrices are treated as arrays of vectors. + pi32Index[0] = (offsetToFind - thisOffset) / 16; + } + //Check for array of vectors + else if(psType->Class == SVC_VECTOR && psType->Elements > 1) + { + pi32Index[0] = (offsetToFind - thisOffset) / 16; + } + else if(psType->Class == SVC_VECTOR && psType->Columns > 1) + { + //Check for vector starting at a non-vec4 offset. + + // cbuffer $Globals + // { + // + // float angle; // Offset: 0 Size: 4 + // float2 angle2; // Offset: 4 Size: 8 + // + // } + + //cb0[0].x = angle + //cb0[0].yzyy = angle2.xyxx + + //Rebase angle2 so that .y maps to .x, .z maps to .y + + pi32Rebase[0] = thisOffset % 16; + } + + return 1; + } + return 0; +} + +int GetShaderVarFromOffset(const uint32_t ui32Vec4Offset, + const uint32_t* pui32Swizzle, + ConstantBuffer* psCBuf, + ShaderVarType** ppsShaderVar, + int32_t* pi32Index, + int32_t* pi32Rebase) +{ + uint32_t i; + const uint32_t ui32BaseByteOffset = ui32Vec4Offset * 16; + + uint32_t ui32ByteOffset = ui32Vec4Offset * 16; + + const uint32_t ui32NumVars = psCBuf->ui32NumVars; + + for(i=0; iasVars[i].sType.Class == SVC_STRUCT) + { + uint32_t m = 0; + + for(m=0; m < psCBuf->asVars[i].sType.MemberCount; ++m) + { + ShaderVarType* psMember = psCBuf->asVars[i].sType.Members + m; + + ASSERT(psMember->Class != SVC_STRUCT); + + if(IsOffsetInType(psMember, psCBuf->asVars[i].ui32StartOffset, ui32ByteOffset, pui32Swizzle, pi32Index, pi32Rebase)) + { + ppsShaderVar[0] = psMember; + return 1; + } + } + } + else + { + if(IsOffsetInType(&psCBuf->asVars[i].sType, psCBuf->asVars[i].ui32StartOffset, ui32ByteOffset, pui32Swizzle, pi32Index, pi32Rebase)) + { + ppsShaderVar[0] = &psCBuf->asVars[i].sType; + return 1; + } + } + } + return 0; +} + +ResourceGroup ResourceTypeToResourceGroup(ResourceType eType) +{ + switch(eType) + { + case RTYPE_CBUFFER: + return RGROUP_CBUFFER; + + case RTYPE_SAMPLER: + return RGROUP_SAMPLER; + + case RTYPE_TEXTURE: + case RTYPE_BYTEADDRESS: + case RTYPE_STRUCTURED: + return RGROUP_TEXTURE; + + case RTYPE_UAV_RWTYPED: + case RTYPE_UAV_RWSTRUCTURED: + case RTYPE_UAV_RWBYTEADDRESS: + case RTYPE_UAV_APPEND_STRUCTURED: + case RTYPE_UAV_CONSUME_STRUCTURED: + case RTYPE_UAV_RWSTRUCTURED_WITH_COUNTER: + return RGROUP_UAV; + + case RTYPE_TBUFFER: + ASSERT(0); // Need to find out which group this belongs to + return RGROUP_TEXTURE; + } + + ASSERT(0); + return RGROUP_CBUFFER; +} + +void LoadShaderInfo(const uint32_t ui32MajorVersion, + const uint32_t ui32MinorVersion, + const ReflectionChunks* psChunks, + ShaderInfo* psInfo) +{ + const uint32_t* pui32Inputs = psChunks->pui32Inputs; + const uint32_t* pui32Inputs11 = psChunks->pui32Inputs11; + const uint32_t* pui32Resources = psChunks->pui32Resources; + const uint32_t* pui32Interfaces = psChunks->pui32Interfaces; + const uint32_t* pui32Outputs = psChunks->pui32Outputs; + const uint32_t* pui32Outputs11 = psChunks->pui32Outputs11; + const uint32_t* pui32OutputsWithStreams = psChunks->pui32OutputsWithStreams; + + psInfo->eTessOutPrim = TESSELLATOR_OUTPUT_UNDEFINED; + psInfo->eTessPartitioning = TESSELLATOR_PARTITIONING_UNDEFINED; + + psInfo->ui32MajorVersion = ui32MajorVersion; + psInfo->ui32MinorVersion = ui32MinorVersion; + + + if(pui32Inputs) + ReadInputSignatures(pui32Inputs, psInfo, 0); + if(pui32Inputs11) + ReadInputSignatures(pui32Inputs11, psInfo, 1); + if(pui32Resources) + ReadResources(pui32Resources, psInfo); + if(pui32Interfaces) + ReadInterfaces(pui32Interfaces, psInfo); + if(pui32Outputs) + ReadOutputSignatures(pui32Outputs, psInfo, 0, 0); + if(pui32Outputs11) + ReadOutputSignatures(pui32Outputs11, psInfo, 1, 1); + if(pui32OutputsWithStreams) + ReadOutputSignatures(pui32OutputsWithStreams, psInfo, 0, 1); + + { + uint32_t i; + for(i=0; iui32NumConstantBuffers;++i) + { + bstring cbufName = bfromcstr(&psInfo->psConstantBuffers[i].Name[0]); + bstring cbufThisPointer = bfromcstr("$ThisPointer"); + if(bstrcmp(cbufName, cbufThisPointer) == 0) + { + psInfo->psThisPointerConstBuffer = &psInfo->psConstantBuffers[i]; + } + } + } +} + +void FreeShaderInfo(ShaderInfo* psShaderInfo) +{ + //Free any default values for constants. + uint32_t cbuf; + for(cbuf=0; cbufui32NumConstantBuffers; ++cbuf) + { + ConstantBuffer* psCBuf = &psShaderInfo->psConstantBuffers[cbuf]; + uint32_t var; + for(var=0; var < psCBuf->ui32NumVars; ++var) + { + ShaderVar* psVar = &psCBuf->asVars[var]; + if(psVar->haveDefaultValue) + { + hlslcc_free(psVar->pui32DefaultValues); + } + } + } + hlslcc_free(psShaderInfo->psInputSignatures); + hlslcc_free(psShaderInfo->psResourceBindings); + hlslcc_free(psShaderInfo->psConstantBuffers); + hlslcc_free(psShaderInfo->psClassTypes); + hlslcc_free(psShaderInfo->psClassInstances); + hlslcc_free(psShaderInfo->psOutputSignatures); + + psShaderInfo->ui32NumInputSignatures = 0; + psShaderInfo->ui32NumResourceBindings = 0; + psShaderInfo->ui32NumConstantBuffers = 0; + psShaderInfo->ui32NumClassTypes = 0; + psShaderInfo->ui32NumClassInstances = 0; + psShaderInfo->ui32NumOutputSignatures = 0; +} + +typedef struct ConstantTableD3D9_TAG +{ + uint32_t size; + uint32_t creator; + uint32_t version; + uint32_t constants; + uint32_t constantInfos; + uint32_t flags; + uint32_t target; +} ConstantTableD3D9; + +// These enums match those in d3dx9shader.h. +enum RegisterSet +{ + RS_BOOL, + RS_INT4, + RS_FLOAT4, + RS_SAMPLER, +}; + +enum TypeClass +{ + CLASS_SCALAR, + CLASS_VECTOR, + CLASS_MATRIX_ROWS, + CLASS_MATRIX_COLUMNS, + CLASS_OBJECT, + CLASS_STRUCT, +}; + +enum Type +{ + PT_VOID, + PT_BOOL, + PT_INT, + PT_FLOAT, + PT_STRING, + PT_TEXTURE, + PT_TEXTURE1D, + PT_TEXTURE2D, + PT_TEXTURE3D, + PT_TEXTURECUBE, + PT_SAMPLER, + PT_SAMPLER1D, + PT_SAMPLER2D, + PT_SAMPLER3D, + PT_SAMPLERCUBE, + PT_PIXELSHADER, + PT_VERTEXSHADER, + PT_PIXELFRAGMENT, + PT_VERTEXFRAGMENT, + PT_UNSUPPORTED, +}; +typedef struct ConstantInfoD3D9_TAG +{ + uint32_t name; + uint16_t registerSet; + uint16_t registerIndex; + uint16_t registerCount; + uint16_t reserved; + uint32_t typeInfo; + uint32_t defaultValue; +} ConstantInfoD3D9; + +typedef struct TypeInfoD3D9_TAG +{ + uint16_t typeClass; + uint16_t type; + uint16_t rows; + uint16_t columns; + uint16_t elements; + uint16_t structMembers; + uint32_t structMemberInfos; +} TypeInfoD3D9; + +typedef struct StructMemberInfoD3D9_TAG +{ + uint32_t name; + uint32_t typeInfo; +} StructMemberInfoD3D9; + +void LoadD3D9ConstantTable(const char* data, + ShaderInfo* psInfo) +{ + ConstantTableD3D9* ctab; + uint32_t constNum; + ConstantInfoD3D9* cinfos; + ConstantBuffer* psConstantBuffer; + uint32_t ui32ConstantBufferSize = 0; + uint32_t numResourceBindingsNeeded = 0; + ShaderVar* var; + + ctab = (ConstantTableD3D9*)data; + + cinfos = (ConstantInfoD3D9*) (data + ctab->constantInfos); + + psInfo->ui32NumConstantBuffers++; + + //Only 1 Constant Table in d3d9 + ASSERT(psInfo->ui32NumConstantBuffers==1); + + psConstantBuffer = hlslcc_malloc(sizeof(ConstantBuffer)); + + psInfo->psConstantBuffers = psConstantBuffer; + + psConstantBuffer->ui32NumVars = 0; + strcpy(psConstantBuffer->Name, "$Globals"); + + //Determine how many resource bindings to create + for(constNum = 0; constNum < ctab->constants; ++constNum) + { + if(cinfos[constNum].registerSet == RS_SAMPLER) + { + ++numResourceBindingsNeeded; + } + } + + psInfo->psResourceBindings = hlslcc_malloc(numResourceBindingsNeeded*sizeof(ResourceBinding)); + + var = &psConstantBuffer->asVars[0]; + + for(constNum = 0; constNum < ctab->constants; ++constNum) + { + TypeInfoD3D9* typeInfo = (TypeInfoD3D9*) (data + cinfos[constNum].typeInfo); + + if(cinfos[constNum].registerSet != RS_SAMPLER) + { + strcpy(var->Name, data + cinfos[constNum].name); + FormatVariableName(var->Name); + var->ui32Size = cinfos[constNum].registerCount * 16; + var->ui32StartOffset = cinfos[constNum].registerIndex * 16; + var->haveDefaultValue = 0; + + if(ui32ConstantBufferSize < (var->ui32Size + var->ui32StartOffset)) + { + ui32ConstantBufferSize = var->ui32Size + var->ui32StartOffset; + } + + var->sType.Rows = typeInfo->rows; + var->sType.Columns = typeInfo->columns; + var->sType.Elements = typeInfo->elements; + var->sType.MemberCount = typeInfo->structMembers; + var->sType.Members = 0; + var->sType.Offset = 0; + strcpy(var->sType.FullName, var->Name); + var->sType.Parent = 0; + var->sType.ParentCount = 0; + + switch(typeInfo->typeClass) + { + case CLASS_SCALAR: + { + var->sType.Class = SVC_SCALAR; + break; + } + case CLASS_VECTOR: + { + var->sType.Class = SVC_VECTOR; + break; + } + case CLASS_MATRIX_ROWS: + { + var->sType.Class = SVC_MATRIX_ROWS; + break; + } + case CLASS_MATRIX_COLUMNS: + { + var->sType.Class = SVC_MATRIX_COLUMNS; + break; + } + case CLASS_OBJECT: + { + var->sType.Class = SVC_OBJECT; + break; + } + case CLASS_STRUCT: + { + var->sType.Class = SVC_STRUCT; + break; + } + } + + switch(cinfos[constNum].registerSet) + { + case RS_BOOL: + { + var->sType.Type = SVT_BOOL; + break; + } + case RS_INT4: + { + var->sType.Type = SVT_INT; + break; + } + case RS_FLOAT4: + { + var->sType.Type = SVT_FLOAT; + break; + } + } + + var++; + psConstantBuffer->ui32NumVars++; + } + else + { + //Create a resource if it is sampler in order to replicate the d3d10+ + //method of separating samplers from general constants. + uint32_t ui32ResourceIndex = psInfo->ui32NumResourceBindings++; + ResourceBinding* res = &psInfo->psResourceBindings[ui32ResourceIndex]; + + strcpy(res->Name, data + cinfos[constNum].name); + FormatVariableName(res->Name); + + res->ui32BindPoint = cinfos[constNum].registerIndex; + res->ui32BindCount = cinfos[constNum].registerCount; + res->ui32Flags = 0; + res->ui32NumSamples = 1; + res->ui32ReturnType = 0; + + res->eType = RTYPE_TEXTURE; + + switch(typeInfo->type) + { + case PT_SAMPLER: + case PT_SAMPLER1D: + res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURE1D; + break; + case PT_SAMPLER2D: + res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURE2D; + break; + case PT_SAMPLER3D: + res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURE2D; + break; + case PT_SAMPLERCUBE: + res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURECUBE; + break; + } + } + } + psConstantBuffer->ui32TotalSizeInBytes = ui32ConstantBufferSize; +} diff --git a/build/tools/HLSLcc/May_2014/src/toGLSL.c b/build/tools/HLSLcc/May_2014/src/toGLSL.c new file mode 100644 index 0000000..471416b --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/toGLSL.c @@ -0,0 +1,900 @@ +#include "internal_includes/tokens.h" +#include "internal_includes/structs.h" +#include "internal_includes/decode.h" +#include "stdlib.h" +#include "stdio.h" +#include "bstrlib.h" +#include "internal_includes/toGLSLInstruction.h" +#include "internal_includes/toGLSLOperand.h" +#include "internal_includes/toGLSLDeclaration.h" +#include "internal_includes/languages.h" +#include "internal_includes/debug.h" +#include "internal_includes/hlslcc_malloc.h" + +#ifndef GL_VERTEX_SHADER_ARB +#define GL_VERTEX_SHADER_ARB 0x8B31 +#endif +#ifndef GL_FRAGMENT_SHADER_ARB +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#endif +#ifndef GL_GEOMETRY_SHADER +#define GL_GEOMETRY_SHADER 0x8DD9 +#endif +#ifndef GL_TESS_EVALUATION_SHADER +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#endif +#ifndef GL_TESS_CONTROL_SHADER +#define GL_TESS_CONTROL_SHADER 0x8E88 +#endif +#ifndef GL_COMPUTE_SHADER +#define GL_COMPUTE_SHADER 0x91B9 +#endif + + +HLSLCC_API void HLSLCC_APIENTRY HLSLcc_SetMemoryFunctions(void* (*malloc_override)(size_t),void* (*calloc_override)(size_t,size_t),void (*free_override)(void *),void* (*realloc_override)(void*,size_t)) +{ + hlslcc_malloc = malloc_override; + hlslcc_calloc = calloc_override; + hlslcc_free = free_override; + hlslcc_realloc = realloc_override; +} + +static void ClearDependencyData(SHADER_TYPE eType, GLSLCrossDependencyData* depends) +{ + if(depends == NULL) + { + return; + } + + switch(eType) + { + case PIXEL_SHADER: + { + uint32_t i; + for(i=0;iaePixelInputInterpolation[i] = INTERPOLATION_UNDEFINED; + } + break; + } + case HULL_SHADER: + { + depends->eTessPartitioning = TESSELLATOR_PARTITIONING_UNDEFINED; + depends->eTessOutPrim = TESSELLATOR_OUTPUT_UNDEFINED; + break; + } + } +} + +void AddIndentation(HLSLCrossCompilerContext* psContext) +{ + int i; + int indent = psContext->indent; + bstring glsl = *psContext->currentGLSLString; + for(i=0; i < indent; ++i) + { + bcatcstr(glsl, " "); + } +} + +void AddVersionDependentCode(HLSLCrossCompilerContext* psContext) +{ + bstring glsl = *psContext->currentGLSLString; + + if(psContext->psShader->ui32MajorVersion <= 3) + { + bcatcstr(glsl, "int RepCounter;\n"); + bcatcstr(glsl, "int LoopCounter;\n"); + bcatcstr(glsl, "int ZeroBasedCounter;\n"); + if(psContext->psShader->eShaderType == VERTEX_SHADER) + { + uint32_t texCoord; + bcatcstr(glsl, "ivec4 Address;\n"); + + if(InOutSupported(psContext->psShader->eTargetLanguage)) + { + bcatcstr(glsl, "out vec4 OffsetColour;\n"); + bcatcstr(glsl, "out vec4 BaseColour;\n"); + + bcatcstr(glsl, "out vec4 Fog;\n"); + + for(texCoord=0; texCoord<8; ++texCoord) + { + bformata(glsl, "out vec4 TexCoord%d;\n", texCoord); + } + } + else + { + bcatcstr(glsl, "varying vec4 OffsetColour;\n"); + bcatcstr(glsl, "varying vec4 BaseColour;\n"); + + bcatcstr(glsl, "varying vec4 Fog;\n"); + + for(texCoord=0; texCoord<8; ++texCoord) + { + bformata(glsl, "varying vec4 TexCoord%d;\n", texCoord); + } + } + } + else + { + uint32_t renderTargets, texCoord; + + bcatcstr(glsl, "varying vec4 OffsetColour;\n"); + bcatcstr(glsl, "varying vec4 BaseColour;\n"); + + bcatcstr(glsl, "varying vec4 Fog;\n"); + + for(texCoord=0; texCoord<8; ++texCoord) + { + bformata(glsl, "varying vec4 TexCoord%d;\n", texCoord); + } + + for(renderTargets=0; renderTargets<8; ++renderTargets) + { + bformata(glsl, "#define Output%d gl_FragData[%d]\n", renderTargets, renderTargets); + } + } + } + + if(!HaveCompute(psContext->psShader->eTargetLanguage)) + { + if(psContext->psShader->eShaderType == COMPUTE_SHADER) + { + bcatcstr(glsl,"#extension GL_ARB_compute_shader : enable\n"); + bcatcstr(glsl,"#extension GL_ARB_shader_storage_buffer_object : enable\n"); + } + } + + if (!HaveAtomicMem(psContext->psShader->eTargetLanguage) || + !HaveAtomicCounter(psContext->psShader->eTargetLanguage)) + { + if( psContext->psShader->aiOpcodeUsed[OPCODE_IMM_ATOMIC_ALLOC] || + psContext->psShader->aiOpcodeUsed[OPCODE_IMM_ATOMIC_CONSUME] || + psContext->psShader->aiOpcodeUsed[OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED]) + { + bcatcstr(glsl,"#extension GL_ARB_shader_atomic_counters : enable\n"); + + bcatcstr(glsl,"#extension GL_ARB_shader_storage_buffer_object : enable\n"); + } + } + + if(!HaveGather(psContext->psShader->eTargetLanguage)) + { + if(psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4] || + psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO_C] || + psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO] || + psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_C]) + { + bcatcstr(glsl,"#extension GL_ARB_texture_gather : enable\n"); + } + } + + if(!HaveGatherNonConstOffset(psContext->psShader->eTargetLanguage)) + { + if(psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO_C] || + psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO]) + { + bcatcstr(glsl,"#extension GL_ARB_gpu_shader5 : enable\n"); + } + } + + if(!HaveQueryLod(psContext->psShader->eTargetLanguage)) + { + if(psContext->psShader->aiOpcodeUsed[OPCODE_LOD]) + { + bcatcstr(glsl,"#extension GL_ARB_texture_query_lod : enable\n"); + } + } + + if(!HaveQueryLevels(psContext->psShader->eTargetLanguage)) + { + if(psContext->psShader->aiOpcodeUsed[OPCODE_RESINFO]) + { + bcatcstr(glsl,"#extension GL_ARB_texture_query_levels : enable\n"); + } + } + + if(!HaveImageLoadStore(psContext->psShader->eTargetLanguage)) + { + if(psContext->psShader->aiOpcodeUsed[OPCODE_STORE_UAV_TYPED] || + psContext->psShader->aiOpcodeUsed[OPCODE_STORE_RAW] || + psContext->psShader->aiOpcodeUsed[OPCODE_STORE_STRUCTURED]) + { + bcatcstr(glsl,"#extension GL_ARB_shader_image_load_store : enable\n"); + bcatcstr(glsl,"#extension GL_ARB_shader_bit_encoding : enable\n"); + } + else + if(psContext->psShader->aiOpcodeUsed[OPCODE_LD_UAV_TYPED] || + psContext->psShader->aiOpcodeUsed[OPCODE_LD_RAW] || + psContext->psShader->aiOpcodeUsed[OPCODE_LD_STRUCTURED]) + { + bcatcstr(glsl,"#extension GL_ARB_shader_image_load_store : enable\n"); + } + } + + + if((psContext->flags & HLSLCC_FLAG_ORIGIN_UPPER_LEFT) + && (psContext->psShader->eTargetLanguage >= LANG_150)) + { + bcatcstr(glsl,"layout(origin_upper_left) in vec4 gl_FragCoord;\n"); + } + + if((psContext->flags & HLSLCC_FLAG_PIXEL_CENTER_INTEGER) + && (psContext->psShader->eTargetLanguage >= LANG_150)) + { + bcatcstr(glsl,"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"); + } + + //The fragment language has no default precision qualifier for floating point types. + if(psContext->psShader->eShaderType == PIXEL_SHADER && + psContext->psShader->eTargetLanguage == LANG_ES_100 || psContext->psShader->eTargetLanguage == LANG_ES_300 ) + { + bcatcstr(glsl,"precision highp float;\n"); + } + + /* For versions which do not support a vec1 (currently all versions) */ + bcatcstr(glsl,"struct vec1 {\n"); + bcatcstr(glsl,"\tfloat x;\n"); + bcatcstr(glsl,"};\n"); + + if(HaveUVec(psContext->psShader->eTargetLanguage)) + { + bcatcstr(glsl,"struct uvec1 {\n"); + bcatcstr(glsl,"\tuint x;\n"); + bcatcstr(glsl,"};\n"); + } + + bcatcstr(glsl,"struct ivec1 {\n"); + bcatcstr(glsl,"\tint x;\n"); + bcatcstr(glsl,"};\n"); + + /* + OpenGL 4.1 API spec: + To use any built-in input or output in the gl_PerVertex block in separable + program objects, shader code must redeclare that block prior to use. + */ + if(psContext->psShader->eShaderType == VERTEX_SHADER && psContext->psShader->eTargetLanguage >= LANG_410) + { + bcatcstr(glsl, "out gl_PerVertex {\n"); + bcatcstr(glsl, "vec4 gl_Position;\n"); + bcatcstr(glsl, "float gl_PointSize;\n"); + bcatcstr(glsl, "float gl_ClipDistance[];"); + bcatcstr(glsl, "};\n"); + } + + /* There is no default precision qualifier for the following sampler types in either the vertex or fragment language: */ + if(psContext->psShader->eTargetLanguage == LANG_ES_300 || psContext->psShader->eTargetLanguage == LANG_ES_310) + { + bcatcstr(glsl,"precision lowp sampler3D;\n"); + bcatcstr(glsl,"precision lowp samplerCubeShadow;\n"); + bcatcstr(glsl,"precision lowp sampler2DShadow;\n"); + bcatcstr(glsl,"precision lowp sampler2DArray;\n"); + bcatcstr(glsl,"precision lowp sampler2DArrayShadow;\n"); + bcatcstr(glsl,"precision lowp isampler2D;\n"); + bcatcstr(glsl,"precision lowp isampler3D;\n"); + bcatcstr(glsl,"precision lowp isamplerCube;\n"); + bcatcstr(glsl,"precision lowp isampler2DArray;\n"); + bcatcstr(glsl,"precision lowp usampler2D;\n"); + bcatcstr(glsl,"precision lowp usampler3D;\n"); + bcatcstr(glsl,"precision lowp usamplerCube;\n"); + bcatcstr(glsl,"precision lowp usampler2DArray;\n"); + + if(psContext->psShader->eTargetLanguage == LANG_ES_310) + { + bcatcstr(glsl,"precision lowp isampler2DMS;\n"); + bcatcstr(glsl,"precision lowp usampler2D;\n"); + bcatcstr(glsl,"precision lowp usampler3D;\n"); + bcatcstr(glsl,"precision lowp usamplerCube;\n"); + bcatcstr(glsl,"precision lowp usampler2DArray;\n"); + bcatcstr(glsl,"precision lowp usampler2DMS;\n"); + bcatcstr(glsl,"precision lowp image2D;\n"); + bcatcstr(glsl,"precision lowp image3D;\n"); + bcatcstr(glsl,"precision lowp imageCube;\n"); + bcatcstr(glsl,"precision lowp image2DArray;\n"); + bcatcstr(glsl,"precision lowp iimage2D;\n"); + bcatcstr(glsl,"precision lowp iimage3D;\n"); + bcatcstr(glsl,"precision lowp iimageCube;\n"); + bcatcstr(glsl,"precision lowp uimage2DArray;\n"); + //Only highp is valid for atomic_uint + bcatcstr(glsl,"precision highp atomic_uint;\n"); + } + } + + if(SubroutinesSupported(psContext->psShader->eTargetLanguage)) + { + bcatcstr(glsl, "subroutine void SubroutineType();\n"); + } +} + +GLLang ChooseLanguage(Shader* psShader) +{ + // Depends on the HLSL shader model extracted from bytecode. + switch(psShader->ui32MajorVersion) + { + case 5: + { + return LANG_430; + } + case 4: + { + return LANG_330; + } + default: + { + return LANG_120; + } + } +} + +const char* GetVersionString(GLLang language) +{ + switch(language) + { + case LANG_ES_100: + { + return "#version 100\n"; + break; + } + case LANG_ES_300: + { + return "#version 300 es\n"; + break; + } + case LANG_ES_310: + { + return "#version 310 es\n"; + break; + } + case LANG_120: + { + return "#version 120\n"; + break; + } + case LANG_130: + { + return "#version 130\n"; + break; + } + case LANG_140: + { + return "#version 140\n"; + break; + } + case LANG_150: + { + return "#version 150\n"; + break; + } + case LANG_330: + { + return "#version 330\n"; + break; + } + case LANG_400: + { + return "#version 400\n"; + break; + } + case LANG_410: + { + return "#version 410\n"; + break; + } + case LANG_420: + { + return "#version 420\n"; + break; + } + case LANG_430: + { + return "#version 430\n"; + break; + } + case LANG_440: + { + return "#version 440\n"; + break; + } + default: + { + return ""; + break; + } + } +} + +void TranslateToGLSL(HLSLCrossCompilerContext* psContext, GLLang* planguage,const GlExtensions *extensions) +{ + bstring glsl; + uint32_t i; + Shader* psShader = psContext->psShader; + GLLang language = *planguage; + const uint32_t ui32InstCount = psShader->ui32InstCount; + const uint32_t ui32DeclCount = psShader->ui32DeclCount; + + psContext->indent = 0; + + if(language == LANG_DEFAULT) + { + language = ChooseLanguage(psShader); + *planguage = language; + } + + glsl = bfromcstralloc (1024, GetVersionString(language)); + + psContext->glsl = glsl; + psContext->earlyMain = bfromcstralloc (1024, ""); + for(i=0; ipostShaderCode[i] = bfromcstralloc (1024, ""); + } + psContext->currentGLSLString = &glsl; + psShader->eTargetLanguage = language; + psShader->extensions = (const struct GlExtensions*)extensions; + psContext->currentPhase = MAIN_PHASE; + + if(extensions) + { + if(extensions->ARB_explicit_attrib_location) + bcatcstr(glsl,"#extension GL_ARB_explicit_attrib_location : require\n"); + if(extensions->ARB_explicit_uniform_location) + bcatcstr(glsl,"#extension GL_ARB_explicit_uniform_location : require\n"); + if(extensions->ARB_shading_language_420pack) + bcatcstr(glsl,"#extension GL_ARB_shading_language_420pack : require\n"); + } + + ClearDependencyData(psShader->eShaderType, psContext->psDependencies); + + AddVersionDependentCode(psContext); + + if(psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT) + { + bcatcstr(glsl, "layout(std140) uniform;\n"); + } + + //Special case. Can have multiple phases. + if(psShader->eShaderType == HULL_SHADER) + { + int haveInstancedForkPhase = 0; + uint32_t forkIndex = 0; + + ConsolidateHullTempVars(psShader); + + for(i=0; i < psShader->ui32HSDeclCount; ++i) + { + TranslateDeclaration(psContext, psShader->psHSDecl+i); + } + + //control + psContext->currentPhase = HS_CTRL_POINT_PHASE; + + if(psShader->ui32HSControlPointDeclCount) + { + bcatcstr(glsl, "//Control point phase declarations\n"); + for(i=0; i < psShader->ui32HSControlPointDeclCount; ++i) + { + TranslateDeclaration(psContext, psShader->psHSControlPointPhaseDecl+i); + } + } + + if(psShader->ui32HSControlPointInstrCount) + { + SetDataTypes(psContext, psShader->psHSControlPointPhaseInstr, psShader->ui32HSControlPointInstrCount); + + bcatcstr(glsl, "void control_point_phase()\n{\n"); + psContext->indent++; + + for(i=0; i < psShader->ui32HSControlPointInstrCount; ++i) + { + TranslateInstruction(psContext, psShader->psHSControlPointPhaseInstr+i); + } + psContext->indent--; + bcatcstr(glsl, "}\n"); + } + + //fork + psContext->currentPhase = HS_FORK_PHASE; + for(forkIndex = 0; forkIndex < psShader->ui32ForkPhaseCount; ++forkIndex) + { + bcatcstr(glsl, "//Fork phase declarations\n"); + for(i=0; i < psShader->aui32HSForkDeclCount[forkIndex]; ++i) + { + TranslateDeclaration(psContext, psShader->apsHSForkPhaseDecl[forkIndex]+i); + if(psShader->apsHSForkPhaseDecl[forkIndex][i].eOpcode == OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT) + { + haveInstancedForkPhase = 1; + } + } + + bformata(glsl, "void fork_phase%d()\n{\n", forkIndex); + psContext->indent++; + + SetDataTypes(psContext, psShader->apsHSForkPhaseInstr[forkIndex], psShader->aui32HSForkInstrCount[forkIndex]-1); + + if(haveInstancedForkPhase) + { + AddIndentation(psContext); + bformata(glsl, "for(int forkInstanceID = 0; forkInstanceID < HullPhase%dInstanceCount; ++forkInstanceID) {\n", forkIndex); + psContext->indent++; + } + + //The minus one here is remove the return statement at end of phases. + //This is needed otherwise the for loop will only run once. + ASSERT(psShader->apsHSForkPhaseInstr[forkIndex][psShader->aui32HSForkInstrCount[forkIndex]-1].eOpcode == OPCODE_RET); + for(i=0; i < psShader->aui32HSForkInstrCount[forkIndex]-1; ++i) + { + TranslateInstruction(psContext, psShader->apsHSForkPhaseInstr[forkIndex]+i); + } + + if(haveInstancedForkPhase) + { + psContext->indent--; + AddIndentation(psContext); + bcatcstr(glsl, "}\n"); + + if(psContext->havePostShaderCode[psContext->currentPhase]) + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- Post shader code ---\n"); +#endif + bconcat(glsl, psContext->postShaderCode[psContext->currentPhase]); +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- End post shader code ---\n"); +#endif + } + } + + psContext->indent--; + bcatcstr(glsl, "}\n"); + } + + + //join + psContext->currentPhase = HS_JOIN_PHASE; + if(psShader->ui32HSJoinDeclCount) + { + bcatcstr(glsl, "//Join phase declarations\n"); + for(i=0; i < psShader->ui32HSJoinDeclCount; ++i) + { + TranslateDeclaration(psContext, psShader->psHSJoinPhaseDecl+i); + } + } + + if(psShader->ui32HSJoinInstrCount) + { + SetDataTypes(psContext, psShader->psHSJoinPhaseInstr, psShader->ui32HSJoinInstrCount); + + bcatcstr(glsl, "void join_phase()\n{\n"); + psContext->indent++; + + for(i=0; i < psShader->ui32HSJoinInstrCount; ++i) + { + TranslateInstruction(psContext, psShader->psHSJoinPhaseInstr+i); + } + + psContext->indent--; + bcatcstr(glsl, "}\n"); + } + + bcatcstr(glsl, "void main()\n{\n"); + + psContext->indent++; + +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- Start Early Main ---\n"); +#endif + bconcat(glsl, psContext->earlyMain); +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- End Early Main ---\n"); +#endif + + if(psShader->ui32HSControlPointInstrCount) + { + AddIndentation(psContext); + bcatcstr(glsl, "control_point_phase();\n"); + + if(psShader->ui32ForkPhaseCount || psShader->ui32HSJoinInstrCount) + { + AddIndentation(psContext); + bcatcstr(glsl, "barrier();\n"); + } + } + for(forkIndex = 0; forkIndex < psShader->ui32ForkPhaseCount; ++forkIndex) + { + AddIndentation(psContext); + bformata(glsl, "fork_phase%d();\n", forkIndex); + + if(psShader->ui32HSJoinInstrCount || (forkIndex+1 < psShader->ui32ForkPhaseCount)) + { + AddIndentation(psContext); + bcatcstr(glsl, "barrier();\n"); + } + } + if(psShader->ui32HSJoinInstrCount) + { + AddIndentation(psContext); + bcatcstr(glsl, "join_phase();\n"); + } + + psContext->indent--; + + bcatcstr(glsl, "}\n"); + + if(psContext->psDependencies) + { + //Save partitioning and primitive type for use by domain shader. + psContext->psDependencies->eTessOutPrim = psShader->sInfo.eTessOutPrim; + + psContext->psDependencies->eTessPartitioning = psShader->sInfo.eTessPartitioning; + } + + return; + } + + if(psShader->eShaderType == DOMAIN_SHADER && psContext->psDependencies) + { + //Load partitioning and primitive type from hull shader. + switch(psContext->psDependencies->eTessOutPrim) + { + case TESSELLATOR_OUTPUT_TRIANGLE_CW: + { + bcatcstr(glsl, "layout(cw) in;\n"); + break; + } + case TESSELLATOR_OUTPUT_POINT: + { + bcatcstr(glsl, "layout(point_mode) in;\n"); + break; + } + default: + { + break; + } + } + + switch(psContext->psDependencies->eTessPartitioning) + { + case TESSELLATOR_PARTITIONING_FRACTIONAL_ODD: + { + bcatcstr(glsl, "layout(fractional_odd_spacing) in;\n"); + break; + } + case TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN: + { + bcatcstr(glsl, "layout(fractional_even_spacing) in;\n"); + break; + } + default: + { + break; + } + } + } + + for(i=0; i < ui32DeclCount; ++i) + { + TranslateDeclaration(psContext, psShader->psDecl+i); + } + + if(psContext->psShader->ui32NumDx9ImmConst) + { + bformata(psContext->glsl, "vec4 ImmConstArray [%d];\n", psContext->psShader->ui32NumDx9ImmConst); + } + + bcatcstr(glsl, "void main()\n{\n"); + + psContext->indent++; + +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- Start Early Main ---\n"); +#endif + bconcat(glsl, psContext->earlyMain); +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- End Early Main ---\n"); +#endif + + MarkIntegerImmediates(psContext); + + SetDataTypes(psContext, psShader->psInst, ui32InstCount); + + for(i=0; i < ui32InstCount; ++i) + { + TranslateInstruction(psContext, psShader->psInst+i); + } + + psContext->indent--; + + bcatcstr(glsl, "}\n"); +} + +static void FreeSubOperands(Instruction* psInst, const uint32_t ui32NumInsts) +{ + uint32_t ui32Inst; + for(ui32Inst = 0; ui32Inst < ui32NumInsts; ++ui32Inst) + { + Instruction* psCurrentInst = &psInst[ui32Inst]; + const uint32_t ui32NumOperands = psCurrentInst->ui32NumOperands; + uint32_t ui32Operand; + + for(ui32Operand = 0; ui32Operand < ui32NumOperands; ++ui32Operand) + { + uint32_t ui32SubOperand; + for(ui32SubOperand = 0; ui32SubOperand < MAX_SUB_OPERANDS; ++ui32SubOperand) + { + if(psCurrentInst->asOperands[ui32Operand].psSubOperand[ui32SubOperand]) + { + hlslcc_free(psCurrentInst->asOperands[ui32Operand].psSubOperand[ui32SubOperand]); + psCurrentInst->asOperands[ui32Operand].psSubOperand[ui32SubOperand] = NULL; + } + } + } + } +} + +HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromMem(const char* shader, + unsigned int flags, + GLLang language, + const GlExtensions *extensions, + GLSLCrossDependencyData* dependencies, + GLSLShader* result) +{ + uint32_t* tokens; + Shader* psShader; + char* glslcstr = NULL; + int GLSLShaderType = GL_FRAGMENT_SHADER_ARB; + int success = 0; + uint32_t i; + + tokens = (uint32_t*)shader; + + psShader = DecodeDXBC(tokens); + + if(psShader) + { + HLSLCrossCompilerContext sContext; + + sContext.psShader = psShader; + sContext.flags = flags; + sContext.psDependencies = dependencies; + + for(i=0; ieShaderType) + { + case VERTEX_SHADER: + { + GLSLShaderType = GL_VERTEX_SHADER_ARB; + break; + } + case GEOMETRY_SHADER: + { + GLSLShaderType = GL_GEOMETRY_SHADER; + break; + } + case DOMAIN_SHADER: + { + GLSLShaderType = GL_TESS_EVALUATION_SHADER; + break; + } + case HULL_SHADER: + { + GLSLShaderType = GL_TESS_CONTROL_SHADER; + break; + } + case COMPUTE_SHADER: + { + GLSLShaderType = GL_COMPUTE_SHADER; + break; + } + default: + { + break; + } + } + + glslcstr = bstr2cstr(sContext.glsl, '\0'); + + bdestroy(sContext.glsl); + bdestroy(sContext.earlyMain); + for(i=0; ipsHSControlPointPhaseDecl); + FreeSubOperands(psShader->psHSControlPointPhaseInstr, psShader->ui32HSControlPointInstrCount); + hlslcc_free(psShader->psHSControlPointPhaseInstr); + + for(i=0; i < psShader->ui32ForkPhaseCount; ++i) + { + hlslcc_free(psShader->apsHSForkPhaseDecl[i]); + FreeSubOperands(psShader->apsHSForkPhaseInstr[i], psShader->aui32HSForkInstrCount[i]); + hlslcc_free(psShader->apsHSForkPhaseInstr[i]); + } + hlslcc_free(psShader->psHSJoinPhaseDecl); + FreeSubOperands(psShader->psHSJoinPhaseInstr, psShader->ui32HSJoinInstrCount); + hlslcc_free(psShader->psHSJoinPhaseInstr); + + hlslcc_free(psShader->psDecl); + FreeSubOperands(psShader->psInst, psShader->ui32InstCount); + hlslcc_free(psShader->psInst); + + memcpy(&result->reflection,&psShader->sInfo,sizeof(psShader->sInfo)); + + + hlslcc_free(psShader); + + success = 1; + } + + shader = 0; + tokens = 0; + + /* Fill in the result struct */ + + result->shaderType = GLSLShaderType; + result->sourceCode = glslcstr; + result->GLSLLanguage = language; + + return success; +} + +HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromFile(const char* filename, + unsigned int flags, + GLLang language, + const GlExtensions *extensions, + GLSLCrossDependencyData* dependencies, + GLSLShader* result) +{ + FILE* shaderFile; + int length; + size_t readLength; + char* shader; + int success = 0; + + shaderFile = fopen(filename, "rb"); + + if(!shaderFile) + { + return 0; + } + + fseek(shaderFile, 0, SEEK_END); + length = ftell(shaderFile); + fseek(shaderFile, 0, SEEK_SET); + + shader = (char*)hlslcc_malloc(length+1); + + readLength = fread(shader, 1, length, shaderFile); + + fclose(shaderFile); + shaderFile = 0; + + shader[readLength] = '\0'; + + success = TranslateHLSLFromMem(shader, flags, language, extensions, dependencies, result); + + hlslcc_free(shader); + + return success; +} + +HLSLCC_API void HLSLCC_APIENTRY FreeGLSLShader(GLSLShader* s) +{ + bcstrfree(s->sourceCode); + s->sourceCode = NULL; + FreeShaderInfo(&s->reflection); +} + diff --git a/build/tools/HLSLcc/May_2014/src/toGLSLDeclaration.c b/build/tools/HLSLcc/May_2014/src/toGLSLDeclaration.c new file mode 100644 index 0000000..5104346 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/toGLSLDeclaration.c @@ -0,0 +1,2436 @@ +#include "hlslcc.h" +#include "internal_includes/toGLSLDeclaration.h" +#include "internal_includes/toGLSLOperand.h" +#include "internal_includes/languages.h" +#include "bstrlib.h" +#include "internal_includes/debug.h" +#include +#include + +#ifdef _MSC_VER +#define isnan(x) _isnan(x) +#define isinf(x) (!_finite(x)) +#endif + +#define fpcheck(x) (isnan(x) || isinf(x)) + +typedef enum { + GLVARTYPE_FLOAT, + GLVARTYPE_INT, + GLVARTYPE_FLOAT4, +} GLVARTYPE; + +extern void AddIndentation(HLSLCrossCompilerContext* psContext); + +const char* GetTypeString(GLVARTYPE eType) +{ + switch(eType) + { + case GLVARTYPE_FLOAT: + { + return "float"; + } + case GLVARTYPE_INT: + { + return "int"; + } + case GLVARTYPE_FLOAT4: + { + return "vec4"; + } + default: + { + return ""; + } + } +} +const uint32_t GetTypeElementCount(GLVARTYPE eType) +{ + switch(eType) + { + case GLVARTYPE_FLOAT: + case GLVARTYPE_INT: + { + return 1; + } + case GLVARTYPE_FLOAT4: + { + return 4; + } + default: + { + return 0; + } + } +} + +void AddToDx9ImmConstIndexableArray(HLSLCrossCompilerContext* psContext, const Operand* psOperand) +{ + bstring* savedStringPtr = psContext->currentGLSLString; + + psContext->currentGLSLString = &psContext->earlyMain; + psContext->indent++; + AddIndentation(psContext); + psContext->psShader->aui32Dx9ImmConstArrayRemap[psOperand->ui32RegisterNumber] = psContext->psShader->ui32NumDx9ImmConst; + bformata(psContext->earlyMain, "ImmConstArray[%d] = ", psContext->psShader->ui32NumDx9ImmConst); + TranslateOperand(psContext, psOperand, TO_FLAG_NONE); + bcatcstr(psContext->earlyMain, ";\n"); + psContext->indent--; + psContext->psShader->ui32NumDx9ImmConst++; + + psContext->currentGLSLString = savedStringPtr; +} + +void DeclareConstBufferShaderVariable(bstring glsl, const char* Name, const struct ShaderVarType_TAG* psType, int unsizedArray) + //const SHADER_VARIABLE_CLASS eClass, const SHADER_VARIABLE_TYPE eType, + //const char* pszName) +{ + if(psType->Class == SVC_STRUCT) + { + bformata(glsl, "\t%s_Type %s", Name, Name); + } + else if(psType->Class == SVC_MATRIX_COLUMNS || psType->Class == SVC_MATRIX_ROWS) + { + switch(psType->Type) + { + case SVT_FLOAT: + { + bformata(glsl, "\tvec4 %s[4", Name); + break; + } + default: + { + ASSERT(0); + break; + } + } + if(psType->Elements > 1) + { + bformata(glsl, " * %d", psType->Elements); + } + bformata(glsl, "]"); + } + else + if(psType->Class == SVC_VECTOR) + { + switch(psType->Type) + { + case SVT_FLOAT: + { + bformata(glsl, "\tvec%d %s", psType->Columns, Name); + break; + } + case SVT_UINT: + { + bformata(glsl, "\tuvec%d %s", psType->Columns, Name); + break; + } + case SVT_INT: + { + bformata(glsl, "\tivec%d %s", psType->Columns, Name); + break; + } + case SVT_DOUBLE: + { + bformata(glsl, "\tdvec%d %s", psType->Columns, Name); + break; + } + default: + { + ASSERT(0); + break; + } + } + + if(psType->Elements > 1) + { + bformata(glsl, "[%d]", psType->Elements); + } + } + else + if(psType->Class == SVC_SCALAR) + { + switch(psType->Type) + { + case SVT_FLOAT: + { + bformata(glsl, "\tfloat %s", Name); + break; + } + case SVT_UINT: + { + bformata(glsl, "\tuint %s", Name); + break; + } + case SVT_INT: + { + bformata(glsl, "\tint %s", Name); + break; + } + case SVT_DOUBLE: + { + bformata(glsl, "\tdouble %s", Name); + break; + } + case SVT_BOOL: + { + //Use int instead of bool. + //Allows implicit conversions to integer and + //bool consumes 4-bytes in HLSL and GLSL anyway. + bformata(glsl, "\tint %s", Name); + break; + } + default: + { + ASSERT(0); + break; + } + } + + if(psType->Elements > 1) + { + bformata(glsl, "[%d]", psType->Elements); + } + } + if(unsizedArray) + bformata(glsl, "[]"); + bformata(glsl, ";\n"); +} + +//In GLSL embedded structure definitions are not supported. +void PreDeclareStructType(bstring glsl, const char* Name, const struct ShaderVarType_TAG* psType) +{ + uint32_t i; + + for(i=0; iMemberCount; ++i) + { + if(psType->Members[i].Class == SVC_STRUCT) + { + PreDeclareStructType(glsl, psType->Members[i].Name, &psType->Members[i]); + } + } + + if(psType->Class == SVC_STRUCT) + { + + uint32_t unnamed_struct = strcmp(Name, "$Element") == 0 ? 1 : 0; + + //Not supported at the moment + ASSERT(!unnamed_struct); + + bformata(glsl, "struct %s_Type {\n", Name); + + for(i=0; iMemberCount; ++i) + { + ASSERT(psType->Members != 0); + + DeclareConstBufferShaderVariable(glsl, psType->Members[i].Name, &psType->Members[i], 0); + } + + bformata(glsl, "};\n"); + } +} + +const char* GetDeclaredInputName(const HLSLCrossCompilerContext* psContext, const SHADER_TYPE eShaderType, const Operand* psOperand) +{ + bstring inputName; + char* cstr; + InOutSignature* psIn; + + if(eShaderType == GEOMETRY_SHADER) + { + inputName = bformat("VtxOutput%d", psOperand->ui32RegisterNumber); + } + else if(eShaderType == HULL_SHADER) + { + inputName = bformat("VtxGeoOutput%d", psOperand->ui32RegisterNumber); + } + else if(eShaderType == DOMAIN_SHADER) + { + inputName = bformat("HullOutput%d", psOperand->ui32RegisterNumber); + } + else if(eShaderType == PIXEL_SHADER) + { + if(psContext->flags & HLSLCC_FLAG_TESS_ENABLED) + { + inputName = bformat("DomOutput%d", psOperand->ui32RegisterNumber); + } + else + { + inputName = bformat("VtxGeoOutput%d", psOperand->ui32RegisterNumber); + } + } + else + { + ASSERT(eShaderType == VERTEX_SHADER); + inputName = bformat("dcl_Input%d", psOperand->ui32RegisterNumber); + } + if((psContext->flags & HLSLCC_FLAG_INOUT_SEMANTIC_NAMES) && GetInputSignatureFromRegister(psOperand->ui32RegisterNumber, &psContext->psShader->sInfo, &psIn)) + { + bformata(inputName,"_%s%d", psIn->SemanticName, psIn->ui32SemanticIndex); + } + + cstr = bstr2cstr(inputName, '\0'); + bdestroy(inputName); + return cstr; +} + +const char* GetDeclaredOutputName(const HLSLCrossCompilerContext* psContext, + const SHADER_TYPE eShaderType, + const Operand* psOperand, + int* piStream) +{ + bstring outputName; + char* cstr; + InOutSignature* psOut; + + int foundOutput = GetOutputSignatureFromRegister(psOperand->ui32RegisterNumber, + psOperand->ui32CompMask, + psContext->psShader->ui32CurrentVertexOutputStream, + &psContext->psShader->sInfo, + &psOut); + + ASSERT(foundOutput); + + if(eShaderType == GEOMETRY_SHADER) + { + if(psOut->ui32Stream != 0) + { + outputName = bformat("VtxGeoOutput%d_S%d", psOperand->ui32RegisterNumber, psOut->ui32Stream); + piStream[0] = psOut->ui32Stream; + } + else + { + outputName = bformat("VtxGeoOutput%d", psOperand->ui32RegisterNumber); + } + + } + else if(eShaderType == DOMAIN_SHADER) + { + outputName = bformat("DomOutput%d", psOperand->ui32RegisterNumber); + } + else if(eShaderType == VERTEX_SHADER) + { + if(psContext->flags & HLSLCC_FLAG_GS_ENABLED) + { + outputName = bformat("VtxOutput%d", psOperand->ui32RegisterNumber); + } + else + { + outputName = bformat("VtxGeoOutput%d", psOperand->ui32RegisterNumber); + } + } + else if(eShaderType == PIXEL_SHADER) + { + outputName = bformat("PixOutput%d", psOperand->ui32RegisterNumber); + } + else + { + ASSERT(eShaderType == HULL_SHADER); + outputName = bformat("HullOutput%d", psOperand->ui32RegisterNumber); + } + if(psContext->flags & HLSLCC_FLAG_INOUT_SEMANTIC_NAMES) + { + bformata(outputName, "_%s%d", psOut->SemanticName, psOut->ui32SemanticIndex); + } + + cstr = bstr2cstr(outputName, '\0'); + bdestroy(outputName); + return cstr; +} + +const char* GetInterpolationString(INTERPOLATION_MODE eMode) +{ + switch(eMode) + { + case INTERPOLATION_CONSTANT: + { + return "flat"; + } + case INTERPOLATION_LINEAR: + { + return ""; + } + case INTERPOLATION_LINEAR_CENTROID: + { + return "centroid"; + } + case INTERPOLATION_LINEAR_NOPERSPECTIVE: + { + return "noperspective"; + break; + } + case INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID: + { + return "noperspective centroid"; + } + case INTERPOLATION_LINEAR_SAMPLE: + { + return "sample"; + } + case INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE: + { + return "noperspective sample"; + } + default: + { + return ""; + } + } +} + +static void DeclareInput( + HLSLCrossCompilerContext* psContext, + const Declaration* psDecl, + const char* Interpolation, const char* StorageQualifier, const char* Precision, int iNumComponents, OPERAND_INDEX_DIMENSION eIndexDim, const char* InputName) +{ + Shader* psShader = psContext->psShader; + bstring glsl = *psContext->currentGLSLString; + + // This falls within the specified index ranges. The default is 0 if no input range is specified + if(psShader->aIndexedInput[psDecl->asOperands[0].ui32RegisterNumber] == -1) + return; + + if(psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] == 0) + { + const char* vecType = "vec"; + const char* scalarType = "float"; + InOutSignature* psSignature = NULL; + + if( GetInputSignatureFromRegister(psDecl->asOperands[0].ui32RegisterNumber, &psShader->sInfo, &psSignature) ) + { + switch(psSignature->eComponentType) + { + case INOUT_COMPONENT_UINT32: + { + vecType = "uvec"; + scalarType = "uint"; + break; + } + case INOUT_COMPONENT_SINT32: + { + vecType = "ivec"; + scalarType = "int"; + break; + } + case INOUT_COMPONENT_FLOAT32: + { + break; + } + } + } + + if(psContext->psDependencies) + { + if(psShader->eShaderType == PIXEL_SHADER) + { + psContext->psDependencies->aePixelInputInterpolation[psDecl->asOperands[0].ui32RegisterNumber] = psDecl->value.eInterpolation; + } + } + + if( HaveInOutLocationQualifier(psContext->psShader->eTargetLanguage,psContext->psShader->extensions) || + (psShader->eShaderType == VERTEX_SHADER && HaveLimitedInOutLocationQualifier(psContext->psShader->eTargetLanguage))) + { + bformata(glsl, "layout(location = %d) ", psDecl->asOperands[0].ui32RegisterNumber); + } + + switch(eIndexDim) + { + case INDEX_2D: + { + if(iNumComponents == 1) + { + const uint32_t regNum = psDecl->asOperands[0].ui32RegisterNumber; + const uint32_t arraySize = psDecl->asOperands[0].aui32ArraySizes[0]; + + psContext->psShader->abScalarInput[psDecl->asOperands[0].ui32RegisterNumber] = -1; + + bformata(glsl, "%s %s %s %s [%d];\n", StorageQualifier, Precision, scalarType, InputName, + arraySize); + + bformata(glsl, "%s1 Input%d;\n", vecType, psDecl->asOperands[0].ui32RegisterNumber); + + psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] = arraySize; + } + else + { + bformata(glsl, "%s %s %s%d %s [%d];\n", StorageQualifier, Precision, vecType, iNumComponents, InputName, + psDecl->asOperands[0].aui32ArraySizes[0]); + + bformata(glsl, "%s%d Input%d[%d];\n", vecType, iNumComponents, psDecl->asOperands[0].ui32RegisterNumber, + psDecl->asOperands[0].aui32ArraySizes[0]); + + psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] = psDecl->asOperands[0].aui32ArraySizes[0]; + } + break; + } + default: + { + + if(psDecl->asOperands[0].eType == OPERAND_TYPE_SPECIAL_TEXCOORD) + { + InputName = "TexCoord"; + } + + if(iNumComponents == 1) + { + psContext->psShader->abScalarInput[psDecl->asOperands[0].ui32RegisterNumber] = 1; + + bformata(glsl, "%s %s %s %s %s;\n", Interpolation, StorageQualifier, Precision, scalarType, InputName); + bformata(glsl, "%s1 Input%d;\n", vecType, psDecl->asOperands[0].ui32RegisterNumber); + + psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] = -1; + } + else + { + if(psShader->aIndexedInput[psDecl->asOperands[0].ui32RegisterNumber] > 0) + { + bformata(glsl, "%s %s %s %s%d %s", Interpolation, StorageQualifier, Precision, vecType, iNumComponents, InputName); + bformata(glsl, "[%d];\n", psShader->aIndexedInput[psDecl->asOperands[0].ui32RegisterNumber]); + + bformata(glsl, "%s%d Input%d[%d];\n", vecType, iNumComponents, psDecl->asOperands[0].ui32RegisterNumber, + psShader->aIndexedInput[psDecl->asOperands[0].ui32RegisterNumber]); + + + psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] = psShader->aIndexedInput[psDecl->asOperands[0].ui32RegisterNumber]; + } + else + { + bformata(glsl, "%s %s %s %s%d %s;\n", Interpolation, StorageQualifier, Precision, vecType, iNumComponents, InputName); + bformata(glsl, "%s%d Input%d;\n", vecType, iNumComponents, psDecl->asOperands[0].ui32RegisterNumber); + + psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] = -1; + } + } + break; + } + } + } + + if(psShader->abInputReferencedByInstruction[psDecl->asOperands[0].ui32RegisterNumber]) + { + psContext->currentGLSLString = &psContext->earlyMain; + psContext->indent++; + + if(psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] == -1) //Not an array + { + AddIndentation(psContext); + bformata(psContext->earlyMain, "Input%d = %s;\n", psDecl->asOperands[0].ui32RegisterNumber, InputName); + } + else + { + int arrayIndex = psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber]; + + while(arrayIndex) + { + AddIndentation(psContext); + bformata(psContext->earlyMain, "Input%d[%d] = %s[%d];\n", psDecl->asOperands[0].ui32RegisterNumber, arrayIndex-1, + InputName, arrayIndex-1); + + arrayIndex--; + } + } + psContext->indent--; + psContext->currentGLSLString = &psContext->glsl; + } +} + +void AddBuiltinInput(HLSLCrossCompilerContext* psContext, const Declaration* psDecl, const char* builtinName) +{ + bstring glsl = *psContext->currentGLSLString; + Shader* psShader = psContext->psShader; + + if(psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] == 0) + { + SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, &psDecl->asOperands[0]); + switch(eType) + { + case SVT_INT: + bformata(glsl, "ivec4 "); + break; + case SVT_UINT: + bformata(glsl, "uvec4 "); + break; + default: + bformata(glsl, "vec4 "); + break; + } + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NAME_ONLY); + bformata(glsl, ";\n"); + + psShader->aiInputDeclaredSize[psDecl->asOperands[0].ui32RegisterNumber] = 1; + } + else + { + //This register has already been declared. The HLSL bytecode likely looks + //something like this then: + // dcl_input_ps constant v3.x + // dcl_input_ps_sgv v3.y, primitive_id + + //GLSL does not allow assignment to a varying! + } + + psContext->currentGLSLString = &psContext->earlyMain; + psContext->indent++; + AddIndentation(psContext); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + + bformata(psContext->earlyMain, " = %s", builtinName); + + switch(psDecl->asOperands[0].eSpecialName) + { + case NAME_POSITION: + TranslateOperandSwizzle(psContext, &psDecl->asOperands[0]); + break; + default: + //Scalar built-in. Don't apply swizzle. + break; + } + bcatcstr(psContext->earlyMain, ";\n"); + + psContext->indent--; + psContext->currentGLSLString = &psContext->glsl; +} + +int OutputNeedsDeclaring(HLSLCrossCompilerContext* psContext, const Operand* psOperand, const int count) +{ + Shader* psShader = psContext->psShader; + const uint32_t declared = ((psContext->currentPhase + 1) << 3) | psShader->ui32CurrentVertexOutputStream; + if(psShader->aiOutputDeclared[psOperand->ui32RegisterNumber] != declared) + { + int offset; + + for(offset = 0; offset < count; offset++) + { + psShader->aiOutputDeclared[psOperand->ui32RegisterNumber+offset] = declared; + } + return 1; + } + + if(psShader->eShaderType == PIXEL_SHADER) + { + if(psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL || + psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL) + { + return 1; + } + } + + return 0; +} + +void AddBuiltinOutput(HLSLCrossCompilerContext* psContext, const Declaration* psDecl, const GLVARTYPE type, int arrayElements, const char* builtinName) +{ + bstring glsl = *psContext->currentGLSLString; + Shader* psShader = psContext->psShader; + + psContext->havePostShaderCode[psContext->currentPhase] = 1; + + if(OutputNeedsDeclaring(psContext, &psDecl->asOperands[0], arrayElements ? arrayElements : 1)) + { + InOutSignature* psSignature = NULL; + + GetOutputSignatureFromRegister(psDecl->asOperands[0].ui32RegisterNumber, + psDecl->asOperands[0].ui32CompMask, + 0, + &psShader->sInfo, &psSignature); + + bcatcstr(glsl, "#undef "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, "\n"); + + bcatcstr(glsl, "#define "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NAME_ONLY); + bformata(glsl, " phase%d_", psContext->currentPhase); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, "\n"); + + bcatcstr(glsl, "vec4 "); + bformata(glsl, "phase%d_", psContext->currentPhase); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NAME_ONLY); + if(arrayElements) + bformata(glsl, "[%d];\n", arrayElements); + else + bcatcstr(glsl, ";\n"); + + psContext->currentGLSLString = &psContext->postShaderCode[psContext->currentPhase]; + glsl = *psContext->currentGLSLString; + psContext->indent++; + if(arrayElements) + { + int elem; + for(elem = 0; elem < arrayElements; elem++) + { + AddIndentation(psContext); + bformata(glsl, "%s[%d] = %s(phase%d_", builtinName, elem, GetTypeString(type), psContext->currentPhase); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NAME_ONLY); + bformata(glsl, "[%d]", elem); + TranslateOperandSwizzle(psContext, &psDecl->asOperands[0]); + bformata(glsl, ");\n"); + } + } + else + { + + if(psDecl->asOperands[0].eSpecialName == NAME_CLIP_DISTANCE) + { + int max = GetMaxComponentFromComponentMask(&psDecl->asOperands[0]); + + int applySiwzzle = GetNumSwizzleElements(&psDecl->asOperands[0]) > 1 ? 1 : 0; + int index; + int i; + int multiplier = 1; + char* swizzle[] = {".x", ".y", ".z", ".w"}; + + ASSERT(psSignature!=NULL); + + index = psSignature->ui32SemanticIndex; + + //Clip distance can be spread across 1 or 2 outputs (each no more than a vec4). + //Some examples: + //float4 clip[2] : SV_ClipDistance; //8 clip distances + //float3 clip[2] : SV_ClipDistance; //6 clip distances + //float4 clip : SV_ClipDistance; //4 clip distances + //float clip : SV_ClipDistance; //1 clip distance. + + //In GLSL the clip distance built-in is an array of up to 8 floats. + //So vector to array conversion needs to be done here. + if(index == 1) + { + InOutSignature* psFirstClipSignature; + if(GetOutputSignatureFromSystemValue(NAME_CLIP_DISTANCE, 1, &psShader->sInfo, &psFirstClipSignature)) + { + if(psFirstClipSignature->ui32Mask & (1 << 3)) + { + multiplier = 4; + } + else + if(psFirstClipSignature->ui32Mask & (1 << 2)) + { + multiplier = 3; + } + else + if(psFirstClipSignature->ui32Mask & (1 << 1)) + { + multiplier = 2; + } + } + } + + for(i=0; icurrentPhase); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + if(applySiwzzle) + { + bformata(glsl, ")%s;\n", swizzle[i]); + } + else + { + bformata(glsl, ");\n"); + } + } + } + else + { + uint32_t elements = GetNumSwizzleElements(&psDecl->asOperands[0]); + + if(elements != GetTypeElementCount(type)) + { + //This is to handle float3 position seen in control point phases + //struct HS_OUTPUT + //{ + // float3 vPosition : POSITION; + //}; -> dcl_output o0.xyz + //gl_Position is vec4. + AddIndentation(psContext); + bformata(glsl, "%s = %s(phase%d_", builtinName, GetTypeString(type), psContext->currentPhase); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + bformata(glsl, ", 1);\n"); + } + else + { + AddIndentation(psContext); + bformata(glsl, "%s = %s(phase%d_", builtinName, GetTypeString(type), psContext->currentPhase); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + bformata(glsl, ");\n"); + } + } + } + psContext->indent--; + psContext->currentGLSLString = &psContext->glsl; + } +} + +void AddUserOutput(HLSLCrossCompilerContext* psContext, const Declaration* psDecl) +{ + bstring glsl = *psContext->currentGLSLString; + Shader* psShader = psContext->psShader; + + if(OutputNeedsDeclaring(psContext, &psDecl->asOperands[0], 1)) + { + const Operand* psOperand = &psDecl->asOperands[0]; + const char* Precision = ""; + const char* type = "vec"; + + InOutSignature* psSignature = NULL; + + GetOutputSignatureFromRegister(psDecl->asOperands[0].ui32RegisterNumber, + psDecl->asOperands[0].ui32CompMask, + psShader->ui32CurrentVertexOutputStream, + &psShader->sInfo, + &psSignature); + + switch(psSignature->eComponentType) + { + case INOUT_COMPONENT_UINT32: + { + type = "uvec"; + break; + } + case INOUT_COMPONENT_SINT32: + { + type = "ivec"; + break; + } + case INOUT_COMPONENT_FLOAT32: + { + break; + } + } + + if(HavePrecisionQualifers(psShader->eTargetLanguage)) + { + switch(psOperand->eMinPrecision) + { + case OPERAND_MIN_PRECISION_DEFAULT: + { + Precision = "highp"; + break; + } + case OPERAND_MIN_PRECISION_FLOAT_16: + { + Precision = "mediump"; + break; + } + case OPERAND_MIN_PRECISION_FLOAT_2_8: + { + Precision = "lowp"; + break; + } + case OPERAND_MIN_PRECISION_SINT_16: + { + Precision = "mediump"; + //type = "ivec"; + break; + } + case OPERAND_MIN_PRECISION_UINT_16: + { + Precision = "mediump"; + //type = "uvec"; + break; + } + } + } + + switch(psShader->eShaderType) + { + case PIXEL_SHADER: + { + switch(psDecl->asOperands[0].eType) + { + case OPERAND_TYPE_OUTPUT_COVERAGE_MASK: + case OPERAND_TYPE_OUTPUT_DEPTH: + { + + break; + } + case OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL: + { + bcatcstr(glsl, "#ifdef GL_ARB_conservative_depth\n"); + bcatcstr(glsl, "#extension GL_ARB_conservative_depth : enable\n"); + bcatcstr(glsl, "layout (depth_greater) out float gl_FragDepth;\n"); + bcatcstr(glsl, "#endif\n"); + break; + } + case OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL: + { + bcatcstr(glsl, "#ifdef GL_ARB_conservative_depth\n"); + bcatcstr(glsl, "#extension GL_ARB_conservative_depth : enable\n"); + bcatcstr(glsl, "layout (depth_less) out float gl_FragDepth;\n"); + bcatcstr(glsl, "#endif\n"); + break; + } + default: + { + if(WriteToFragData(psContext->psShader->eTargetLanguage)) + { + bformata(glsl, "#define Output%d gl_FragData[%d]\n", psDecl->asOperands[0].ui32RegisterNumber, psDecl->asOperands[0].ui32RegisterNumber); + } + else + { + int stream = 0; + const char* OutputName = GetDeclaredOutputName(psContext, PIXEL_SHADER, psOperand, &stream); + + if(HaveInOutLocationQualifier(psContext->psShader->eTargetLanguage,psContext->psShader->extensions) || HaveLimitedInOutLocationQualifier(psContext->psShader->eTargetLanguage)) + { + uint32_t index = 0; + uint32_t renderTarget = psDecl->asOperands[0].ui32RegisterNumber; + + if((psContext->flags & HLSLCC_FLAG_DUAL_SOURCE_BLENDING) && DualSourceBlendSupported(psContext->psShader->eTargetLanguage)) + { + if(renderTarget > 0) + { + renderTarget = 0; + index = 1; + } + bformata(glsl, "layout(location = %d, index = %d) ", renderTarget, index); + } + else + { + bformata(glsl, "layout(location = %d) ", renderTarget); + } + } + + bformata(glsl, "out %s %s4 %s;\n", Precision, type, OutputName); + if(stream) + { + bformata(glsl, "#define Output%d_S%d %s\n", psDecl->asOperands[0].ui32RegisterNumber, stream, OutputName); + } + else + { + bformata(glsl, "#define Output%d %s\n", psDecl->asOperands[0].ui32RegisterNumber, OutputName); + } + } + break; + } + } + break; + } + case VERTEX_SHADER: + { + int iNumComponents = 4;//GetMaxComponentFromComponentMask(&psDecl->asOperands[0]); + const char* Interpolation = ""; + int stream = 0; + const char* OutputName = GetDeclaredOutputName(psContext, VERTEX_SHADER, psOperand, &stream); + + if(psContext->psDependencies) + { + if(psShader->eShaderType == VERTEX_SHADER) + { + Interpolation = GetInterpolationString(psContext->psDependencies->aePixelInputInterpolation[psDecl->asOperands[0].ui32RegisterNumber]); + } + } + + if(HaveInOutLocationQualifier(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + { + bformata(glsl, "layout(location = %d) ", psDecl->asOperands[0].ui32RegisterNumber); + } + + if(InOutSupported(psContext->psShader->eTargetLanguage)) + { + bformata(glsl, "%s out %s %s%d %s;\n", Interpolation, Precision, type, iNumComponents, OutputName); + } + else + { + bformata(glsl, "%s varying %s %s%d %s;\n", Interpolation, Precision, type, iNumComponents, OutputName); + } + bformata(glsl, "#define Output%d %s\n", psDecl->asOperands[0].ui32RegisterNumber, OutputName); + + break; + } + case GEOMETRY_SHADER: + { + int stream = 0; + const char* OutputName = GetDeclaredOutputName(psContext, GEOMETRY_SHADER, psOperand, &stream); + + if(HaveInOutLocationQualifier(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + { + bformata(glsl, "layout(location = %d) ", psDecl->asOperands[0].ui32RegisterNumber); + } + + bformata(glsl, "out %s4 %s;\n", type, OutputName); + if(stream) + { + bformata(glsl, "#define Output%d_S%d %s\n", psDecl->asOperands[0].ui32RegisterNumber, stream, OutputName); + } + else + { + bformata(glsl, "#define Output%d %s\n", psDecl->asOperands[0].ui32RegisterNumber, OutputName); + } + break; + } + case HULL_SHADER: + { + int stream = 0; + const char* OutputName = GetDeclaredOutputName(psContext, HULL_SHADER, psOperand, &stream); + + ASSERT(psDecl->asOperands[0].ui32RegisterNumber!=0);//Reg 0 should be gl_out[gl_InvocationID].gl_Position. + + if(HaveInOutLocationQualifier(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + { + bformata(glsl, "layout(location = %d) ", psDecl->asOperands[0].ui32RegisterNumber); + } + bformata(glsl, "out %s4 %s[];\n", type, OutputName); + bformata(glsl, "#define Output%d %s[gl_InvocationID]\n", psDecl->asOperands[0].ui32RegisterNumber, OutputName); + break; + } + case DOMAIN_SHADER: + { + int stream = 0; + const char* OutputName = GetDeclaredOutputName(psContext, DOMAIN_SHADER, psOperand, &stream); + if(HaveInOutLocationQualifier(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + { + bformata(glsl, "layout(location = %d) ", psDecl->asOperands[0].ui32RegisterNumber); + } + bformata(glsl, "out %s4 %s;\n", type, OutputName); + bformata(glsl, "#define Output%d %s\n", psDecl->asOperands[0].ui32RegisterNumber, OutputName); + break; + } + } + } + else + { + /* + Multiple outputs can be packed into one register. e.g. + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------- ------ + // FACTOR 0 x 3 NONE int x + // MAX 0 y 3 NONE int y + + We want unique outputs to make it easier to use transform feedback. + + out ivec4 FACTOR0; + #define Output3 FACTOR0 + out ivec4 MAX0; + + MAIN SHADER CODE. Writes factor and max to Output3 which aliases FACTOR0. + + MAX0.x = FACTOR0.y; + + This unpacking of outputs is only done when using HLSLCC_FLAG_INOUT_SEMANTIC_NAMES. + When not set the application will be using HLSL reflection information to discover + what the input and outputs mean if need be. + */ + + // + + if((psContext->flags & HLSLCC_FLAG_INOUT_SEMANTIC_NAMES) && (psDecl->asOperands[0].eType == OPERAND_TYPE_OUTPUT)) + { + const Operand* psOperand = &psDecl->asOperands[0]; + InOutSignature* psSignature = NULL; + const char* type = "vec"; + int stream = 0; + const char* OutputName = GetDeclaredOutputName(psContext, psShader->eShaderType, psOperand, &stream); + + GetOutputSignatureFromRegister(psOperand->ui32RegisterNumber, + psOperand->ui32CompMask, + 0, + &psShader->sInfo, + &psSignature); + + if(HaveInOutLocationQualifier(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + { + bformata(glsl, "layout(location = %d) ", psDecl->asOperands[0].ui32RegisterNumber); + } + + switch(psSignature->eComponentType) + { + case INOUT_COMPONENT_UINT32: + { + type = "uvec"; + break; + } + case INOUT_COMPONENT_SINT32: + { + type = "ivec"; + break; + } + case INOUT_COMPONENT_FLOAT32: + { + break; + } + } + bformata(glsl, "out %s4 %s;\n", type, OutputName); + + psContext->havePostShaderCode[psContext->currentPhase] = 1; + + psContext->currentGLSLString = &psContext->postShaderCode[psContext->currentPhase]; + glsl = *psContext->currentGLSLString; + + bcatcstr(glsl, OutputName); + AddSwizzleUsingElementCount(psContext, GetNumSwizzleElements(psOperand)); + bformata(glsl, " = Output%d", psOperand->ui32RegisterNumber); + TranslateOperandSwizzle(psContext, psOperand); + bcatcstr(glsl, ";\n"); + + psContext->currentGLSLString = &psContext->glsl; + glsl = *psContext->currentGLSLString; + } + } +} + +void DeclareUBOConstants(HLSLCrossCompilerContext* psContext, const uint32_t ui32BindingPoint, + ConstantBuffer* psCBuf, + bstring glsl) +{ + uint32_t i; + const char* Name = psCBuf->Name; + if(psCBuf->Name[0] == '$') //For $Globals + { + Name++; + } + + for(i=0; i < psCBuf->ui32NumVars; ++i) + { + PreDeclareStructType(glsl, + psCBuf->asVars[i].Name, + &psCBuf->asVars[i].sType); + } + + /* [layout (location = X)] uniform vec4 HLSLConstantBufferName[numConsts]; */ + if(HaveUniformBindingsAndLocations(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + bformata(glsl, "layout(binding = %d) ", ui32BindingPoint); + + bformata(glsl, "uniform %s {\n ", Name); + + for(i=0; i < psCBuf->ui32NumVars; ++i) + { + DeclareConstBufferShaderVariable(glsl, + psCBuf->asVars[i].Name, + &psCBuf->asVars[i].sType, 0); + } + + bcatcstr(glsl, "};\n"); +} + +void DeclareBufferVariable(HLSLCrossCompilerContext* psContext, const uint32_t ui32BindingPoint, + ConstantBuffer* psCBuf, const Operand* psOperand, + const uint32_t ui32GloballyCoherentAccess, + const ResourceType eResourceType, + bstring glsl) +{ + bstring StructName; + uint32_t unnamed_struct = strcmp(psCBuf->asVars[0].Name, "$Element") == 0 ? 1 : 0; + + ASSERT(psCBuf->ui32NumVars == 1); + ASSERT(unnamed_struct); + + StructName = bfromcstr(""); + + //TranslateOperand(psContext, psOperand, TO_FLAG_NAME_ONLY); + if(psOperand->eType == OPERAND_TYPE_RESOURCE && eResourceType == RTYPE_STRUCTURED) + { + bformata(StructName, "StructuredRes%d", psOperand->ui32RegisterNumber); + } + else if(psOperand->eType == OPERAND_TYPE_RESOURCE && eResourceType == RTYPE_UAV_RWBYTEADDRESS) + { + bformata(StructName, "RawRes%d", psOperand->ui32RegisterNumber); + } + else + { + bformata(StructName, "UAV%d", psOperand->ui32RegisterNumber); + } + + PreDeclareStructType(glsl, + bstr2cstr(StructName, '\0'), + &psCBuf->asVars[0].sType); + + /* [layout (location = X)] uniform vec4 HLSLConstantBufferName[numConsts]; */ + if(HaveUniformBindingsAndLocations(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + bformata(glsl, "layout(binding = %d) ", ui32BindingPoint); + + if(ui32GloballyCoherentAccess & GLOBALLY_COHERENT_ACCESS) + { + bcatcstr(glsl, "coherent "); + } + + if(eResourceType == RTYPE_STRUCTURED) + { + bcatcstr(glsl, "readonly "); + } + + bformata(glsl, "buffer Block%d {\n", psOperand->ui32RegisterNumber); + + DeclareConstBufferShaderVariable(glsl, + bstr2cstr(StructName, '\0'), + &psCBuf->asVars[0].sType, + 1); + + bcatcstr(glsl, "};\n"); + + bdestroy(StructName); +} + + +void DeclareStructConstants(HLSLCrossCompilerContext* psContext, const uint32_t ui32BindingPoint, + ConstantBuffer* psCBuf, const Operand* psOperand, + bstring glsl) +{ + uint32_t i; + + for(i=0; i < psCBuf->ui32NumVars; ++i) + { + PreDeclareStructType(glsl, + psCBuf->asVars[i].Name, + &psCBuf->asVars[i].sType); + } + + /* [layout (location = X)] uniform vec4 HLSLConstantBufferName[numConsts]; */ + if(HaveUniformBindingsAndLocations(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + bformata(glsl, "layout(location = %d) ", ui32BindingPoint); + bcatcstr(glsl, "uniform struct "); + TranslateOperand(psContext, psOperand, TO_FLAG_DECLARATION_NAME); + + bcatcstr(glsl, "_Type {\n"); + + for(i=0; i < psCBuf->ui32NumVars; ++i) + { + DeclareConstBufferShaderVariable(glsl, + psCBuf->asVars[i].Name, + &psCBuf->asVars[i].sType, 0); + } + + bcatcstr(glsl, "} "); + + TranslateOperand(psContext, psOperand, TO_FLAG_DECLARATION_NAME); + + bcatcstr(glsl, ";\n"); +} + +void TranslateDeclaration(HLSLCrossCompilerContext* psContext, const Declaration* psDecl) +{ + bstring glsl = *psContext->currentGLSLString; + Shader* psShader = psContext->psShader; + + switch(psDecl->eOpcode) + { + case OPCODE_DCL_INPUT_SGV: + case OPCODE_DCL_INPUT_PS_SGV: + { + const SPECIAL_NAME eSpecialName = psDecl->asOperands[0].eSpecialName; + switch(eSpecialName) + { + case NAME_POSITION: + { + AddBuiltinInput(psContext, psDecl, "gl_Position"); + break; + } + case NAME_RENDER_TARGET_ARRAY_INDEX: + { + AddBuiltinInput(psContext, psDecl, "gl_Layer"); + break; + } + case NAME_CLIP_DISTANCE: + { + AddBuiltinInput(psContext, psDecl, "gl_ClipDistance"); + break; + } + case NAME_VIEWPORT_ARRAY_INDEX: + { + AddBuiltinInput(psContext, psDecl, "gl_ViewportIndex"); + break; + } + case NAME_INSTANCE_ID: + { + AddBuiltinInput(psContext, psDecl, "gl_InstanceID"); + break; + } + case NAME_IS_FRONT_FACE: + { + /* + Cast to int used because + if(gl_FrontFacing != 0) failed to compiled on Intel HD 4000. + Suggests no implicit conversion for bool<->int. + */ + + AddBuiltinInput(psContext, psDecl, "int(gl_FrontFacing)"); + break; + } + case NAME_SAMPLE_INDEX: + { + AddBuiltinInput(psContext, psDecl, "gl_SampleID"); + break; + } + case NAME_VERTEX_ID: + { + AddBuiltinInput(psContext, psDecl, "gl_VertexID"); + break; + } + case NAME_PRIMITIVE_ID: + { + AddBuiltinInput(psContext, psDecl, "gl_PrimitiveID"); + break; + } + default: + { + bformata(glsl, "in vec4 %s;\n", psDecl->asOperands[0].pszSpecialName); + + bcatcstr(glsl, "#define "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + bformata(glsl, " %s\n", psDecl->asOperands[0].pszSpecialName); + break; + } + } + break; + } + + case OPCODE_DCL_OUTPUT_SIV: + { + switch(psDecl->asOperands[0].eSpecialName) + { + case NAME_POSITION: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT4, 0, "gl_Position"); + break; + } + case NAME_RENDER_TARGET_ARRAY_INDEX: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_INT, 0, "gl_Layer"); + break; + } + case NAME_CLIP_DISTANCE: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_ClipDistance"); + break; + } + case NAME_VIEWPORT_ARRAY_INDEX: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_INT, 0, "gl_ViewportIndex"); + break; + } + case NAME_VERTEX_ID: + { + ASSERT(0); //VertexID is not an output + break; + } + case NAME_PRIMITIVE_ID: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_INT, 0, "gl_PrimitiveID"); + break; + } + case NAME_INSTANCE_ID: + { + ASSERT(0); //InstanceID is not an output + break; + } + case NAME_IS_FRONT_FACE: + { + ASSERT(0); //FrontFacing is not an output + break; + } + case NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR: + { + if(psContext->psShader->aIndexedOutput[psDecl->asOperands[0].ui32RegisterNumber]) + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 4, "gl_TessLevelOuter"); + } + else + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[0]"); + } + break; + } + case NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[1]"); + break; + } + case NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[2]"); + break; + } + case NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[3]"); + break; + } + case NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR: + { + if(psContext->psShader->aIndexedOutput[psDecl->asOperands[0].ui32RegisterNumber]) + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 3,"gl_TessLevelOuter"); + } + else + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[0]"); + } + break; + } + case NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[1]"); + break; + } + case NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[2]"); + break; + } + case NAME_FINAL_LINE_DENSITY_TESSFACTOR: + { + if(psContext->psShader->aIndexedOutput[psDecl->asOperands[0].ui32RegisterNumber]) + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 2, "gl_TessLevelOuter"); + } + else + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[0]"); + } + break; + } + case NAME_FINAL_LINE_DETAIL_TESSFACTOR: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelOuter[1]"); + break; + } + case NAME_FINAL_TRI_INSIDE_TESSFACTOR: + case NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR: + { + if(psContext->psShader->aIndexedOutput[psDecl->asOperands[0].ui32RegisterNumber]) + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 2, "gl_TessLevelInner"); + } + else + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelInner[0]"); + } + break; + } + case NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR: + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT, 0, "gl_TessLevelInner[1]"); + break; + } + default: + { + bformata(glsl, "out vec4 %s;\n", psDecl->asOperands[0].pszSpecialName); + + bcatcstr(glsl, "#define "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + bformata(glsl, " %s\n", psDecl->asOperands[0].pszSpecialName); + break; + } + } + break; + } + case OPCODE_DCL_INPUT: + { + const Operand* psOperand = &psDecl->asOperands[0]; + //Force the number of components to be 4. +/*dcl_output o3.xy + dcl_output o3.z + +Would generate a vec2 and a vec3. We discard the second one making .z invalid! + +*/ + int iNumComponents = 4;//GetMaxComponentFromComponentMask(psOperand); + const char* StorageQualifier = "attribute"; + const char* InputName; + const char* Precision = ""; + + if((psOperand->eType == OPERAND_TYPE_INPUT_DOMAIN_POINT)|| + (psOperand->eType == OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID)|| + (psOperand->eType == OPERAND_TYPE_INPUT_COVERAGE_MASK)|| + (psOperand->eType == OPERAND_TYPE_INPUT_THREAD_ID)|| + (psOperand->eType == OPERAND_TYPE_INPUT_THREAD_GROUP_ID)|| + (psOperand->eType == OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP)|| + (psOperand->eType == OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED)) + { + break; + } + + //Already declared as part of an array. + if(psShader->aIndexedInput[psDecl->asOperands[0].ui32RegisterNumber] == -1) + { + break; + } + + InputName = GetDeclaredInputName(psContext, psShader->eShaderType, psOperand); + + if(InOutSupported(psContext->psShader->eTargetLanguage)) + { + StorageQualifier = "in"; + } + + if(HavePrecisionQualifers(psShader->eTargetLanguage)) + { + switch(psOperand->eMinPrecision) + { + case OPERAND_MIN_PRECISION_DEFAULT: + { + Precision = "highp"; + break; + } + case OPERAND_MIN_PRECISION_FLOAT_16: + { + Precision = "mediump"; + break; + } + case OPERAND_MIN_PRECISION_FLOAT_2_8: + { + Precision = "lowp"; + break; + } + case OPERAND_MIN_PRECISION_SINT_16: + { + Precision = "mediump"; + break; + } + case OPERAND_MIN_PRECISION_UINT_16: + { + Precision = "mediump"; + break; + } + } + } + + DeclareInput(psContext, psDecl, + "", StorageQualifier, Precision, iNumComponents, (OPERAND_INDEX_DIMENSION)psOperand->iIndexDims, InputName); + + break; + } + case OPCODE_DCL_INPUT_PS_SIV: + { + switch(psDecl->asOperands[0].eSpecialName) + { + case NAME_POSITION: + { + AddBuiltinInput(psContext, psDecl, "gl_FragCoord"); + break; + } + } + break; + } + case OPCODE_DCL_INPUT_SIV: + { + if(psShader->eShaderType == PIXEL_SHADER && psContext->psDependencies) + { + psContext->psDependencies->aePixelInputInterpolation[psDecl->asOperands[0].ui32RegisterNumber] = psDecl->value.eInterpolation; + } + break; + } + case OPCODE_DCL_INPUT_PS: + { + const Operand* psOperand = &psDecl->asOperands[0]; + int iNumComponents = 4;//GetMaxComponentFromComponentMask(psOperand); + const char* StorageQualifier = "varying"; + const char* Precision = ""; + const char* InputName = GetDeclaredInputName(psContext, PIXEL_SHADER, psOperand); + const char* Interpolation = ""; + + if(InOutSupported(psContext->psShader->eTargetLanguage)) + { + StorageQualifier = "in"; + } + + switch(psDecl->value.eInterpolation) + { + case INTERPOLATION_CONSTANT: + { + Interpolation = "flat"; + break; + } + case INTERPOLATION_LINEAR: + { + break; + } + case INTERPOLATION_LINEAR_CENTROID: + { + Interpolation = "centroid"; + break; + } + case INTERPOLATION_LINEAR_NOPERSPECTIVE: + { + Interpolation = "noperspective"; + break; + } + case INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID: + { + Interpolation = "noperspective centroid"; + break; + } + case INTERPOLATION_LINEAR_SAMPLE: + { + Interpolation = "sample"; + break; + } + case INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE: + { + Interpolation = "noperspective sample"; + break; + } + } + + if(HavePrecisionQualifers(psShader->eTargetLanguage)) + { + switch(psOperand->eMinPrecision) + { + case OPERAND_MIN_PRECISION_DEFAULT: + { + Precision = "highp"; + break; + } + case OPERAND_MIN_PRECISION_FLOAT_16: + { + Precision = "mediump"; + break; + } + case OPERAND_MIN_PRECISION_FLOAT_2_8: + { + Precision = "lowp"; + break; + } + case OPERAND_MIN_PRECISION_SINT_16: + { + Precision = "mediump"; + break; + } + case OPERAND_MIN_PRECISION_UINT_16: + { + Precision = "mediump"; + break; + } + } + } + + DeclareInput(psContext, psDecl, + Interpolation, StorageQualifier, Precision, iNumComponents, INDEX_1D, InputName); + + break; + } + case OPCODE_DCL_TEMPS: + { + uint32_t i = 0; + const uint32_t ui32NumTemps = psDecl->value.ui32NumTemps; + + if(ui32NumTemps > 0) + { + bformata(glsl, "vec4 Temp[%d];\n", ui32NumTemps); + + bformata(glsl, "ivec4 Temp_int[%d];\n", ui32NumTemps); + if(HaveUVec(psShader->eTargetLanguage)) + { + bformata(glsl, "uvec4 Temp_uint[%d];\n", ui32NumTemps); + } + if(psShader->fp64) + { + bformata(glsl, "dvec4 Temp_double[%d];\n", ui32NumTemps); + } + } + + break; + } + case OPCODE_SPECIAL_DCL_IMMCONST: + { + const Operand* psDest = &psDecl->asOperands[0]; + const Operand* psSrc = &psDecl->asOperands[1]; + + ASSERT(psSrc->eType == OPERAND_TYPE_IMMEDIATE32); + if(psDest->eType == OPERAND_TYPE_SPECIAL_IMMCONSTINT) + { + bformata(glsl, "const ivec4 IntImmConst%d = ", psDest->ui32RegisterNumber); + } + else + { + bformata(glsl, "const vec4 ImmConst%d = ", psDest->ui32RegisterNumber); + AddToDx9ImmConstIndexableArray(psContext, psDest); + } + TranslateOperand(psContext, psSrc, TO_FLAG_NONE); + bcatcstr(glsl, ";\n"); + + break; + } + case OPCODE_DCL_CONSTANT_BUFFER: + { + const Operand* psOperand = &psDecl->asOperands[0]; + const uint32_t ui32BindingPoint = psOperand->aui32ArraySizes[0]; + + const char* StageName = "VS"; + + ConstantBuffer* psCBuf = NULL; + GetConstantBufferFromBindingPoint(RGROUP_CBUFFER, ui32BindingPoint, &psContext->psShader->sInfo, &psCBuf); + + // We don't have a original resource name, maybe generate one??? + if(!psCBuf) + { + if(HaveUniformBindingsAndLocations(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + bformata(glsl, "layout(location = %d) ",ui32BindingPoint); + + bformata(glsl, "layout(std140) uniform ConstantBuffer%d {\n\tvec4 data[%d];\n} cb%d;\n", ui32BindingPoint,psOperand->aui32ArraySizes[1],ui32BindingPoint); + break; + } + + switch(psContext->psShader->eShaderType) + { + case PIXEL_SHADER: + { + StageName = "PS"; + break; + } + case HULL_SHADER: + { + StageName = "HS"; + break; + } + case DOMAIN_SHADER: + { + StageName = "DS"; + break; + } + case GEOMETRY_SHADER: + { + StageName = "GS"; + break; + } + case COMPUTE_SHADER: + { + StageName = "CS"; + break; + } + default: + { + break; + } + } + + if(psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT) + { + if(psContext->flags & HLSLCC_FLAG_GLOBAL_CONSTS_NEVER_IN_UBO && psCBuf->Name[0] == '$') + { + DeclareStructConstants(psContext, ui32BindingPoint, psCBuf, psOperand, glsl); + } + else + { + DeclareUBOConstants(psContext, ui32BindingPoint, psCBuf, glsl); + } + } + else + { + DeclareStructConstants(psContext, ui32BindingPoint, psCBuf, psOperand, glsl); + } + break; + } + case OPCODE_DCL_RESOURCE: + { + if(HaveUniformBindingsAndLocations(psContext->psShader->eTargetLanguage,psContext->psShader->extensions)) + { + //Constant buffer locations start at 0. Resource locations start at ui32NumConstantBuffers. + bformata(glsl, "layout(location = %d) ", + psContext->psShader->sInfo.ui32NumConstantBuffers + psDecl->asOperands[0].ui32RegisterNumber); + } + + switch(psDecl->value.eResourceDimension) + { + case RESOURCE_DIMENSION_BUFFER: + { + bcatcstr(glsl, "uniform samplerBuffer "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + break; + } + case RESOURCE_DIMENSION_TEXTURE1D: + { + if(psDecl->ui32IsShadowTex) + { + //Create shadow and non-shadow sampler. + //HLSL does not have separate types for depth compare, just different functions. + bcatcstr(glsl, "uniform sampler1DShadow "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 1); + bcatcstr(glsl, ";\n"); + } + + bcatcstr(glsl, "uniform sampler1D "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 0); + break; + } + case RESOURCE_DIMENSION_TEXTURE2D: + { + if(psDecl->ui32IsShadowTex) + { + //Create shadow and non-shadow sampler. + //HLSL does not have separate types for depth compare, just different functions. + bcatcstr(glsl, "uniform sampler2DShadow "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 1); + bcatcstr(glsl, ";\n"); + } + bcatcstr(glsl, "uniform sampler2D "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 0); + break; + } + case RESOURCE_DIMENSION_TEXTURE2DMS: + { + bcatcstr(glsl, "uniform sampler2DMS "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + break; + } + case RESOURCE_DIMENSION_TEXTURE3D: + { + bcatcstr(glsl, "uniform sampler3D "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + break; + } + case RESOURCE_DIMENSION_TEXTURECUBE: + { + if(psDecl->ui32IsShadowTex) + { + //Create shadow and non-shadow sampler. + //HLSL does not have separate types for depth compare, just different functions. + bcatcstr(glsl, "uniform samplerCubeShadow "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 1); + bcatcstr(glsl, ";\n"); + } + + bcatcstr(glsl, "uniform samplerCube "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 0); + break; + } + case RESOURCE_DIMENSION_TEXTURE1DARRAY: + { + if(psDecl->ui32IsShadowTex) + { + //Create shadow and non-shadow sampler. + //HLSL does not have separate types for depth compare, just different functions. + bcatcstr(glsl, "uniform sampler1DArrayShadow "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 1); + bcatcstr(glsl, ";\n"); + } + + bcatcstr(glsl, "uniform sampler1DArray "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 0); + break; + } + case RESOURCE_DIMENSION_TEXTURE2DARRAY: + { + if(psDecl->ui32IsShadowTex) + { + //Create shadow and non-shadow sampler. + //HLSL does not have separate types for depth compare, just different functions. + bcatcstr(glsl, "uniform sampler2DArrayShadow "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 1); + bcatcstr(glsl, ";\n"); + } + + bcatcstr(glsl, "uniform sampler2DArray "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 0); + break; + } + case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: + { + bcatcstr(glsl, "uniform sampler3DArray "); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + break; + } + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: + { + if(psDecl->ui32IsShadowTex) + { + //Create shadow and non-shadow sampler. + //HLSL does not have separate types for depth compare, just different functions. + bcatcstr(glsl, "uniform samplerCubeArrayShadow "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 1); + bcatcstr(glsl, ";\n"); + } + + bcatcstr(glsl, "uniform samplerCubeArray "); + TextureName(psContext, psDecl->asOperands[0].ui32RegisterNumber, 0); + break; + } + } + bcatcstr(glsl, ";\n"); + ASSERT(psDecl->asOperands[0].ui32RegisterNumber < MAX_TEXTURES); + psShader->aeResourceDims[psDecl->asOperands[0].ui32RegisterNumber] = psDecl->value.eResourceDimension; + break; + } + case OPCODE_DCL_OUTPUT: + { + if(psShader->eShaderType == HULL_SHADER && psDecl->asOperands[0].ui32RegisterNumber==0) + { + AddBuiltinOutput(psContext, psDecl, GLVARTYPE_FLOAT4, 0, "gl_out[gl_InvocationID].gl_Position"); + } + else + { + AddUserOutput(psContext, psDecl); + } + break; + } + case OPCODE_DCL_GLOBAL_FLAGS: + { + uint32_t ui32Flags = psDecl->value.ui32GlobalFlags; + + if(ui32Flags & GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL) + { + bcatcstr(glsl, "layout(early_fragment_tests) in;\n"); + } + if(!(ui32Flags & GLOBAL_FLAG_REFACTORING_ALLOWED)) + { + //TODO add precise + //HLSL precise - http://msdn.microsoft.com/en-us/library/windows/desktop/hh447204(v=vs.85).aspx + } + if(ui32Flags & GLOBAL_FLAG_ENABLE_DOUBLE_PRECISION_FLOAT_OPS) + { + bcatcstr(glsl, "#extension GL_ARB_gpu_shader_fp64 : enable\n"); + psShader->fp64 = 1; + } + break; + } + + case OPCODE_DCL_THREAD_GROUP: + { + bformata(glsl, "layout(local_size_x = %d, local_size_y = %d, local_size_z = %d) in;\n", + psDecl->value.aui32WorkGroupSize[0], + psDecl->value.aui32WorkGroupSize[1], + psDecl->value.aui32WorkGroupSize[2]); + break; + } + case OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: + { + if(psContext->psShader->eShaderType == HULL_SHADER) + { + psContext->psShader->sInfo.eTessOutPrim = psDecl->value.eTessOutPrim; + } + break; + } + case OPCODE_DCL_TESS_DOMAIN: + { + if(psContext->psShader->eShaderType == DOMAIN_SHADER) + { + switch(psDecl->value.eTessDomain) + { + case TESSELLATOR_DOMAIN_ISOLINE: + { + bcatcstr(glsl, "layout(isolines) in;\n"); + break; + } + case TESSELLATOR_DOMAIN_TRI: + { + bcatcstr(glsl, "layout(triangles) in;\n"); + break; + } + case TESSELLATOR_DOMAIN_QUAD: + { + bcatcstr(glsl, "layout(quads) in;\n"); + break; + } + default: + { + break; + } + } + } + break; + } + case OPCODE_DCL_TESS_PARTITIONING: + { + if(psContext->psShader->eShaderType == HULL_SHADER) + { + psContext->psShader->sInfo.eTessPartitioning = psDecl->value.eTessPartitioning; + } + break; + } + case OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: + { + switch(psDecl->value.eOutputPrimitiveTopology) + { + case PRIMITIVE_TOPOLOGY_POINTLIST: + { + bcatcstr(glsl, "layout(points) out;\n"); + break; + } + case PRIMITIVE_TOPOLOGY_LINELIST_ADJ: + case PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ: + case PRIMITIVE_TOPOLOGY_LINELIST: + case PRIMITIVE_TOPOLOGY_LINESTRIP: + { + bcatcstr(glsl, "layout(line_strip) out;\n"); + break; + } + + case PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: + case PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ: + case PRIMITIVE_TOPOLOGY_TRIANGLESTRIP: + case PRIMITIVE_TOPOLOGY_TRIANGLELIST: + { + bcatcstr(glsl, "layout(triangle_strip) out;\n"); + break; + } + default: + { + break; + } + } + break; + } + case OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT: + { + bformata(glsl, "layout(max_vertices = %d) out;\n", psDecl->value.ui32MaxOutputVertexCount); + break; + } + case OPCODE_DCL_GS_INPUT_PRIMITIVE: + { + switch(psDecl->value.eInputPrimitive) + { + case PRIMITIVE_POINT: + { + bcatcstr(glsl, "layout(points) in;\n"); + break; + } + case PRIMITIVE_LINE: + { + bcatcstr(glsl, "layout(lines) in;\n"); + break; + } + case PRIMITIVE_LINE_ADJ: + { + bcatcstr(glsl, "layout(lines_adjacency) in;\n"); + break; + } + case PRIMITIVE_TRIANGLE: + { + bcatcstr(glsl, "layout(triangles) in;\n"); + break; + } + case PRIMITIVE_TRIANGLE_ADJ: + { + bcatcstr(glsl, "layout(triangles_adjacency) in;\n"); + break; + } + default: + { + break; + } + } + break; + } + case OPCODE_DCL_INTERFACE: + { + const uint32_t interfaceID = psDecl->value.interface.ui32InterfaceID; + const uint32_t numUniforms = psDecl->value.interface.ui32ArraySize; + const uint32_t ui32NumBodiesPerTable = psContext->psShader->funcPointer[interfaceID].ui32NumBodiesPerTable; + ShaderVar* psVar; + uint32_t varFound; + + const char* uniformName; + + varFound = GetInterfaceVarFromOffset(interfaceID, &psContext->psShader->sInfo, &psVar); + ASSERT(varFound); + uniformName = &psVar->Name[0]; + + bformata(glsl, "subroutine uniform SubroutineType %s[%d*%d];\n", uniformName, numUniforms, ui32NumBodiesPerTable); + break; + } + case OPCODE_DCL_FUNCTION_BODY: + { + //bformata(glsl, "void Func%d();//%d\n", psDecl->asOperands[0].ui32RegisterNumber, psDecl->asOperands[0].eType); + break; + } + case OPCODE_DCL_FUNCTION_TABLE: + { + break; + } + case OPCODE_CUSTOMDATA: + { + const uint32_t ui32NumVec4 = psDecl->ui32NumOperands; + const uint32_t ui32NumVec4Minus1 = (ui32NumVec4-1); + uint32_t ui32ConstIndex = 0; + float x, y, z, w; + + //If ShaderBitEncodingSupported then 1 integer buffer, use intBitsToFloat to get float values. - More instructions. + //else 2 buffers - one integer and one float. - More data + + if(ShaderBitEncodingSupported(psShader->eTargetLanguage) == 0) + { + bcatcstr(glsl, "#define immediateConstBufferI(idx) immediateConstBufferInt[idx]\n"); + bcatcstr(glsl, "#define immediateConstBufferF(idx) immediateConstBuffer[idx]\n"); + + bformata(glsl, "vec4 immediateConstBuffer[%d] = vec4[%d] (\n", ui32NumVec4, ui32NumVec4); + for(;ui32ConstIndex < ui32NumVec4Minus1; ui32ConstIndex++) + { + float loopLocalX, loopLocalY, loopLocalZ, loopLocalW; + loopLocalX = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].a; + loopLocalY = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].b; + loopLocalZ = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].c; + loopLocalW = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].d; + + //A single vec4 can mix integer and float types. + //Forced NAN and INF to zero inside the immediate constant buffer. This will allow the shader to compile. + if(fpcheck(loopLocalX)) + { + loopLocalX = 0; + } + if(fpcheck(loopLocalY)) + { + loopLocalY = 0; + } + if(fpcheck(loopLocalZ)) + { + loopLocalZ = 0; + } + if(fpcheck(loopLocalW)) + { + loopLocalW = 0; + } + + bformata(glsl, "\tvec4(%f, %f, %f, %f), \n", loopLocalX, loopLocalY, loopLocalZ, loopLocalW); + } + //No trailing comma on this one + x = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].a; + y = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].b; + z = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].c; + w = *(float*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].d; + if(fpcheck(x)) + { + x = 0; + } + if(fpcheck(y)) + { + y = 0; + } + if(fpcheck(z)) + { + z = 0; + } + if(fpcheck(w)) + { + w = 0; + } + bformata(glsl, "\tvec4(%f, %f, %f, %f)\n", x, y, z, w); + bcatcstr(glsl, ");\n"); + } + else + { + bcatcstr(glsl, "#define immediateConstBufferI(idx) immediateConstBufferInt[idx]\n"); + bcatcstr(glsl, "#define immediateConstBufferF(idx) intBitsToFloat(immediateConstBufferInt[idx])\n"); + } + + { + uint32_t ui32ConstIndex = 0; + int x, y, z, w; + + bformata(glsl, "ivec4 immediateConstBufferInt[%d] = ivec4[%d] (\n", ui32NumVec4, ui32NumVec4); + for(;ui32ConstIndex < ui32NumVec4Minus1; ui32ConstIndex++) + { + int loopLocalX, loopLocalY, loopLocalZ, loopLocalW; + loopLocalX = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].a; + loopLocalY = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].b; + loopLocalZ = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].c; + loopLocalW = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].d; + + bformata(glsl, "\tivec4(%d, %d, %d, %d), \n", loopLocalX, loopLocalY, loopLocalZ, loopLocalW); + } + //No trailing comma on this one + x = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].a; + y = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].b; + z = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].c; + w = *(int*)&psDecl->asImmediateConstBuffer[ui32ConstIndex].d; + + bformata(glsl, "\tivec4(%d, %d, %d, %d)\n", x, y, z, w); + bcatcstr(glsl, ");\n"); + } + + break; + } + case OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: + { + const uint32_t forkPhaseNum = psDecl->value.aui32HullPhaseInstanceInfo[0]; + const uint32_t instanceCount = psDecl->value.aui32HullPhaseInstanceInfo[1]; + bformata(glsl, "const int HullPhase%dInstanceCount = %d;\n", forkPhaseNum, instanceCount); + break; + } + case OPCODE_DCL_INDEXABLE_TEMP: + { + const uint32_t ui32RegIndex = psDecl->sIdxTemp.ui32RegIndex; + const uint32_t ui32RegCount = psDecl->sIdxTemp.ui32RegCount; + const uint32_t ui32RegComponentSize = psDecl->sIdxTemp.ui32RegComponentSize; + bformata(glsl, "vec%d TempArray%d[%d];\n", ui32RegComponentSize, ui32RegIndex, ui32RegCount); + bformata(glsl, "ivec%d TempArray%d_int[%d];\n", ui32RegComponentSize, ui32RegIndex, ui32RegCount); + if(HaveUVec(psShader->eTargetLanguage)) + { + bformata(glsl, "uvec%d TempArray%d_uint[%d];\n", ui32RegComponentSize, ui32RegIndex, ui32RegCount); + } + if(psShader->fp64) + { + bformata(glsl, "dvec%d TempArray%d_double[%d];\n", ui32RegComponentSize, ui32RegIndex, ui32RegCount); + } + break; + } + case OPCODE_DCL_INDEX_RANGE: + { + break; + } + case OPCODE_HS_DECLS: + { + break; + } + case OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: + { + break; + } + case OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: + { + if(psContext->psShader->eShaderType == HULL_SHADER) + { + bformata(glsl, "layout(vertices=%d) out;\n", psDecl->value.ui32MaxOutputVertexCount); + } + break; + } + case OPCODE_HS_FORK_PHASE: + { + break; + } + case OPCODE_HS_JOIN_PHASE: + { + break; + } + case OPCODE_DCL_SAMPLER: + { + break; + } + case OPCODE_DCL_HS_MAX_TESSFACTOR: + { + //For GLSL the max tessellation factor is fixed to the value of gl_MaxTessGenLevel. + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: + { + if(psDecl->sUAV.ui32GloballyCoherentAccess & GLOBALLY_COHERENT_ACCESS) + { + bcatcstr(glsl, "coherent "); + } + + if(psShader->aiOpcodeUsed[OPCODE_LD_UAV_TYPED] == 0) + { + bcatcstr(glsl, "writeonly "); + } + else + { + if(psShader->aiOpcodeUsed[OPCODE_STORE_UAV_TYPED] == 0) + { + bcatcstr(glsl, "readonly "); + } + + switch(psDecl->sUAV.Type) + { + case RETURN_TYPE_FLOAT: + bcatcstr(glsl, "layout(rgba32f) "); + break; + case RETURN_TYPE_UNORM: + bcatcstr(glsl, "layout(rgba8) "); + break; + case RETURN_TYPE_SNORM: + bcatcstr(glsl, "layout(rgba8_snorm) "); + break; + case RETURN_TYPE_UINT: + bcatcstr(glsl, "layout(rgba32ui) "); + break; + case RETURN_TYPE_SINT: + bcatcstr(glsl, "layout(rgba32i) "); + break; + default: + ASSERT(0); + } + } + + switch(psDecl->value.eResourceDimension) + { + case RESOURCE_DIMENSION_BUFFER: + { + bcatcstr(glsl, "uniform imageBuffer "); + break; + } + case RESOURCE_DIMENSION_TEXTURE1D: + { + bcatcstr(glsl, "uniform image1D "); + break; + } + case RESOURCE_DIMENSION_TEXTURE2D: + { + bcatcstr(glsl, "uniform image2D "); + break; + } + case RESOURCE_DIMENSION_TEXTURE2DMS: + { + bcatcstr(glsl, "uniform image2DMS "); + break; + } + case RESOURCE_DIMENSION_TEXTURE3D: + { + bcatcstr(glsl, "uniform image3D "); + break; + } + case RESOURCE_DIMENSION_TEXTURECUBE: + { + bcatcstr(glsl, "uniform imageCube "); + break; + } + case RESOURCE_DIMENSION_TEXTURE1DARRAY: + { + bcatcstr(glsl, "uniform image1DArray "); + break; + } + case RESOURCE_DIMENSION_TEXTURE2DARRAY: + { + bcatcstr(glsl, "uniform image2DArray "); + break; + } + case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: + { + bcatcstr(glsl, "uniform image3DArray "); + break; + } + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: + { + bcatcstr(glsl, "uniform imageCubeArray "); + break; + } + } + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: + { + const uint32_t ui32BindingPoint = psDecl->asOperands[0].aui32ArraySizes[0]; + ConstantBuffer* psCBuf = NULL; + + if(psDecl->sUAV.bCounter) + { + bformata(glsl, "layout (binding = 1) uniform atomic_uint UAV%d_counter;\n", psDecl->asOperands[0].ui32RegisterNumber); + } + + GetConstantBufferFromBindingPoint(RGROUP_UAV, ui32BindingPoint, &psContext->psShader->sInfo, &psCBuf); + + DeclareBufferVariable(psContext, ui32BindingPoint, psCBuf, &psDecl->asOperands[0], + psDecl->sUAV.ui32GloballyCoherentAccess, RTYPE_UAV_RWSTRUCTURED, glsl); + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW: + { + if(psDecl->sUAV.bCounter) + { + bformata(glsl, "layout (binding = 1) uniform atomic_uint UAV%d_counter;\n", psDecl->asOperands[0].ui32RegisterNumber); + } + + bformata(glsl, "buffer Block%d {\n\tuint UAV%d[];\n};\n", psDecl->asOperands[0].ui32RegisterNumber, psDecl->asOperands[0].ui32RegisterNumber); + break; + } + case OPCODE_DCL_RESOURCE_STRUCTURED: + { + ConstantBuffer* psCBuf = NULL; + + GetConstantBufferFromBindingPoint(RGROUP_TEXTURE, psDecl->asOperands[0].ui32RegisterNumber, &psContext->psShader->sInfo, &psCBuf); + + DeclareBufferVariable(psContext, psDecl->asOperands[0].ui32RegisterNumber, psCBuf, &psDecl->asOperands[0], + 0, RTYPE_STRUCTURED, glsl); + break; + } + case OPCODE_DCL_RESOURCE_RAW: + { + bformata(glsl, "buffer Block%d {\n\tuint RawRes%d[];\n};\n", psDecl->asOperands[0].ui32RegisterNumber, psDecl->asOperands[0].ui32RegisterNumber); + break; + } + case OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: + { + ShaderVarType* psVarType = &psShader->sGroupSharedVarType[psDecl->asOperands[0].ui32RegisterNumber]; + + ASSERT(psDecl->asOperands[0].ui32RegisterNumber < MAX_GROUPSHARED); + + bcatcstr(glsl, "shared struct {"); + bformata(glsl, "float value[%d];", psDecl->sTGSM.ui32Stride/4); + bcatcstr(glsl, "}"); + TranslateOperand(psContext, &psDecl->asOperands[0], TO_FLAG_NONE); + bformata(glsl, "[%d];\n", + psDecl->sTGSM.ui32Count); + + memset(psVarType, 0, sizeof(ShaderVarType)); + strcpy(psVarType->Name, "$Element"); + + psVarType->Columns = psDecl->sTGSM.ui32Stride/4; + psVarType->Elements = psDecl->sTGSM.ui32Count; + break; + } + case OPCODE_DCL_STREAM: + { + ASSERT(psDecl->asOperands[0].eType == OPERAND_TYPE_STREAM); + + psShader->ui32CurrentVertexOutputStream = psDecl->asOperands[0].ui32RegisterNumber; + + bformata(glsl, "layout(stream = %d) out;\n", psShader->ui32CurrentVertexOutputStream); + + break; + } + case OPCODE_DCL_GS_INSTANCE_COUNT: + { + bformata(glsl, "layout(invocations = %d) in;\n", psDecl->value.ui32GSInstanceCount); + break; + } + default: + { + ASSERT(0); + break; + } + } +} + +//Convert from per-phase temps to global temps for GLSL. +void ConsolidateHullTempVars(Shader* psShader) +{ + uint32_t i, k; + const uint32_t ui32NumDeclLists = 3+psShader->ui32ForkPhaseCount; + Declaration* pasDeclArray[3+MAX_FORK_PHASES]; + uint32_t aui32DeclCounts[3+MAX_FORK_PHASES]; + uint32_t ui32NumTemps = 0; + + i = 0; + + pasDeclArray[i] = psShader->psHSDecl; + aui32DeclCounts[i++] = psShader->ui32HSDeclCount; + + pasDeclArray[i] = psShader->psHSControlPointPhaseDecl; + aui32DeclCounts[i++] = psShader->ui32HSControlPointDeclCount; + for(k=0; k < psShader->ui32ForkPhaseCount; ++k) + { + pasDeclArray[i] = psShader->apsHSForkPhaseDecl[k]; + aui32DeclCounts[i++] = psShader->aui32HSForkDeclCount[k]; + } + pasDeclArray[i] = psShader->psHSJoinPhaseDecl; + aui32DeclCounts[i++] = psShader->ui32HSJoinDeclCount; + + for(k = 0; k < ui32NumDeclLists; ++k) + { + for(i=0; i < aui32DeclCounts[k]; ++i) + { + Declaration* psDecl = pasDeclArray[k]+i; + + if(psDecl->eOpcode == OPCODE_DCL_TEMPS) + { + if(ui32NumTemps < psDecl->value.ui32NumTemps) + { + //Find the total max number of temps needed by the entire + //shader. + ui32NumTemps = psDecl->value.ui32NumTemps; + } + //Only want one global temp declaration. + psDecl->value.ui32NumTemps = 0; + } + } + } + + //Find the first temp declaration and make it + //declare the max needed amount of temps. + for(k = 0; k < ui32NumDeclLists; ++k) + { + for(i=0; i < aui32DeclCounts[k]; ++i) + { + Declaration* psDecl = pasDeclArray[k]+i; + + if(psDecl->eOpcode == OPCODE_DCL_TEMPS) + { + psDecl->value.ui32NumTemps = ui32NumTemps; + return; + } + } + } +} + diff --git a/build/tools/HLSLcc/May_2014/src/toGLSLInstruction.c b/build/tools/HLSLcc/May_2014/src/toGLSLInstruction.c new file mode 100644 index 0000000..253a2d2 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/toGLSLInstruction.c @@ -0,0 +1,4305 @@ +#include "internal_includes/toGLSLInstruction.h" +#include "internal_includes/toGLSLOperand.h" +#include "internal_includes/languages.h" +#include "bstrlib.h" +#include "stdio.h" +#include "internal_includes/debug.h" + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +extern void AddIndentation(HLSLCrossCompilerContext* psContext); + +typedef enum +{ + CMP_EQ, + CMP_LT, + CMP_GE, + CMP_NE, +} ComparisonType; + +static void AddComparision(HLSLCrossCompilerContext* psContext, Instruction* psInst, ComparisonType eType, + uint32_t typeFlag) +{ + bstring glsl = *psContext->currentGLSLString; + const uint32_t destElemCount = GetNumSwizzleElements(&psInst->asOperands[0]); + const uint32_t s0ElemCount = GetNumSwizzleElements(&psInst->asOperands[1]); + const uint32_t s1ElemCount = GetNumSwizzleElements(&psInst->asOperands[2]); + + uint32_t minElemCount = destElemCount < s0ElemCount ? destElemCount : s0ElemCount; + + SHADER_VARIABLE_TYPE eDestType = GetOperandDataType(psContext, &psInst->asOperands[0]); + + minElemCount = s1ElemCount < minElemCount ? s1ElemCount : minElemCount; + + if(destElemCount > 1) + { + const char* glslOpcode [] = { + "equal", + "lessThan", + "greaterThanEqual", + "notEqual", + }; + char* constructor = "vec"; + + if(typeFlag & TO_FLAG_INTEGER) + { + constructor = "ivec"; + } + else if(typeFlag & TO_FLAG_UNSIGNED_INTEGER) + { + constructor = "uvec"; + } + + //Component-wise compare + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + if(eDestType == SVT_UINT) + { + bformata(glsl, " = uvec%d(%s(%s4(", minElemCount, glslOpcode[eType], constructor); + } + else if(eDestType == SVT_INT) + { + bformata(glsl, " = ivec%d(%s(%s4(", minElemCount, glslOpcode[eType], constructor); + } + else if(eDestType == SVT_UINT) + { + bformata(glsl, " = vec%d(%s(%s4(", minElemCount, glslOpcode[eType], constructor); + } + TranslateOperand(psContext, &psInst->asOperands[1], typeFlag); + bcatcstr(glsl, ")"); + AddSwizzleUsingElementCount(psContext, minElemCount); + bformata(glsl, ", %s4(", constructor); + TranslateOperand(psContext, &psInst->asOperands[2], typeFlag); + bcatcstr(glsl, ")"); + AddSwizzleUsingElementCount(psContext, minElemCount); + if(psContext->psShader->ui32MajorVersion < 4) + { + //Result is 1.0f or 0.0f + bcatcstr(glsl, "));\n"); + } + else + { + if(eDestType == SVT_UINT) + { + bcatcstr(glsl, ")) * 0xFFFFFFFFu;\n"); + } + else + { + bcatcstr(glsl, ")) * 0xFFFFFFFF;\n"); + } + } + } + else + { + const char* glslOpcode [] = { + "==", + "<", + ">=", + "!=", + }; + + //Scalar compare + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = (("); + TranslateOperand(psContext, &psInst->asOperands[1], typeFlag); + bcatcstr(glsl, ")"); + if(s0ElemCount > minElemCount) + AddSwizzleUsingElementCount(psContext, minElemCount); + bformata(glsl, "%s (", glslOpcode[eType]); + TranslateOperand(psContext, &psInst->asOperands[2], typeFlag); + bcatcstr(glsl, ")"); + if(s1ElemCount > minElemCount) + AddSwizzleUsingElementCount(psContext, minElemCount); + if(psContext->psShader->ui32MajorVersion < 4) + { + bcatcstr(glsl, ") ? 1.0f : 1.0f;\n"); + } + else + { + if(eDestType == SVT_UINT) + { + bcatcstr(glsl, ") ? 0xFFFFFFFFu : 0u;\n"); + } + else + { + bcatcstr(glsl, ") ? 0xFFFFFFFF : 0;\n"); + } + } + } +} +static void AddMOVCBinaryOp(HLSLCrossCompilerContext* psContext,const Operand *pDest,const Operand *src0,const Operand *src1,const Operand *src2) +{ + bstring glsl = *psContext->currentGLSLString; + uint32_t destElemCount = GetNumSwizzleElements(pDest); + uint32_t s0ElemCount = GetNumSwizzleElements(src0); + uint32_t s1ElemCount = GetNumSwizzleElements(src1); + uint32_t s2ElemCount = GetNumSwizzleElements(src2); + uint32_t destElem; + /* + for each component in dest[.mask] + if the corresponding component in src0 (POS-swizzle) + has any bit set + { + copy this component (POS-swizzle) from src1 into dest + } + else + { + copy this component (POS-swizzle) from src2 into dest + } + endfor + */ + + /* Single-component conditional variable (src0) */ + if(s0ElemCount==1 || IsSwizzleReplacated(src0)) + { + AddIndentation(psContext); + bcatcstr(glsl, "if(vec4("); + + TranslateOperand(psContext, src0, TO_FLAG_NONE); + + bcatcstr(glsl, ").x"); + + if(psContext->psShader->ui32MajorVersion < 4) + { + //cmp opcode uses >= 0 + bcatcstr(glsl, " >= 0.0) {\n"); + } + else + { + bcatcstr(glsl, " != 0.0) {\n"); + } + + psContext->indent++; + AddIndentation(psContext); + TranslateOperand(psContext, pDest, TO_FLAG_DESTINATION); + bcatcstr(glsl, " = "); + if(destElemCount != s1ElemCount) + { + bcatcstr(glsl, "vec4("); + } + TranslateOperand(psContext, src1, TO_FLAG_NONE); + if(destElemCount != s1ElemCount) + { + bcatcstr(glsl, ")"); + AddSwizzleUsingElementCount(psContext, destElemCount); + } + bcatcstr(glsl, ";\n"); + + psContext->indent--; + AddIndentation(psContext); + bcatcstr(glsl, "} else {\n"); + psContext->indent++; + AddIndentation(psContext); + TranslateOperand(psContext, pDest, TO_FLAG_DESTINATION); + bcatcstr(glsl, " = "); + if(destElemCount != s2ElemCount) + { + bcatcstr(glsl, "vec4("); + } + TranslateOperand(psContext, src2, TO_FLAG_NONE); + if(destElemCount != s2ElemCount) + { + bcatcstr(glsl, ")"); + AddSwizzleUsingElementCount(psContext, destElemCount); + } + bcatcstr(glsl, ";\n"); + psContext->indent--; + AddIndentation(psContext); + bcatcstr(glsl, "}\n"); + } + else + { + for(destElem=0; destElem < destElemCount; ++destElem) + { + const char* swizzle[] = {".x", ".y", ".z", ".w"}; + + AddIndentation(psContext); + bcatcstr(glsl, "if("); + TranslateOperand(psContext, src0, TO_FLAG_NONE); + if(s0ElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + + if(psContext->psShader->ui32MajorVersion < 4) + { + //cmp opcode uses >= 0 + bcatcstr(glsl, " >= 0) {\n"); + } + else + { + bcatcstr(glsl, " != 0) {\n"); + } + + psContext->indent++; + AddIndentation(psContext); + TranslateOperand(psContext, pDest, TO_FLAG_DESTINATION); + if(destElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + bcatcstr(glsl, " = "); + TranslateOperand(psContext, src1, TO_FLAG_NONE); + if(s1ElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + bcatcstr(glsl, ";\n"); + + psContext->indent--; + AddIndentation(psContext); + bcatcstr(glsl, "} else {\n"); + psContext->indent++; + AddIndentation(psContext); + TranslateOperand(psContext, pDest, TO_FLAG_DESTINATION); + if(destElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + bcatcstr(glsl, " = "); + TranslateOperand(psContext, src2, TO_FLAG_NONE); + if(s2ElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + bcatcstr(glsl, ";\n"); + psContext->indent--; + AddIndentation(psContext); + bcatcstr(glsl, "}\n"); + } + } +} + +void CallBinaryOp(HLSLCrossCompilerContext* psContext, const char* name, Instruction* psInst, + int dest, int src0, int src1, uint32_t dataType) +{ + bstring glsl = *psContext->currentGLSLString; + uint32_t src1SwizCount = GetNumSwizzleElements(&psInst->asOperands[src1]); + uint32_t src0SwizCount = GetNumSwizzleElements(&psInst->asOperands[src0]); + uint32_t dstSwizCount = GetNumSwizzleElements(&psInst->asOperands[dest]); + + AddIndentation(psContext); + + if(src1SwizCount == src0SwizCount == dstSwizCount) + { + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION|dataType); + bcatcstr(glsl, " = "); + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_NONE|dataType); + bformata(glsl, " %s ", name); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_NONE|dataType); + bcatcstr(glsl, ";\n"); + } + else + { + //Upconvert the inputs to vec4 then apply the dest swizzle. + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION|dataType); + if(dataType == TO_FLAG_UNSIGNED_INTEGER) + { + bcatcstr(glsl, " = uvec4("); + } + else if(dataType == TO_FLAG_INTEGER) + { + bcatcstr(glsl, " = ivec4("); + } + else + { + bcatcstr(glsl, " = vec4("); + } + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_NONE|dataType); + bformata(glsl, " %s ", name); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_NONE|dataType); + bcatcstr(glsl, ")"); + //Limit src swizzles based on dest swizzle + //e.g. given hlsl asm: add r0.xy, v0.xyxx, l(0.100000, 0.000000, 0.000000, 0.000000) + //the two sources must become vec2 + //Temp0.xy = Input0.xyxx + vec4(0.100000, 0.000000, 0.000000, 0.000000); + //becomes + //Temp0.xy = vec4(Input0.xyxx + vec4(0.100000, 0.000000, 0.000000, 0.000000)).xy; + + TranslateOperandSwizzle(psContext, &psInst->asOperands[dest]); + bcatcstr(glsl, ";\n"); + } +} + +void CallTernaryOp(HLSLCrossCompilerContext* psContext, const char* op1, const char* op2, Instruction* psInst, + int dest, int src0, int src1, int src2, uint32_t dataType) +{ + bstring glsl = *psContext->currentGLSLString; + uint32_t src2SwizCount = GetNumSwizzleElements(&psInst->asOperands[src2]); + uint32_t src1SwizCount = GetNumSwizzleElements(&psInst->asOperands[src1]); + uint32_t src0SwizCount = GetNumSwizzleElements(&psInst->asOperands[src0]); + uint32_t dstSwizCount = GetNumSwizzleElements(&psInst->asOperands[dest]); + + AddIndentation(psContext); + + if(src1SwizCount == src0SwizCount == src2SwizCount == dstSwizCount) + { + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION|dataType); + bcatcstr(glsl, " = "); + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_NONE|dataType); + bformata(glsl, " %s ", op1); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_NONE|dataType); + bformata(glsl, " %s ", op2); + TranslateOperand(psContext, &psInst->asOperands[src2], TO_FLAG_NONE|dataType); + bcatcstr(glsl, ";\n"); + } + else + { + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION|dataType); + if(dataType == TO_FLAG_UNSIGNED_INTEGER) + { + bcatcstr(glsl, " = uvec4("); + } + else if(dataType == TO_FLAG_INTEGER) + { + bcatcstr(glsl, " = ivec4("); + } + else + { + bcatcstr(glsl, " = vec4("); + } + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_NONE|dataType); + bformata(glsl, " %s ", op1); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_NONE|dataType); + bformata(glsl, " %s ", op2); + TranslateOperand(psContext, &psInst->asOperands[src2], TO_FLAG_NONE|dataType); + bcatcstr(glsl, ")"); + //Limit src swizzles based on dest swizzle + //e.g. given hlsl asm: add r0.xy, v0.xyxx, l(0.100000, 0.000000, 0.000000, 0.000000) + //the two sources must become vec2 + //Temp0.xy = Input0.xyxx + vec4(0.100000, 0.000000, 0.000000, 0.000000); + //becomes + //Temp0.xy = vec4(Input0.xyxx + vec4(0.100000, 0.000000, 0.000000, 0.000000)).xy; + TranslateOperandSwizzle(psContext, &psInst->asOperands[dest]); + bcatcstr(glsl, ";\n"); + } +} + +void CallHelper3(HLSLCrossCompilerContext* psContext, const char* name, Instruction* psInst, + int dest, int src0, int src1, int src2) +{ + bstring glsl = *psContext->currentGLSLString; + AddIndentation(psContext); + + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION); + + bcatcstr(glsl, " = vec4("); + + bcatcstr(glsl, name); + bcatcstr(glsl, "("); + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_DESTINATION); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_NONE); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[src2], TO_FLAG_NONE); + bcatcstr(glsl, "))"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[dest]); + bcatcstr(glsl, ";\n"); +} + +void CallHelper2(HLSLCrossCompilerContext* psContext, const char* name, Instruction* psInst, + int dest, int src0, int src1) +{ + bstring glsl = *psContext->currentGLSLString; + AddIndentation(psContext); + + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION); + + bcatcstr(glsl, " = vec4("); + + bcatcstr(glsl, name); + bcatcstr(glsl, "("); + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_NONE); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_NONE); + bcatcstr(glsl, "))"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[dest]); + bcatcstr(glsl, ";\n"); +} + +void CallHelper2Int(HLSLCrossCompilerContext* psContext, const char* name, Instruction* psInst, + int dest, int src0, int src1) +{ + bstring glsl = *psContext->currentGLSLString; + AddIndentation(psContext); + + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION); + + bcatcstr(glsl, " = ivec4("); + + bcatcstr(glsl, name); + bcatcstr(glsl, "(int("); + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_INTEGER); + bcatcstr(glsl, "), int("); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_INTEGER); + bcatcstr(glsl, ")))"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[dest]); + bcatcstr(glsl, ";\n"); +} +void CallHelper2UInt(HLSLCrossCompilerContext* psContext, const char* name, Instruction* psInst, + int dest, int src0, int src1) +{ + bstring glsl = *psContext->currentGLSLString; + AddIndentation(psContext); + + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION); + + bcatcstr(glsl, " = ivec4("); + + bcatcstr(glsl, name); + bcatcstr(glsl, "(int("); + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_UNSIGNED_INTEGER); + bcatcstr(glsl, "), int("); + TranslateOperand(psContext, &psInst->asOperands[src1], TO_FLAG_UNSIGNED_INTEGER); + bcatcstr(glsl, ")))"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[dest]); + bcatcstr(glsl, ";\n"); +} + +void CallHelper1(HLSLCrossCompilerContext* psContext, const char* name, Instruction* psInst, + int dest, int src0) +{ + bstring glsl = *psContext->currentGLSLString; + SHADER_VARIABLE_TYPE eDestDataType = GetOperandDataType(psContext, &psInst->asOperands[dest]); + + AddIndentation(psContext); + + TranslateOperand(psContext, &psInst->asOperands[dest], TO_FLAG_DESTINATION); + + switch(eDestDataType) + { + case SVT_INT: + { + bcatcstr(glsl, " = ivec4("); + break; + } + case SVT_UINT: + { + bcatcstr(glsl, " = uvec4("); + break; + } + case SVT_FLOAT: + default: + { + bcatcstr(glsl, " = vec4("); + break; + } + } + + bcatcstr(glsl, name); + bcatcstr(glsl, "("); + TranslateOperand(psContext, &psInst->asOperands[src0], TO_FLAG_NONE); + bcatcstr(glsl, "))"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[dest]); + bcatcstr(glsl, ";\n"); +} + +static void TranslateTexelFetch(HLSLCrossCompilerContext* psContext, + Instruction* psInst, + ResourceBinding* psBinding, + bstring glsl) +{ + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + //AddAssignToDest(psContext, &psInst->asOperands[0], ResourceReturnTypeToFlag(psBinding->ui32ReturnType)); + bcatcstr(glsl, " = texelFetch("); + + switch(psBinding->eDimension) + { + case REFLECT_RESOURCE_DIMENSION_TEXTURE1D: + { + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", int(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ").x), 0)"); + break; + } + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DARRAY: + case REFLECT_RESOURCE_DIMENSION_TEXTURE3D: + { + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", ivec3(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ").xyz), 0)"); + break; + } + case REFLECT_RESOURCE_DIMENSION_TEXTURE2D: + case REFLECT_RESOURCE_DIMENSION_TEXTURE1DARRAY: + { + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", ivec2(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ").xy), 0)"); + break; + } + case REFLECT_RESOURCE_DIMENSION_BUFFER: + { + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", int(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ").x))"); + break; + } + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DMS: + { + ASSERT(psInst->eOpcode == OPCODE_LD_MS); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", ivec2(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ").xy), "); + TranslateOperand(psContext, &psInst->asOperands[3], TO_FLAG_INTEGER); + bcatcstr(glsl, ")"); + break; + } + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DMSARRAY: + { + ASSERT(psInst->eOpcode == OPCODE_LD_MS); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", ivec3(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ").xyz), "); + TranslateOperand(psContext, &psInst->asOperands[3], TO_FLAG_INTEGER); + bcatcstr(glsl, ")"); + break; + } + case REFLECT_RESOURCE_DIMENSION_TEXTURECUBE: + case REFLECT_RESOURCE_DIMENSION_TEXTURECUBEARRAY: + case REFLECT_RESOURCE_DIMENSION_BUFFEREX: + default: + { + ASSERT(0); + break; + } + } + + TranslateOperandSwizzle(psContext, &psInst->asOperands[2]); + //bcatcstr(glsl, ")"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); +} + +static void TranslateTexelFetchOffset(HLSLCrossCompilerContext* psContext, + Instruction* psInst, + ResourceBinding* psBinding, + bstring glsl) +{ + switch(psBinding->eDimension) + { + case REFLECT_RESOURCE_DIMENSION_TEXTURE1D: + { + //texelFetch(samplerBuffer, int coord, level, offset) + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = texelFetchOffset("); + + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", int(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bformata(glsl, ").x), 0, %d", psInst->iUAddrOffset); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DARRAY: + case REFLECT_RESOURCE_DIMENSION_TEXTURE3D: + { + //texelFetch(samplerBuffer, ivec3 coord, level) + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = texelFetchOffset("); + + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", ivec3(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bformata(glsl, ").xyz), 0, ive3(%d, %d, %d))", + psInst->iUAddrOffset, + psInst->iVAddrOffset, + psInst->iWAddrOffset); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case REFLECT_RESOURCE_DIMENSION_TEXTURE2D: + case REFLECT_RESOURCE_DIMENSION_TEXTURE1DARRAY: + { + //texelFetch(samplerBuffer, ivec2 coord, level) + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = texelFetchOffset("); + + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", ivec2(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bformata(glsl, ").xy), 0, ivec2(%d, %d))", psInst->iUAddrOffset, psInst->iVAddrOffset); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case REFLECT_RESOURCE_DIMENSION_BUFFER: + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DMS: + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DMSARRAY: + case REFLECT_RESOURCE_DIMENSION_TEXTURECUBE: + case REFLECT_RESOURCE_DIMENSION_TEXTURECUBEARRAY: + case REFLECT_RESOURCE_DIMENSION_BUFFEREX: + default: + { + ASSERT(0); + break; + } + } +} + + +//Makes sure the texture coordinate swizzle is appropriate for the texture type. +//i.e. vecX for X-dimension texture. +//Currently supports floating point coord only, so not used for texelFetch. +static void TranslateTexCoord(HLSLCrossCompilerContext* psContext, + const RESOURCE_DIMENSION eResDim, + Operand* psTexCoordOperand) +{ + int constructor = 0; + bstring glsl = *psContext->currentGLSLString; + + switch(eResDim) + { + case RESOURCE_DIMENSION_TEXTURE1D: + { + //Vec1 texcoord. Mask out the other components. + psTexCoordOperand->aui32Swizzle[1] = 0xFFFFFFFF; + psTexCoordOperand->aui32Swizzle[2] = 0xFFFFFFFF; + psTexCoordOperand->aui32Swizzle[3] = 0xFFFFFFFF; + if(psTexCoordOperand->eType == OPERAND_TYPE_IMMEDIATE32 || + psTexCoordOperand->eType == OPERAND_TYPE_IMMEDIATE64) + { + psTexCoordOperand->iNumComponents = 1; + } + break; + } + case RESOURCE_DIMENSION_TEXTURE2D: + case RESOURCE_DIMENSION_TEXTURE1DARRAY: + { + //Vec2 texcoord. Mask out the other components. + psTexCoordOperand->aui32Swizzle[2] = 0xFFFFFFFF; + psTexCoordOperand->aui32Swizzle[3] = 0xFFFFFFFF; + if(psTexCoordOperand->eType == OPERAND_TYPE_IMMEDIATE32 || + psTexCoordOperand->eType == OPERAND_TYPE_IMMEDIATE64) + { + psTexCoordOperand->iNumComponents = 2; + } + if(psTexCoordOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + constructor = 1; + bcatcstr(glsl, "vec2("); + } + break; + } + case RESOURCE_DIMENSION_TEXTURECUBE: + case RESOURCE_DIMENSION_TEXTURE3D: + case RESOURCE_DIMENSION_TEXTURE2DARRAY: + { + //Vec3 texcoord. Mask out the other component. + psTexCoordOperand->aui32Swizzle[3] = 0xFFFFFFFF; + if(psTexCoordOperand->eType == OPERAND_TYPE_IMMEDIATE32 || + psTexCoordOperand->eType == OPERAND_TYPE_IMMEDIATE64) + { + psTexCoordOperand->iNumComponents = 3; + } + if(psTexCoordOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + constructor = 1; + bcatcstr(glsl, "vec3("); + } + break; + } + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: + { + if(psTexCoordOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + constructor = 1; + bcatcstr(glsl, "vec4("); + } + break; + } + default: + { + ASSERT(0); + break; + } + } + + TranslateOperand(psContext, psTexCoordOperand, TO_FLAG_NONE); + + if(constructor) + { + bcatcstr(glsl, ")"); + } +} + +static int GetNumTextureDimensions(HLSLCrossCompilerContext* psContext, + const RESOURCE_DIMENSION eResDim) +{ + int constructor = 0; + bstring glsl = *psContext->currentGLSLString; + + switch(eResDim) + { + case RESOURCE_DIMENSION_TEXTURE1D: + { + return 1; + } + case RESOURCE_DIMENSION_TEXTURE2D: + case RESOURCE_DIMENSION_TEXTURE1DARRAY: + case RESOURCE_DIMENSION_TEXTURECUBE: + { + return 2; + } + + case RESOURCE_DIMENSION_TEXTURE3D: + case RESOURCE_DIMENSION_TEXTURE2DARRAY: + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: + { + return 3; + } + default: + { + ASSERT(0); + break; + } + } + return 0; +} + +void GetResInfoData(HLSLCrossCompilerContext* psContext, Instruction* psInst, int index) +{ + bstring glsl = *psContext->currentGLSLString; + const RESINFO_RETURN_TYPE eResInfoReturnType = psInst->eResInfoReturnType; + const RESOURCE_DIMENSION eResDim = psContext->psShader->aeResourceDims[psInst->asOperands[2].ui32RegisterNumber]; + + //[width, height, depth or array size, total-mip-count] + if(index < 3) + { + int dim = GetNumTextureDimensions(psContext, eResDim); + + if(dim < (index+1)) + { + bcatcstr(glsl, "0"); + } + else + { + if(eResInfoReturnType == RESINFO_INSTRUCTION_RETURN_UINT) + { + bformata(glsl, "ivec%d(textureSize(", dim); + } + else if(eResInfoReturnType == RESINFO_INSTRUCTION_RETURN_RCPFLOAT) + { + bformata(glsl, "vec%d(1.0f) / vec%d(textureSize(", dim, dim); + } + else + { + bformata(glsl, "vec%d(textureSize(", dim); + } + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, "))"); + + switch(index) + { + case 0: + bcatcstr(glsl, ".x"); + break; + case 1: + bcatcstr(glsl, ".y"); + break; + case 2: + bcatcstr(glsl, ".z"); + break; + } + } + + bcatcstr(glsl, ";\n"); + } + else + { + bcatcstr(glsl,"textureQueryLevels("); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ");\n"); + } +} + +#define TEXSMP_FLAG_NONE 0x0 +#define TEXSMP_FLAG_LOD 0x1 //LOD comes from operand +#define TEXSMP_FLAG_DEPTHCOMPARE 0x2 +#define TEXSMP_FLAG_FIRSTLOD 0x4 //LOD is 0 +#define TEXSMP_FLAG_BIAS 0x8 +#define TEXSMP_FLAGS_GRAD 0x10 +static void TranslateTextureSample(HLSLCrossCompilerContext* psContext, Instruction* psInst, + uint32_t ui32Flags) +{ + bstring glsl = *psContext->currentGLSLString; + + const char* funcName = "texture"; + const char* offset = ""; + const char* depthCmpCoordType = ""; + const char* gradSwizzle = ""; + + uint32_t ui32NumOffsets = 0; + + const RESOURCE_DIMENSION eResDim = psContext->psShader->aeResourceDims[psInst->asOperands[2].ui32RegisterNumber]; + + const int iHaveOverloadedTexFuncs = HaveOverloadedTextureFuncs(psContext->psShader->eTargetLanguage); + + ASSERT(psInst->asOperands[2].ui32RegisterNumber < MAX_TEXTURES); + + if(psInst->bAddressOffset) + { + offset = "Offset"; + } + + switch(eResDim) + { + case RESOURCE_DIMENSION_TEXTURE1D: + { + depthCmpCoordType = "vec2"; + gradSwizzle = ".x"; + ui32NumOffsets = 1; + if(!iHaveOverloadedTexFuncs) + { + funcName = "texture1D"; + if(ui32Flags & TEXSMP_FLAG_DEPTHCOMPARE) + { + funcName = "shadow1D"; + } + } + break; + } + case RESOURCE_DIMENSION_TEXTURE2D: + { + depthCmpCoordType = "vec3"; + gradSwizzle = ".xy"; + ui32NumOffsets = 2; + if(!iHaveOverloadedTexFuncs) + { + funcName = "texture2D"; + if(ui32Flags & TEXSMP_FLAG_DEPTHCOMPARE) + { + funcName = "shadow2D"; + } + } + break; + } + case RESOURCE_DIMENSION_TEXTURECUBE: + { + depthCmpCoordType = "vec3"; + gradSwizzle = ".xyz"; + ui32NumOffsets = 3; + if(!iHaveOverloadedTexFuncs) + { + funcName = "textureCube"; + } + break; + } + case RESOURCE_DIMENSION_TEXTURE3D: + { + depthCmpCoordType = "vec4"; + gradSwizzle = ".xyz"; + ui32NumOffsets = 3; + if(!iHaveOverloadedTexFuncs) + { + funcName = "texture3D"; + } + break; + } + case RESOURCE_DIMENSION_TEXTURE1DARRAY: + { + depthCmpCoordType = "vec3"; + gradSwizzle = ".x"; + ui32NumOffsets = 1; + break; + } + case RESOURCE_DIMENSION_TEXTURE2DARRAY: + { + depthCmpCoordType = "vec4"; + gradSwizzle = ".xy"; + ui32NumOffsets = 2; + break; + } + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: + { + gradSwizzle = ".xyz"; + ui32NumOffsets = 3; + if(ui32Flags & TEXSMP_FLAG_DEPTHCOMPARE) + { + //Special. Reference is a separate argument. + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + if(ui32Flags & (TEXSMP_FLAG_LOD|TEXSMP_FLAG_FIRSTLOD)) + { + bcatcstr(glsl, "= (vec4(textureLod("); + } + else + { + bcatcstr(glsl, "= (vec4(texture("); + } + TextureName(psContext, psInst->asOperands[2].ui32RegisterNumber, 1); + bcatcstr(glsl, ","); + TranslateTexCoord(psContext, eResDim, &psInst->asOperands[1]); + bcatcstr(glsl, ","); + //.z = reference. + TranslateOperand(psContext, &psInst->asOperands[4], TO_FLAG_NONE); + + if(ui32Flags & TEXSMP_FLAG_FIRSTLOD) + { + bcatcstr(glsl, ", 0"); + } + + bcatcstr(glsl, "))"); + // iWriteMaskEnabled is forced off during DecodeOperand because swizzle on sampler uniforms + // does not make sense. But need to re-enable to correctly swizzle this particular instruction. + psInst->asOperands[2].iWriteMaskEnabled = 1; + TranslateOperandSwizzle(psContext, &psInst->asOperands[2]); + bcatcstr(glsl, ")"); + + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + return; + } + + break; + } + default: + { + ASSERT(0); + break; + } + } + + if(ui32Flags & TEXSMP_FLAG_DEPTHCOMPARE) + { + //For non-cubeMap Arrays the reference value comes from the + //texture coord vector in GLSL. For cubmap arrays there is a + //separate parameter. + //It is always separate paramter in HLSL. + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + + if(ui32Flags & (TEXSMP_FLAG_LOD|TEXSMP_FLAG_FIRSTLOD)) + { + bformata(glsl, " =(vec4(%sLod%s(", funcName, offset); + } + else + { + bformata(glsl, " =(vec4(%s%s(", funcName, offset); + } + TextureName(psContext, psInst->asOperands[2].ui32RegisterNumber, 1); + bformata(glsl, ", %s(", depthCmpCoordType); + TranslateTexCoord(psContext, eResDim, &psInst->asOperands[1]); + bcatcstr(glsl, ","); + //.z = reference. + TranslateOperand(psContext, &psInst->asOperands[4], TO_FLAG_NONE); + bcatcstr(glsl, ")"); + + if(ui32Flags & TEXSMP_FLAG_FIRSTLOD) + { + bcatcstr(glsl, ", 0"); + } + + bcatcstr(glsl, "))"); + } + else + { + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + if(ui32Flags & (TEXSMP_FLAG_LOD|TEXSMP_FLAG_FIRSTLOD)) + { + bformata(glsl, " = (%sLod%s(", funcName, offset); + } + else + if(ui32Flags & TEXSMP_FLAGS_GRAD) + { + bformata(glsl, " = (%sGrad%s(", funcName, offset); + } + else + { + bformata(glsl, " = (%s%s(", funcName, offset); + } + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE);//resource + bcatcstr(glsl, ", "); + TranslateTexCoord(psContext, eResDim, &psInst->asOperands[1]); + + if(ui32Flags & (TEXSMP_FLAG_LOD)) + { + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[4], TO_FLAG_NONE); + if(psContext->psShader->ui32MajorVersion < 4) + { + bcatcstr(glsl, ".w"); + } + } + else + if(ui32Flags & TEXSMP_FLAG_FIRSTLOD) + { + bcatcstr(glsl, ", 0"); + } + else + if(ui32Flags & TEXSMP_FLAGS_GRAD) + { + bcatcstr(glsl, ", vec4("); + TranslateOperand(psContext, &psInst->asOperands[4], TO_FLAG_NONE);//dx + bcatcstr(glsl, ")"); + bcatcstr(glsl, gradSwizzle); + bcatcstr(glsl, ", vec4("); + TranslateOperand(psContext, &psInst->asOperands[5], TO_FLAG_NONE);//dy + bcatcstr(glsl, ")"); + bcatcstr(glsl, gradSwizzle); + } + + if(psInst->bAddressOffset) + { + if(ui32NumOffsets == 1) + { + bformata(glsl, ", %d", + psInst->iUAddrOffset); + } + else + if(ui32NumOffsets == 2) + { + bformata(glsl, ", ivec2(%d, %d)", + psInst->iUAddrOffset, + psInst->iVAddrOffset); + } + else + if(ui32NumOffsets == 3) + { + bformata(glsl, ", ivec3(%d, %d, %d)", + psInst->iUAddrOffset, + psInst->iVAddrOffset, + psInst->iWAddrOffset); + } + } + + if(ui32Flags & (TEXSMP_FLAG_BIAS)) + { + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[4], TO_FLAG_NONE); + } + + bcatcstr(glsl, ")"); + } + + // iWriteMaskEnabled is forced off during DecodeOperand because swizzle on sampler uniforms + // does not make sense. But need to re-enable to correctly swizzle this particular instruction. + psInst->asOperands[2].iWriteMaskEnabled = 1; + TranslateOperandSwizzle(psContext, &psInst->asOperands[2]); + bcatcstr(glsl, ")"); + + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); +} + +static ShaderVarType* LookupStructuredVar(HLSLCrossCompilerContext* psContext, + Operand* psResource, + Operand* psByteOffset, + uint32_t ui32Component) +{ + ConstantBuffer* psCBuf = NULL; + ShaderVarType* psVarType = NULL; + uint32_t aui32Swizzle[4] = {OPERAND_4_COMPONENT_X}; + int byteOffset = ((int*)psByteOffset->afImmediates)[0] + 4*ui32Component; + int vec4Offset = 0; + int32_t index = -1; + int32_t rebase = -1; + int found; + //TODO: multi-component stores and vector writes need testing. + + //aui32Swizzle[0] = psInst->asOperands[0].aui32Swizzle[component]; + + switch(byteOffset % 16) + { + case 0: + aui32Swizzle[0] = 0; + break; + case 4: + aui32Swizzle[0] = 1; + break; + case 8: + aui32Swizzle[0] = 2; + break; + case 12: + aui32Swizzle[0] = 3; + break; + } + + switch(psResource->eType) + { + case OPERAND_TYPE_RESOURCE: + GetConstantBufferFromBindingPoint(RGROUP_TEXTURE, psResource->ui32RegisterNumber, &psContext->psShader->sInfo, &psCBuf); + break; + case OPERAND_TYPE_UNORDERED_ACCESS_VIEW: + GetConstantBufferFromBindingPoint(RGROUP_UAV, psResource->ui32RegisterNumber, &psContext->psShader->sInfo, &psCBuf); + break; + case OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY: + { + //dcl_tgsm_structured defines the amount of memory and a stride. + ASSERT(psResource->ui32RegisterNumber < MAX_GROUPSHARED); + return &psContext->psShader->sGroupSharedVarType[psResource->ui32RegisterNumber]; + } + default: + ASSERT(0); + break; + } + + found = GetShaderVarFromOffset(vec4Offset, aui32Swizzle, psCBuf, &psVarType, &index, &rebase); + ASSERT(found); + + return psVarType; +} + + +static void TranslateShaderStorageStore(HLSLCrossCompilerContext* psContext, Instruction* psInst) +{ + bstring glsl = *psContext->currentGLSLString; + ShaderVarType* psVarType = NULL; + uint32_t ui32DataTypeFlag = TO_FLAG_INTEGER; + int component; + int srcComponent = 0; + + Operand* psDest = 0; + Operand* psDestAddr = 0; + Operand* psDestByteOff = 0; + Operand* psSrc = 0; + int structured = 0; + int groupshared = 0; + + switch(psInst->eOpcode) + { + case OPCODE_STORE_STRUCTURED: + psDest = &psInst->asOperands[0]; + psDestAddr = &psInst->asOperands[1]; + psDestByteOff = &psInst->asOperands[2]; + psSrc = &psInst->asOperands[3]; + structured = 1; + + break; + case OPCODE_STORE_RAW: + psDest = &psInst->asOperands[0]; + psDestByteOff = &psInst->asOperands[1]; + psSrc = &psInst->asOperands[2]; + break; + } + + for(component=0; component < 4; component++) + { + const char* swizzleString [] = { ".x", ".y", ".z", ".w" }; + ASSERT(psInst->asOperands[0].eSelMode == OPERAND_4_COMPONENT_MASK_MODE); + if(psInst->asOperands[0].ui32CompMask & (1<eType != OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY) + { + psVarType = LookupStructuredVar(psContext, psDest, psDestByteOff, component); + } + + AddIndentation(psContext); + + if(structured && psDest->eType == OPERAND_TYPE_RESOURCE) + { + bformata(glsl, "StructuredRes%d", psDest->ui32RegisterNumber); + } + else + { + TranslateOperand(psContext, psDest, TO_FLAG_DESTINATION|TO_FLAG_NAME_ONLY); + } + bformata(glsl, "["); + if(structured) //Dest address and dest byte offset + { + if(psDest->eType == OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY) + { + TranslateOperand(psContext, psDestAddr, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + bformata(glsl, "].value["); + TranslateOperand(psContext, psDestByteOff, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + bformata(glsl, "/4 ");//bytes to floats + } + else + { + TranslateOperand(psContext, psDestAddr, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + } + } + else + { + TranslateOperand(psContext, psDestByteOff, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + } + + //RAW: change component using index offset + if(!structured || (psDest->eType == OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY)) + { + bformata(glsl, " + %d", component); + } + + bformata(glsl, "]"); + + if(structured && psDest->eType != OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY) + { + if(strcmp(psVarType->Name, "$Element") != 0) + { + bformata(glsl, ".%s", psVarType->Name); + } + } + + bformata(glsl, " = "); + + if(structured) + { + uint32_t flags = TO_FLAG_NONE; + if(psVarType) + { + if(psVarType->Type == SVT_INT) + { + flags |= TO_FLAG_INTEGER; + } + else if(psVarType->Type == SVT_UINT) + { + flags |= TO_FLAG_UNSIGNED_INTEGER; + } + } + TranslateOperand(psContext, psSrc, flags); + } + else + { + //Dest type is currently always a uint array. + switch(eSrcDataType) + { + case SVT_FLOAT: + bcatcstr(glsl, "floatBitsToUint("); + TranslateOperand(psContext, psSrc, TO_FLAG_NONE); + bcatcstr(glsl, ")"); + break; + default: + TranslateOperand(psContext, psSrc, TO_FLAG_NONE); + break; + } + } + + if(GetNumSwizzleElements(psSrc) > 1) + bformata(glsl, swizzleString[srcComponent++]); + + //Double takes an extra slot. + if(psVarType && psVarType->Type == SVT_DOUBLE) + { + component++; + } + + bformata(glsl, ";\n"); + } + } +} +static void TranslateShaderStorageLoad(HLSLCrossCompilerContext* psContext, Instruction* psInst) +{ + bstring glsl = *psContext->currentGLSLString; + ShaderVarType* psVarType = NULL; + uint32_t aui32Swizzle[4] = {OPERAND_4_COMPONENT_X}; + uint32_t ui32DataTypeFlag = TO_FLAG_INTEGER; + int component; + int destComponent = 0; + + Operand* psDest = 0; + Operand* psSrcAddr = 0; + Operand* psSrcByteOff = 0; + Operand* psSrc = 0; + int structured = 0; + + switch(psInst->eOpcode) + { + case OPCODE_LD_STRUCTURED: + psDest = &psInst->asOperands[0]; + psSrcAddr = &psInst->asOperands[1]; + psSrcByteOff = &psInst->asOperands[2]; + psSrc = &psInst->asOperands[3]; + structured = 1; + break; + case OPCODE_LD_RAW: + psDest = &psInst->asOperands[0]; + psSrcByteOff = &psInst->asOperands[1]; + psSrc = &psInst->asOperands[2]; + break; + } + + //(int)GetNumSwizzleElements(&psInst->asOperands[0]) + for(component=0; component < 4; component++) + { + const char* swizzleString [] = { ".x", ".y", ".z", ".w" }; + ASSERT(psDest->eSelMode == OPERAND_4_COMPONENT_MASK_MODE); + if(psDest->ui32CompMask & (1<eType != OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY) + { + psVarType = LookupStructuredVar(psContext, psSrc, psSrcByteOff, psSrc->aui32Swizzle[component]); + } + + AddIndentation(psContext); + + aui32Swizzle[0] = psSrc->aui32Swizzle[component]; + + TranslateOperand(psContext, psDest, TO_FLAG_DESTINATION); + if(GetNumSwizzleElements(psDest) > 1) + bformata(glsl, swizzleString[destComponent++]); + + if(psSrc->eType == OPERAND_TYPE_RESOURCE) + { + if(structured) + bformata(glsl, " = StructuredRes%d[", psSrc->ui32RegisterNumber); + else + bformata(glsl, " = RawRes%d[", psSrc->ui32RegisterNumber); + } + else + { + bformata(glsl, " = "); + TranslateOperand(psContext, psSrc, TO_FLAG_NAME_ONLY); + bformata(glsl, "["); + } + + if(structured) //src address and src byte offset + { + if(psSrc->eType == OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY) + { + TranslateOperand(psContext, psSrcAddr, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + bformata(glsl, "].value["); + TranslateOperand(psContext, psSrcByteOff, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + bformata(glsl, "/4 ");//bytes to floats + } + else + { + TranslateOperand(psContext, psSrcAddr, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + } + } + else + { + TranslateOperand(psContext, psSrcByteOff, TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER); + } + + //RAW: change component using index offset + if(!structured || (psSrc->eType == OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY)) + { + bformata(glsl, " + %d", psSrc->aui32Swizzle[component]); + } + + bformata(glsl, "]"); + if(structured && psSrc->eType != OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY) + { + if(strcmp(psVarType->Name, "$Element") != 0) + { + bformata(glsl, ".%s", psVarType->Name); + } + + if( psVarType->Type == SVT_DOUBLE) + { + //Double takes an extra slot. + component++; + } + } + + bformata(glsl, ";\n"); + } + } +} + +void TranslateAtomicMemOp(HLSLCrossCompilerContext* psContext, Instruction* psInst) +{ + bstring glsl = *psContext->currentGLSLString; + ShaderVarType* psVarType = NULL; + uint32_t ui32DataTypeFlag = TO_FLAG_INTEGER; + const char* func = ""; + Operand* dest = 0; + Operand* previousValue = 0; + Operand* destAddr = 0; + Operand* src = 0; + Operand* compare = 0; + + switch(psInst->eOpcode) + { + case OPCODE_IMM_ATOMIC_IADD: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_IADD\n"); +#endif + func = "atomicAdd"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_IADD: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_IADD\n"); +#endif + func = "atomicAdd"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + case OPCODE_IMM_ATOMIC_AND: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_AND\n"); +#endif + func = "atomicAnd"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_AND: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_AND\n"); +#endif + func = "atomicAnd"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + case OPCODE_IMM_ATOMIC_OR: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_OR\n"); +#endif + func = "atomicOr"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_OR: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_OR\n"); +#endif + func = "atomicOr"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + case OPCODE_IMM_ATOMIC_XOR: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_XOR\n"); +#endif + func = "atomicXor"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_XOR: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_XOR\n"); +#endif + func = "atomicXor"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + + case OPCODE_IMM_ATOMIC_EXCH: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_EXCH\n"); +#endif + func = "atomicExchange"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_IMM_ATOMIC_CMP_EXCH: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_CMP_EXC\n"); +#endif + func = "atomicCompSwap"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + compare = &psInst->asOperands[3]; + src = &psInst->asOperands[4]; + break; + } + case OPCODE_ATOMIC_CMP_STORE: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_CMP_STORE\n"); +#endif + func = "atomicCompSwap"; + previousValue = 0; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + compare = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_IMM_ATOMIC_UMIN: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_UMIN\n"); +#endif + func = "atomicMin"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_UMIN: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_UMIN\n"); +#endif + func = "atomicMin"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + case OPCODE_IMM_ATOMIC_IMIN: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_IMIN\n"); +#endif + func = "atomicMin"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_IMIN: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_IMIN\n"); +#endif + func = "atomicMin"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + case OPCODE_IMM_ATOMIC_UMAX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_UMAX\n"); +#endif + func = "atomicMax"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_UMAX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_UMAX\n"); +#endif + func = "atomicMax"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + case OPCODE_IMM_ATOMIC_IMAX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_IMAX\n"); +#endif + func = "atomicMax"; + previousValue = &psInst->asOperands[0]; + dest = &psInst->asOperands[1]; + destAddr = &psInst->asOperands[2]; + src = &psInst->asOperands[3]; + break; + } + case OPCODE_ATOMIC_IMAX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ATOMIC_IMAX\n"); +#endif + func = "atomicMax"; + dest = &psInst->asOperands[0]; + destAddr = &psInst->asOperands[1]; + src = &psInst->asOperands[2]; + break; + } + } + + AddIndentation(psContext); + + psVarType = LookupStructuredVar(psContext, dest, destAddr, 0); + + if(previousValue) + { + TranslateOperand(psContext, previousValue, TO_FLAG_DESTINATION); + bcatcstr(glsl, " = "); + } + + bcatcstr(glsl, func); + bformata(glsl, "(UAV%d[0]", dest->ui32RegisterNumber); + if(strcmp(psVarType->Name, "$Element") != 0) + { + bformata(glsl, ".%s",psVarType->Name); + } + + if(psVarType->Type == SVT_UINT) + { + ui32DataTypeFlag = TO_FLAG_UNSIGNED_INTEGER; + } + bcatcstr(glsl, ", "); + + if(compare) + { + TranslateOperand(psContext, compare, ui32DataTypeFlag); + bcatcstr(glsl, ", "); + } + + TranslateOperand(psContext, src, ui32DataTypeFlag); + bcatcstr(glsl, ");\n"); +} + +static void TranslateConditional(HLSLCrossCompilerContext* psContext, + Instruction* psInst, + bstring glsl) +{ + const char* statement = ""; + if(psInst->eOpcode == OPCODE_BREAKC) + { + statement = "break"; + } + else if(psInst->eOpcode == OPCODE_CONTINUEC) + { + statement = "continue"; + } + else if(psInst->eOpcode == OPCODE_RETC) + { + statement = "return"; + } + + if(psContext->psShader->ui32MajorVersion < 4) + { + bcatcstr(glsl, "if("); + + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + switch(psInst->eDX9TestType) + { + case D3DSPC_GT: + { + bcatcstr(glsl, " > "); + break; + } + case D3DSPC_EQ: + { + bcatcstr(glsl, " == "); + break; + } + case D3DSPC_GE: + { + bcatcstr(glsl, " >= "); + break; + } + case D3DSPC_LT: + { + bcatcstr(glsl, " < "); + break; + } + case D3DSPC_NE: + { + bcatcstr(glsl, " != "); + break; + } + case D3DSPC_LE: + { + bcatcstr(glsl, " <= "); + break; + } + case D3DSPC_BOOLEAN: + { + bcatcstr(glsl, " != 0"); + break; + } + default: + { + break; + } + } + + if(psInst->eDX9TestType != D3DSPC_BOOLEAN) + { + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + } + + if(psInst->eOpcode != OPCODE_IF) + { + bformata(glsl, "){ %s; }\n", statement); + } + else + { + bcatcstr(glsl, "){\n"); + } + } + else + { + if(psInst->eBooleanTestType == INSTRUCTION_TEST_ZERO) + { + bcatcstr(glsl, "if(("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + + if(psInst->eOpcode != OPCODE_IF) + { + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + bformata(glsl, ")==0u){%s;}\n", statement); + else + bformata(glsl, ")==0){%s;}\n", statement); + } + else + { + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + bcatcstr(glsl, ")==0u){\n"); + else + bcatcstr(glsl, ")==0){\n"); + } + } + else + { + ASSERT(psInst->eBooleanTestType == INSTRUCTION_TEST_NONZERO); + bcatcstr(glsl, "if(("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + + if(psInst->eOpcode != OPCODE_IF) + { + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + bformata(glsl, ")!=0u){%s;}\n", statement); + else + bformata(glsl, ")!=0){%s;}\n", statement); + } + else + { + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + bcatcstr(glsl, ")!=0u){\n"); + else + bcatcstr(glsl, ")!=0){\n"); + } + } + } +} + +void SetDataTypes(HLSLCrossCompilerContext* psContext, Instruction* psInst, const int32_t i32InstCount) +{ + int32_t i; + + SHADER_VARIABLE_TYPE aeTempVecType[MAX_TEMP_VEC4 * 4]; + SHADER_VARIABLE_TYPE eNewType; + + for(i=0; i < MAX_TEMP_VEC4 * 4; ++i) + { + aeTempVecType[i] = SVT_FLOAT; + } + + for(i=0; i < i32InstCount; ++i, psInst++) + { + int k = 0; + + if(psInst->ui32NumOperands == 0) + continue; + + //Preserve the current type on dest array index + if(psInst->asOperands[0].eType == OPERAND_TYPE_INDEXABLE_TEMP) + { + Operand* psSubOperand = psInst->asOperands[0].psSubOperand[1]; + if(psSubOperand != 0) + { + const uint32_t ui32RegIndex = psSubOperand->ui32RegisterNumber*4; + ASSERT(psSubOperand->eType == OPERAND_TYPE_TEMP); + + if(psSubOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + psSubOperand->aeDataType[psSubOperand->aui32Swizzle[0]] = aeTempVecType[ui32RegIndex+psSubOperand->aui32Swizzle[0]]; + } + else if(psSubOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psSubOperand->ui32Swizzle == (NO_SWIZZLE)) + { + psSubOperand->aeDataType[0] = aeTempVecType[ui32RegIndex]; + psSubOperand->aeDataType[1] = aeTempVecType[ui32RegIndex]; + psSubOperand->aeDataType[2] = aeTempVecType[ui32RegIndex]; + psSubOperand->aeDataType[3] = aeTempVecType[ui32RegIndex]; + } + else + { + psSubOperand->aeDataType[psSubOperand->aui32Swizzle[0]] = aeTempVecType[ui32RegIndex+psSubOperand->aui32Swizzle[0]]; + } + } + else if(psSubOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + int c = 0; + uint32_t ui32CompMask = psSubOperand->ui32CompMask; + if(!psSubOperand->ui32CompMask) + { + ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL; + } + + for(;c<4;++c) + { + if(ui32CompMask & (1<aeDataType[c] = aeTempVecType[ui32RegIndex+c]; + } + } + } + } + } + + //Preserve the current type on sources. + for(k = psInst->ui32NumOperands-1; k >= (int)psInst->ui32FirstSrc; --k) + { + int32_t subOperand; + Operand* psOperand = &psInst->asOperands[k]; + + if(psOperand->eType == OPERAND_TYPE_TEMP) + { + const uint32_t ui32RegIndex = psOperand->ui32RegisterNumber*4; + + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + psOperand->aeDataType[psOperand->aui32Swizzle[0]] = aeTempVecType[ui32RegIndex+psOperand->aui32Swizzle[0]]; + } + else if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle == (NO_SWIZZLE)) + { + psOperand->aeDataType[0] = aeTempVecType[ui32RegIndex]; + psOperand->aeDataType[1] = aeTempVecType[ui32RegIndex]; + psOperand->aeDataType[2] = aeTempVecType[ui32RegIndex]; + psOperand->aeDataType[3] = aeTempVecType[ui32RegIndex]; + } + else + { + psOperand->aeDataType[psOperand->aui32Swizzle[0]] = aeTempVecType[ui32RegIndex+psOperand->aui32Swizzle[0]]; + } + } + else if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + int c = 0; + uint32_t ui32CompMask = psOperand->ui32CompMask; + if(!psOperand->ui32CompMask) + { + ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL; + } + + for(;c<4;++c) + { + if(ui32CompMask & (1<aeDataType[c] = aeTempVecType[ui32RegIndex+c]; + } + } + } + } + + for(subOperand=0; subOperand < MAX_SUB_OPERANDS; subOperand++) + { + if(psOperand->psSubOperand[subOperand] != 0) + { + Operand* psSubOperand = psOperand->psSubOperand[subOperand]; + if(psSubOperand->eType == OPERAND_TYPE_TEMP) + { + const uint32_t ui32RegIndex = psSubOperand->ui32RegisterNumber*4; + + if(psSubOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + psSubOperand->aeDataType[psSubOperand->aui32Swizzle[0]] = aeTempVecType[ui32RegIndex+psSubOperand->aui32Swizzle[0]]; + } + else if(psSubOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psSubOperand->ui32Swizzle == (NO_SWIZZLE)) + { + psSubOperand->aeDataType[0] = aeTempVecType[ui32RegIndex]; + psSubOperand->aeDataType[1] = aeTempVecType[ui32RegIndex]; + psSubOperand->aeDataType[2] = aeTempVecType[ui32RegIndex]; + psSubOperand->aeDataType[3] = aeTempVecType[ui32RegIndex]; + } + else + { + psSubOperand->aeDataType[psSubOperand->aui32Swizzle[0]] = aeTempVecType[ui32RegIndex+psSubOperand->aui32Swizzle[0]]; + } + } + else if(psSubOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + int c = 0; + uint32_t ui32CompMask = psSubOperand->ui32CompMask; + if(!psSubOperand->ui32CompMask) + { + ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL; + } + + + for(;c<4;++c) + { + if(ui32CompMask & (1<aeDataType[c] = aeTempVecType[ui32RegIndex+c]; + } + } + } + } + } + } + } + + + switch(psInst->eOpcode) + { + case OPCODE_RESINFO: + { + if(psInst->eResInfoReturnType == RESINFO_INSTRUCTION_RETURN_UINT) + { + eNewType = SVT_INT; + } + else + { + eNewType = SVT_FLOAT; + } + break; + } + case OPCODE_AND: + case OPCODE_OR: + case OPCODE_XOR: + case OPCODE_NOT: + { + eNewType = SVT_UINT; + break; + } + case OPCODE_IADD: + case OPCODE_IMAD: + case OPCODE_IMAX: + case OPCODE_IMIN: + case OPCODE_IMUL: + case OPCODE_INEG: + case OPCODE_ISHL: + case OPCODE_ISHR: + { + uint32_t k; + eNewType = SVT_INT; + + //If the rhs evaluates to unsigned then that is the dest type picked. + for(k=psInst->ui32FirstSrc; k < psInst->ui32NumOperands; ++k) + { + if(GetOperandDataType(psContext, &psInst->asOperands[k]) == SVT_UINT) + { + eNewType = SVT_UINT; + break; + } + } + + break; + } + case OPCODE_IMM_ATOMIC_AND: + case OPCODE_IMM_ATOMIC_IADD: + case OPCODE_IMM_ATOMIC_IMAX: + case OPCODE_IMM_ATOMIC_IMIN: + case OPCODE_IMM_ATOMIC_UMAX: + case OPCODE_IMM_ATOMIC_UMIN: + case OPCODE_IMM_ATOMIC_OR: + case OPCODE_IMM_ATOMIC_XOR: + case OPCODE_IMM_ATOMIC_EXCH: + case OPCODE_IMM_ATOMIC_CMP_EXCH: + { + Operand* dest = &psInst->asOperands[1]; + Operand* destAddr = &psInst->asOperands[2]; + ShaderVarType* type = LookupStructuredVar(psContext, dest, destAddr, 0); + eNewType = type->Type; + break; + } + + case OPCODE_IEQ: + case OPCODE_IGE: + case OPCODE_ILT: + case OPCODE_INE: + case OPCODE_EQ: + case OPCODE_GE: + case OPCODE_LT: + case OPCODE_NE: + case OPCODE_UDIV: + case OPCODE_ULT: + case OPCODE_UGE: + case OPCODE_UMUL: + case OPCODE_UMAD: + case OPCODE_UMAX: + case OPCODE_UMIN: + case OPCODE_USHR: + case OPCODE_IMM_ATOMIC_ALLOC: + case OPCODE_IMM_ATOMIC_CONSUME: + { + if(psContext->psShader->ui32MajorVersion < 4) + { + //SLT and SGE are translated to LT and GE respectively. + //But SLT and SGE have a floating point 1.0f or 0.0f result + //instead of setting all bits on or all bits off. + eNewType = SVT_FLOAT; + } + else + { + eNewType = SVT_UINT; + } + break; + } + + case OPCODE_LD_UAV_TYPED: + { + ResourceBinding* psRes = NULL; + GetResourceFromBindingPoint(RGROUP_UAV, psInst->asOperands[2].ui32RegisterNumber, &psContext->psShader->sInfo, &psRes); + switch(psRes->ui32ReturnType) + { + case RETURN_TYPE_SINT: + eNewType = SVT_INT; + break; + case RETURN_TYPE_UINT: + eNewType = SVT_UINT; + break; + case RETURN_TYPE_FLOAT: + eNewType = SVT_FLOAT; + break; + default: + ASSERT(0); + break; + } + break; + } + + case OPCODE_MOV: + { + //Inherit the type of the source operand + const Operand* psOperand = &psInst->asOperands[0]; + if(psOperand->eType == OPERAND_TYPE_TEMP) + { + eNewType = GetOperandDataType(psContext, &psInst->asOperands[1]); + } + break; + } + case OPCODE_MOVC: + { + //Inherit the type of the source operand + const Operand* psOperand = &psInst->asOperands[0]; + if(psOperand->eType == OPERAND_TYPE_TEMP) + { + eNewType = GetOperandDataType(psContext, &psInst->asOperands[2]); + //Check assumption that both the values which MOVC might pick have the same basic data type. + //ASSERT(GetOperandDataType(psContext, &psInst->asOperands[2]) == GetOperandDataType(psContext, &psInst->asOperands[3])); + } + break; + } + case OPCODE_FTOI: + { + ASSERT(GetOperandDataType(psContext, &psInst->asOperands[1]) == SVT_FLOAT); + eNewType = SVT_INT; + break; + } + case OPCODE_FTOU: + { + ASSERT(GetOperandDataType(psContext, &psInst->asOperands[1]) == SVT_FLOAT); + eNewType = SVT_UINT; + break; + } + + case OPCODE_UTOF: + case OPCODE_ITOF: + { + eNewType = SVT_FLOAT; + break; + } + case OPCODE_IF: + case OPCODE_SWITCH: + case OPCODE_BREAKC: + { + const Operand* psOperand = &psInst->asOperands[0]; + if(psOperand->eType == OPERAND_TYPE_TEMP) + { + const uint32_t ui32RegIndex = psOperand->ui32RegisterNumber*4; + + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + eNewType = aeTempVecType[ui32RegIndex+psOperand->aui32Swizzle[0]]; + } + else if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle == (NO_SWIZZLE)) + { + eNewType = aeTempVecType[ui32RegIndex]; + } + else + { + eNewType = aeTempVecType[ui32RegIndex+psOperand->aui32Swizzle[0]]; + } + } + else if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + uint32_t ui32CompMask = psOperand->ui32CompMask; + if(!psOperand->ui32CompMask) + { + ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL; + } + for(;k<4;++k) + { + if(ui32CompMask & (1<psShader->eTargetLanguage)==0) + { + //Fallback to signed int if unsigned int is not supported. + eNewType = SVT_INT; + } + + //Process the destination last in order to handle instructions + //where the destination register is also used as a source. + for(k = 0; k < (int)psInst->ui32FirstSrc; ++k) + { + Operand* psOperand = &psInst->asOperands[k]; + if(psOperand->eType == OPERAND_TYPE_TEMP) + { + const uint32_t ui32RegIndex = psOperand->ui32RegisterNumber*4; + + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + aeTempVecType[ui32RegIndex+psOperand->aui32Swizzle[0]] = eNewType; + psOperand->aeDataType[psOperand->aui32Swizzle[0]] = eNewType; + } + else if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle == (NO_SWIZZLE)) + { + aeTempVecType[ui32RegIndex] = eNewType; + psOperand->aeDataType[0] = eNewType; + psOperand->aeDataType[1] = eNewType; + psOperand->aeDataType[2] = eNewType; + psOperand->aeDataType[3] = eNewType; + } + else + { + aeTempVecType[ui32RegIndex+psOperand->aui32Swizzle[0]] = eNewType; + psOperand->aeDataType[psOperand->aui32Swizzle[0]] = eNewType; + } + } + else if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + int c = 0; + uint32_t ui32CompMask = psOperand->ui32CompMask; + if(!psOperand->ui32CompMask) + { + ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL; + } + + for(;c<4;++c) + { + if(ui32CompMask & (1<aeDataType[c] = eNewType; + } + } + } + } + } + + } +} + +void TranslateInstruction(HLSLCrossCompilerContext* psContext, Instruction* psInst) +{ + bstring glsl = *psContext->currentGLSLString; + +#ifdef _DEBUG + AddIndentation(psContext); + bformata(glsl, "//Instruction %d\n", psInst->id); +#if 0 + if(psInst->id == 73) + { + ASSERT(1); //Set breakpoint here to debug an instruction from its ID. + } +#endif +#endif + + switch(psInst->eOpcode) + { + case OPCODE_FTOI: //Fall-through to MOV + case OPCODE_FTOU: //Fall-through to MOV + case OPCODE_MOV: + { + uint32_t srcCount = GetNumSwizzleElements(&psInst->asOperands[1]); + uint32_t dstCount = GetNumSwizzleElements(&psInst->asOperands[0]); + uint32_t ui32DstFlags = TO_FLAG_DESTINATION; + + if(psInst->eOpcode == OPCODE_FTOU) + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//FTOU\n"); +#endif + ui32DstFlags |= TO_FLAG_UNSIGNED_INTEGER; + + ASSERT(GetOperandDataType(psContext, &psInst->asOperands[1]) == SVT_FLOAT); + } + else if(psInst->eOpcode == OPCODE_FTOI) + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//FTOI\n"); +#endif + ui32DstFlags |= TO_FLAG_INTEGER; + + ASSERT(GetOperandDataType(psContext, &psInst->asOperands[1]) == SVT_FLOAT); + } + else + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//MOV\n"); +#endif + } + + AddIndentation(psContext); + + if(psInst->eOpcode == OPCODE_FTOU) + { + TranslateOperand(psContext, &psInst->asOperands[0], ui32DstFlags); + + if(srcCount == 1) + bcatcstr(glsl, " = uint("); + if(srcCount == 2) + bcatcstr(glsl, " = uivec2("); + if(srcCount == 3) + bcatcstr(glsl, " = uivec3("); + if(srcCount == 4) + bcatcstr(glsl, " = uivec4("); + + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + if(srcCount != dstCount) + { + bcatcstr(glsl, ")"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + } + else + { + bcatcstr(glsl, ");\n"); + } + } + else + if(psInst->eOpcode == OPCODE_FTOI) + { + TranslateOperand(psContext, &psInst->asOperands[0], ui32DstFlags); + + if(srcCount == 1) + bcatcstr(glsl, " = int("); + if(srcCount == 2) + bcatcstr(glsl, " = ivec2("); + if(srcCount == 3) + bcatcstr(glsl, " = ivec3("); + if(srcCount == 4) + bcatcstr(glsl, " = ivec4("); + + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + + if(srcCount != dstCount) + { + bcatcstr(glsl, ")"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + } + else + { + bcatcstr(glsl, ");\n"); + } + } + else + { + const SHADER_VARIABLE_TYPE eDestType = GetOperandDataType(psContext, &psInst->asOperands[0]); + const SHADER_VARIABLE_TYPE eSrcType = GetOperandDataType(psContext, &psInst->asOperands[1]); + + if(eDestType != eSrcType) + { + bcatcstr(glsl, "//WARNING: type mismatch on MOV. Could indicate incorrect data-type handling.\n"); + AddIndentation(psContext); + } + + TranslateOperand(psContext, &psInst->asOperands[0], ui32DstFlags); + + if(eDestType == SVT_UINT) + { + bcatcstr(glsl, " = uvec4("); + } + else if(eDestType == SVT_INT) + { + bcatcstr(glsl, " = ivec4("); + } + else + { + bcatcstr(glsl, " = vec4("); + } + + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, ")"); + //Mismatched element count or destination has any swizzle + if(srcCount != dstCount || (GetFirstOperandSwizzle(psContext, &psInst->asOperands[0]) != -1)) + { + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + } + else + { + AddSwizzleUsingElementCount(psContext, dstCount); + } + bcatcstr(glsl, ";\n"); + } + break; + } + case OPCODE_ITOF://signed to float + case OPCODE_UTOF://unsigned to float + { + const SHADER_VARIABLE_TYPE eDestType = GetOperandDataType(psContext, &psInst->asOperands[0]); + const SHADER_VARIABLE_TYPE eSrcType = GetOperandDataType(psContext, &psInst->asOperands[1]); + + if(eSrcType == SVT_FLOAT) + { + //With ld_uav_typed, the result is uint and then converted to the actual format. + //But we will set the dest of imageLoad as the actual format and igore the utof. + //Otherwise no suitable overload of imageLoad will be found. + //Example from tests\ps5\load_store: + //ld_uav_typed_indexable(texture3d)(float,float,float,float) r1.x, r0.xxxx, u5.xyzw + //utof r1.x, r1.x + bcatcstr(glsl, "//Warning. UTOF/ITOF on a src which is float. This is okay if ld_uav_typed last wrote to the src.\n"); + } + +#ifdef _DEBUG + AddIndentation(psContext); + if(psInst->eOpcode == OPCODE_ITOF) + { + bcatcstr(glsl, "//ITOF\n"); + } + else + { + bcatcstr(glsl, "//UTOF\n"); + } +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = vec4("); + TranslateOperand(psContext, &psInst->asOperands[1], (eSrcType == SVT_INT) ? TO_FLAG_INTEGER : TO_FLAG_UNSIGNED_INTEGER); + bcatcstr(glsl, ")"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_MAD: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//MAD\n"); +#endif + CallTernaryOp(psContext, "*", "+", psInst, 0, 1, 2, 3, TO_FLAG_NONE); + break; + } + case OPCODE_IMAD: + { + uint32_t ui32Flags = TO_FLAG_INTEGER; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMAD\n"); +#endif + + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + { + ui32Flags = TO_FLAG_UNSIGNED_INTEGER; + } + + CallTernaryOp(psContext, "*", "+", psInst, 0, 1, 2, 3, ui32Flags); + break; + } + case OPCODE_DADD: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DADD\n"); +#endif + CallBinaryOp(psContext, "+", psInst, 0, 1, 2, TO_FLAG_DOUBLE); + break; + } + case OPCODE_IADD: + { + uint32_t ui32Flags = TO_FLAG_INTEGER; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IADD\n"); +#endif + //Is this a signed or unsigned add? + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + { + ui32Flags = TO_FLAG_UNSIGNED_INTEGER; + } + CallBinaryOp(psContext, "+", psInst, 0, 1, 2, ui32Flags); + break; + } + case OPCODE_ADD: + { + +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ADD\n"); +#endif + CallBinaryOp(psContext, "+", psInst, 0, 1, 2, TO_FLAG_NONE); + break; + } + case OPCODE_OR: + { + /*Todo: vector version */ +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//OR\n"); +#endif + CallBinaryOp(psContext, "|", psInst, 0, 1, 2, TO_FLAG_INTEGER); + break; + } + case OPCODE_AND: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//AND\n"); +#endif + CallBinaryOp(psContext, "&", psInst, 0, 1, 2, TO_FLAG_INTEGER); + break; + } + case OPCODE_GE: + { + /* + dest = vec4(greaterThanEqual(vec4(srcA), vec4(srcB)); + Caveat: The result is a boolean but HLSL asm returns 0xFFFFFFFF/0x0 instead. + */ +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//GE\n"); +#endif + AddComparision(psContext, psInst, CMP_GE, TO_FLAG_NONE); + break; + } + case OPCODE_MUL: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//MUL\n"); +#endif + CallBinaryOp(psContext, "*", psInst, 0, 1, 2, TO_FLAG_NONE); + break; + } + case OPCODE_IMUL: + { + uint32_t ui32Flags = TO_FLAG_INTEGER; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMUL\n"); +#endif + if(GetOperandDataType(psContext, &psInst->asOperands[1]) == SVT_UINT) + { + ui32Flags = TO_FLAG_UNSIGNED_INTEGER; + } + + ASSERT(psInst->asOperands[0].eType == OPERAND_TYPE_NULL); + + CallBinaryOp(psContext, "*", psInst, 1, 2, 3, ui32Flags); + break; + } + case OPCODE_UDIV: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//UDIV\n"); +#endif + //destQuotient, destRemainder, src0, src1 + CallBinaryOp(psContext, "/", psInst, 0, 2, 3, TO_FLAG_UNSIGNED_INTEGER); + CallHelper2UInt(psContext, "mod", psInst, 1, 2, 3); + break; + } + case OPCODE_DIV: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DIV\n"); +#endif + CallBinaryOp(psContext, "/", psInst, 0, 1, 2, TO_FLAG_NONE); + break; + } + case OPCODE_SINCOS: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SINCOS\n"); +#endif + if(psInst->asOperands[0].eType != OPERAND_TYPE_NULL) + { + CallHelper1(psContext, "sin", psInst, 0, 2); + } + + if(psInst->asOperands[1].eType != OPERAND_TYPE_NULL) + { + CallHelper1(psContext, "cos", psInst, 1, 2); + } + break; + } + + case OPCODE_DP2: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DP2\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = vec4(dot(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, ").xy, ("); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ").xy))"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_DP3: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DP3\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = vec4(dot(("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, ").xyz, ("); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ").xyz))"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_DP4: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DP4\n"); +#endif + CallHelper2(psContext, "dot", psInst, 0, 1, 2); + break; + } + case OPCODE_INE: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//INE\n"); +#endif + AddComparision(psContext, psInst, CMP_NE, TO_FLAG_INTEGER); + break; + } + case OPCODE_NE: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//NE\n"); +#endif + AddComparision(psContext, psInst, CMP_NE, TO_FLAG_NONE); + break; + } + case OPCODE_IGE: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IGE\n"); +#endif + AddComparision(psContext, psInst, CMP_GE, TO_FLAG_INTEGER); + break; + } + case OPCODE_ILT: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ILT\n"); +#endif + AddComparision(psContext, psInst, CMP_LT, TO_FLAG_INTEGER); + break; + } + case OPCODE_LT: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LT\n"); +#endif + AddComparision(psContext, psInst, CMP_LT, TO_FLAG_NONE); + break; + } + case OPCODE_IEQ: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IEQ\n"); +#endif + AddComparision(psContext, psInst, CMP_EQ, TO_FLAG_INTEGER); + break; + } + case OPCODE_ULT: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ULT\n"); +#endif + AddComparision(psContext, psInst, CMP_LT, TO_FLAG_UNSIGNED_INTEGER); + break; + } + case OPCODE_UGE: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//UGE\n"); +#endif + AddComparision(psContext, psInst, CMP_GE, TO_FLAG_UNSIGNED_INTEGER); + break; + } + case OPCODE_MOVC: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//MOVC\n"); +#endif + AddMOVCBinaryOp(psContext,&psInst->asOperands[0],&psInst->asOperands[1],&psInst->asOperands[2],&psInst->asOperands[3]); + break; + } + case OPCODE_SWAPC: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SWAPC\n"); +#endif + AddMOVCBinaryOp(psContext,&psInst->asOperands[0],&psInst->asOperands[2],&psInst->asOperands[4],&psInst->asOperands[3]); + AddMOVCBinaryOp(psContext,&psInst->asOperands[1],&psInst->asOperands[2],&psInst->asOperands[3],&psInst->asOperands[4]); + break; + } + + case OPCODE_LOG: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LOG\n"); +#endif + CallHelper1(psContext, "log2", psInst, 0, 1); + break; + } + case OPCODE_RSQ: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//RSQ\n"); +#endif + CallHelper1(psContext, "inversesqrt", psInst, 0, 1); + break; + } + case OPCODE_EXP: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EXP\n"); +#endif + CallHelper1(psContext, "exp2", psInst, 0, 1); + break; + } + case OPCODE_SQRT: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SQRT\n"); +#endif + CallHelper1(psContext, "sqrt", psInst, 0, 1); + break; + } + case OPCODE_ROUND_PI: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ROUND_PI\n"); +#endif + CallHelper1(psContext, "ceil", psInst, 0, 1); + break; + } + case OPCODE_ROUND_NI: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ROUND_NI\n"); +#endif + CallHelper1(psContext, "floor", psInst, 0, 1); + break; + } + case OPCODE_ROUND_Z: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ROUND_Z\n"); +#endif + CallHelper1(psContext, "trunc", psInst, 0, 1); + break; + } + case OPCODE_ROUND_NE: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ROUND_NE\n"); +#endif + CallHelper1(psContext, "roundEven", psInst, 0, 1); + break; + } + case OPCODE_FRC: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//FRC\n"); +#endif + CallHelper1(psContext, "fract", psInst, 0, 1); + break; + } + case OPCODE_IMAX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMAX\n"); +#endif + CallHelper2Int(psContext, "max", psInst, 0, 1, 2); + break; + } + case OPCODE_MAX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//MAX\n"); +#endif + CallHelper2(psContext, "max", psInst, 0, 1, 2); + break; + } + case OPCODE_IMIN: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMIN\n"); +#endif + CallHelper2Int(psContext, "min", psInst, 0, 1, 2); + break; + } + case OPCODE_MIN: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//MIN\n"); +#endif + CallHelper2(psContext, "min", psInst, 0, 1, 2); + break; + } + case OPCODE_GATHER4: + { + //dest, coords, tex, sampler + const RESOURCE_DIMENSION eResDim = psContext->psShader->aeResourceDims[psInst->asOperands[2].ui32RegisterNumber]; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//GATHER4\n"); +#endif +//gather4 r7.xyzw, r3.xyxx, t3.xyzw, s0.x + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = (textureGather("); + + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", "); + TranslateTexCoord(psContext, eResDim, &psInst->asOperands[1]); + bcatcstr(glsl, ")"); + // iWriteMaskEnabled is forced off during DecodeOperand because swizzle on sampler uniforms + // does not make sense. But need to re-enable to correctly swizzle this particular instruction. + psInst->asOperands[2].iWriteMaskEnabled = 1; + TranslateOperandSwizzle(psContext, &psInst->asOperands[2]); + bcatcstr(glsl, ")"); + + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_GATHER4_PO_C: + { + //dest, coords, offset, tex, sampler, srcReferenceValue + const RESOURCE_DIMENSION eResDim = psContext->psShader->aeResourceDims[psInst->asOperands[3].ui32RegisterNumber]; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//GATHER4_PO_C\n"); +#endif + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = (textureGatherOffset("); + + TextureName(psContext, psInst->asOperands[3].ui32RegisterNumber, 1); + + bcatcstr(glsl, ", "); + + TranslateTexCoord(psContext, eResDim, &psInst->asOperands[1]); + + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[5], TO_FLAG_NONE); + + bcatcstr(glsl, ", ivec2("); + //ivec2 offset + psInst->asOperands[2].aui32Swizzle[2] = 0xFFFFFFFF; + psInst->asOperands[2].aui32Swizzle[3] = 0xFFFFFFFF; + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, "))"); + // iWriteMaskEnabled is forced off during DecodeOperand because swizzle on sampler uniforms + // does not make sense. But need to re-enable to correctly swizzle this particular instruction. + psInst->asOperands[2].iWriteMaskEnabled = 1; + TranslateOperandSwizzle(psContext, &psInst->asOperands[3]); + bcatcstr(glsl, ")"); + + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_GATHER4_PO: + { + //dest, coords, offset, tex, sampler +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//GATHER4_PO\n"); +#endif + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = (textureGatherOffset("); + + TextureName(psContext, psInst->asOperands[3].ui32RegisterNumber, 0); + + bcatcstr(glsl, ", "); + //Texture coord cannot be vec4 + //Determining if it is a vec3 for vec2 yet to be done. + psInst->asOperands[1].aui32Swizzle[2] = 0xFFFFFFFF; + psInst->asOperands[1].aui32Swizzle[3] = 0xFFFFFFFF; + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + + bcatcstr(glsl, ", ivec2("); + //ivec2 offset + psInst->asOperands[2].aui32Swizzle[2] = 0xFFFFFFFF; + psInst->asOperands[2].aui32Swizzle[3] = 0xFFFFFFFF; + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, "))"); + // iWriteMaskEnabled is forced off during DecodeOperand because swizzle on sampler uniforms + // does not make sense. But need to re-enable to correctly swizzle this particular instruction. + psInst->asOperands[2].iWriteMaskEnabled = 1; + TranslateOperandSwizzle(psContext, &psInst->asOperands[3]); + bcatcstr(glsl, ")"); + + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_GATHER4_C: + { + //dest, coords, tex, sampler srcReferenceValue +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//GATHER4_C\n"); +#endif + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = (textureGather("); + + TextureName(psContext, psInst->asOperands[2].ui32RegisterNumber, 1); + + bcatcstr(glsl, ", "); + //Texture coord cannot be vec4 + //Determining if it is a vec3 for vec2 yet to be done. + psInst->asOperands[1].aui32Swizzle[2] = 0xFFFFFFFF; + psInst->asOperands[1].aui32Swizzle[3] = 0xFFFFFFFF; + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[4], TO_FLAG_NONE); + bcatcstr(glsl, ")"); + // iWriteMaskEnabled is forced off during DecodeOperand because swizzle on sampler uniforms + // does not make sense. But need to re-enable to correctly swizzle this particular instruction. + psInst->asOperands[2].iWriteMaskEnabled = 1; + TranslateOperandSwizzle(psContext, &psInst->asOperands[2]); + bcatcstr(glsl, ")"); + + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_SAMPLE: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SAMPLE\n"); +#endif + TranslateTextureSample(psContext, psInst, TEXSMP_FLAG_NONE); + break; + } + case OPCODE_SAMPLE_L: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SAMPLE_L\n"); +#endif + TranslateTextureSample(psContext, psInst, TEXSMP_FLAG_LOD); + break; + } + case OPCODE_SAMPLE_C: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SAMPLE_C\n"); +#endif + + TranslateTextureSample(psContext, psInst, TEXSMP_FLAG_DEPTHCOMPARE); + break; + } + case OPCODE_SAMPLE_C_LZ: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SAMPLE_C_LZ\n"); +#endif + + TranslateTextureSample(psContext, psInst, TEXSMP_FLAG_DEPTHCOMPARE | TEXSMP_FLAG_FIRSTLOD); + break; + } + case OPCODE_SAMPLE_D: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SAMPLE_D\n"); +#endif + + TranslateTextureSample(psContext, psInst, TEXSMP_FLAGS_GRAD); + break; + } + case OPCODE_SAMPLE_B: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SAMPLE_B\n"); +#endif + + TranslateTextureSample(psContext, psInst, TEXSMP_FLAG_BIAS); + break; + } + case OPCODE_RET: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//RET\n"); +#endif + if(psContext->havePostShaderCode[psContext->currentPhase]) + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- Post shader code ---\n"); +#endif + bconcat(glsl, psContext->postShaderCode[psContext->currentPhase]); +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- End post shader code ---\n"); +#endif + } + AddIndentation(psContext); + bcatcstr(glsl, "return;\n"); + break; + } + case OPCODE_INTERFACE_CALL: + { + const char* name; + ShaderVar* psVar; + uint32_t varFound; + + uint32_t funcPointer; + uint32_t funcTableIndex; + uint32_t funcTable; + uint32_t funcBodyIndex; + uint32_t funcBody; + uint32_t ui32NumBodiesPerTable; + +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//INTERFACE_CALL\n"); +#endif + + ASSERT(psInst->asOperands[0].eIndexRep[0] == OPERAND_INDEX_IMMEDIATE32); + + funcPointer = psInst->asOperands[0].aui32ArraySizes[0]; + funcTableIndex = psInst->asOperands[0].aui32ArraySizes[1]; + funcBodyIndex = psInst->ui32FuncIndexWithinInterface; + + ui32NumBodiesPerTable = psContext->psShader->funcPointer[funcPointer].ui32NumBodiesPerTable; + + funcTable = psContext->psShader->funcPointer[funcPointer].aui32FuncTables[funcTableIndex]; + + funcBody = psContext->psShader->funcTable[funcTable].aui32FuncBodies[funcBodyIndex]; + + varFound = GetInterfaceVarFromOffset(funcPointer, &psContext->psShader->sInfo, &psVar); + + ASSERT(varFound); + + name = &psVar->Name[0]; + + AddIndentation(psContext); + bcatcstr(glsl, name); + TranslateOperandIndexMAD(psContext, &psInst->asOperands[0], 1, ui32NumBodiesPerTable, funcBodyIndex); + //bformata(glsl, "[%d]", funcBodyIndex); + bcatcstr(glsl, "();\n"); + break; + } + case OPCODE_LABEL: + { + #ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LABEL\n"); +#endif + --psContext->indent; + AddIndentation(psContext); + bcatcstr(glsl, "}\n"); //Closing brace ends the previous function. + AddIndentation(psContext); + + bcatcstr(glsl, "subroutine(SubroutineType)\n"); + bcatcstr(glsl, "void "); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, "(){\n"); + ++psContext->indent; + break; + } + case OPCODE_COUNTBITS: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//COUNTBITS\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_INTEGER|TO_FLAG_DESTINATION); + bcatcstr(glsl, " = bitCount("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_FIRSTBIT_HI: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//FIRSTBIT_HI\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_UNSIGNED_INTEGER|TO_FLAG_DESTINATION); + bcatcstr(glsl, " = findMSB("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_UNSIGNED_INTEGER); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_FIRSTBIT_LO: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//FIRSTBIT_LO\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_UNSIGNED_INTEGER|TO_FLAG_DESTINATION); + bcatcstr(glsl, " = findLSB("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_UNSIGNED_INTEGER); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_FIRSTBIT_SHI: //signed high + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//FIRSTBIT_SHI\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_INTEGER|TO_FLAG_DESTINATION); + bcatcstr(glsl, " = findMSB("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_BFREV: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//BFREV\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_INTEGER|TO_FLAG_DESTINATION); + bcatcstr(glsl, " = bitfieldReverse("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_BFI: + { + uint32_t numelements_width = GetNumSwizzleElements(&psInst->asOperands[1]); + uint32_t numelements_offset = GetNumSwizzleElements(&psInst->asOperands[2]); + uint32_t numelements_dest = GetNumSwizzleElements(&psInst->asOperands[0]); + uint32_t numoverall_elements = min(min(numelements_width,numelements_offset),numelements_dest); + uint32_t i,j; + static const char* bfi_elementidx[] = { "x","y","z","w" }; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//BFI\n"); +#endif + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_INTEGER|TO_FLAG_DESTINATION); + bformata(glsl, " = ivec%d(",numoverall_elements); + for(i = 0; i < numoverall_elements; ++i) + { + bcatcstr(glsl,"bitfieldInsert("); + + for(j = 4; j >= 1; --j) + { + uint32_t opSwizzleCount = GetNumSwizzleElements(&psInst->asOperands[j]); + + if(opSwizzleCount != 1) + bcatcstr(glsl, " ("); + TranslateOperand(psContext, &psInst->asOperands[j], TO_FLAG_INTEGER); + if(opSwizzleCount != 1) + bformata(glsl, " ).%s",bfi_elementidx[i]); + if(j != 1) + bcatcstr(glsl, ","); + } + + bcatcstr(glsl, ") "); + if(i + 1 != numoverall_elements) + bcatcstr(glsl, ", "); + } + + bcatcstr(glsl, ")."); + for(i = 0; i < numoverall_elements; ++i) + bformata(glsl, "%s",bfi_elementidx[i]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_CUT: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//CUT\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "EndPrimitive();\n"); + break; + } + case OPCODE_EMIT: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EMIT\n"); +#endif + if(psContext->havePostShaderCode[psContext->currentPhase]) + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- Post shader code ---\n"); +#endif + bconcat(glsl, psContext->postShaderCode[psContext->currentPhase]); +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//--- End post shader code ---\n"); +#endif + AddIndentation(psContext); + } + + AddIndentation(psContext); + bcatcstr(glsl, "EmitVertex();\n"); + break; + } + case OPCODE_EMITTHENCUT: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EMITTHENCUT\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "EmitVertex();\nEndPrimitive();\n"); + break; + } + + case OPCODE_CUT_STREAM: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//CUT\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "EndStreamPrimitive("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, ");\n"); + + break; + } + case OPCODE_EMIT_STREAM: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EMIT\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "EmitStreamVertex("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_EMITTHENCUT_STREAM: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EMITTHENCUT\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "EmitStreamVertex("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, ");\n"); + bcatcstr(glsl, "EndStreamPrimitive("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_REP: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//REP\n"); +#endif + //Need to handle nesting. + //Max of 4 for rep - 'Flow Control Limitations' http://msdn.microsoft.com/en-us/library/windows/desktop/bb219848(v=vs.85).aspx + + AddIndentation(psContext); + bcatcstr(glsl, "RepCounter = ivec4("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl, ").x;\n"); + + AddIndentation(psContext); + bcatcstr(glsl, "while(RepCounter!=0){\n"); + ++psContext->indent; + break; + } + case OPCODE_ENDREP: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ENDREP\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "RepCounter--;\n"); + + --psContext->indent; + + AddIndentation(psContext); + bcatcstr(glsl, "}\n"); + break; + } + case OPCODE_LOOP: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LOOP\n"); +#endif + AddIndentation(psContext); + + if(psInst->ui32NumOperands == 2) + { + //DX9 version + ASSERT(psInst->asOperands[0].eType == OPERAND_TYPE_SPECIAL_LOOPCOUNTER); + bcatcstr(glsl, "for("); + bcatcstr(glsl, "LoopCounter = "); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, ".y, ZeroBasedCounter = 0;"); + bcatcstr(glsl, "ZeroBasedCounter < "); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, ".x;"); + + bcatcstr(glsl, "LoopCounter += "); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, ".z, ZeroBasedCounter++){\n"); + ++psContext->indent; + } + else + { + bcatcstr(glsl, "while(true){\n"); + ++psContext->indent; + } + break; + } + case OPCODE_ENDLOOP: + { + --psContext->indent; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ENDLOOP\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "}\n"); + break; + } + case OPCODE_BREAK: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//BREAK\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "break;\n"); + break; + } + case OPCODE_BREAKC: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//BREAKC\n"); +#endif + AddIndentation(psContext); + + TranslateConditional(psContext, psInst, glsl); + break; + } + case OPCODE_CONTINUEC: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//CONTINUEC\n"); +#endif + AddIndentation(psContext); + + TranslateConditional(psContext, psInst, glsl); + break; + } + case OPCODE_IF: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IF\n"); +#endif + AddIndentation(psContext); + + TranslateConditional(psContext, psInst, glsl); + ++psContext->indent; + break; + } + case OPCODE_RETC: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//RETC\n"); +#endif + AddIndentation(psContext); + + TranslateConditional(psContext, psInst, glsl); + break; + } + case OPCODE_ELSE: + { + --psContext->indent; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ELSE\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "} else {\n"); + psContext->indent++; + break; + } + case OPCODE_ENDSWITCH: + case OPCODE_ENDIF: + { + --psContext->indent; + AddIndentation(psContext); + bcatcstr(glsl, "//ENDIF\n"); + AddIndentation(psContext); + bcatcstr(glsl, "}\n"); + break; + } + case OPCODE_CONTINUE: + { + AddIndentation(psContext); + bcatcstr(glsl, "continue;\n"); + break; + } + case OPCODE_DEFAULT: + { + --psContext->indent; + AddIndentation(psContext); + bcatcstr(glsl, "default:\n"); + ++psContext->indent; + break; + } + case OPCODE_NOP: + { + break; + } + case OPCODE_SYNC: + { + const uint32_t ui32SyncFlags = psInst->ui32SyncFlags; + +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SYNC\n"); +#endif + + if(ui32SyncFlags & SYNC_THREADS_IN_GROUP) + { + AddIndentation(psContext); + bcatcstr(glsl, "groupMemoryBarrier();\n"); + } + if(ui32SyncFlags & SYNC_THREAD_GROUP_SHARED_MEMORY) + { + AddIndentation(psContext); + bcatcstr(glsl, "memoryBarrierShared();\n"); + } + if(ui32SyncFlags & (SYNC_UNORDERED_ACCESS_VIEW_MEMORY_GROUP|SYNC_UNORDERED_ACCESS_VIEW_MEMORY_GLOBAL)) + { + AddIndentation(psContext); + bcatcstr(glsl, "memoryBarrier();\n"); + } + break; + } + case OPCODE_SWITCH: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//SWITCH\n"); +#endif + AddIndentation(psContext); + bcatcstr(glsl, "switch(int("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl, ")){\n"); + + psContext->indent += 2; + break; + } + case OPCODE_CASE: + { + --psContext->indent; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//case\n"); +#endif + AddIndentation(psContext); + + bcatcstr(glsl, "case "); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl, ":\n"); + + ++psContext->indent; + break; + } + case OPCODE_EQ: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EQ\n"); +#endif + AddComparision(psContext, psInst, CMP_EQ, TO_FLAG_NONE); + break; + } + case OPCODE_USHR: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//USHR\n"); +#endif + CallBinaryOp(psContext, ">>", psInst, 0, 1, 2, TO_FLAG_UNSIGNED_INTEGER); + break; + } + case OPCODE_ISHL: + { + uint32_t ui32Flags = TO_FLAG_INTEGER; + +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ISHL\n"); +#endif + + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + { + ui32Flags = TO_FLAG_UNSIGNED_INTEGER; + } + + CallBinaryOp(psContext, "<<", psInst, 0, 1, 2, ui32Flags); + break; + } + case OPCODE_ISHR: + { + uint32_t ui32Flags = TO_FLAG_INTEGER; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//ISHR\n"); +#endif + + if(GetOperandDataType(psContext, &psInst->asOperands[0]) == SVT_UINT) + { + ui32Flags = TO_FLAG_UNSIGNED_INTEGER; + } + + CallBinaryOp(psContext, ">>", psInst, 0, 1, 2, ui32Flags); + break; + } + case OPCODE_LD: + case OPCODE_LD_MS: + { + ResourceBinding* psBinding = 0; + uint32_t dstSwizCount = GetNumSwizzleElements(&psInst->asOperands[0]); +#ifdef _DEBUG + AddIndentation(psContext); + if(psInst->eOpcode == OPCODE_LD) + bcatcstr(glsl, "//LD\n"); + else + bcatcstr(glsl, "//LD_MS\n"); +#endif + + GetResourceFromBindingPoint(RGROUP_TEXTURE, psInst->asOperands[2].ui32RegisterNumber, &psContext->psShader->sInfo, &psBinding); + + if(psInst->bAddressOffset) + { + TranslateTexelFetchOffset(psContext, psInst, psBinding, glsl); + } + else + { + TranslateTexelFetch(psContext, psInst, psBinding, glsl); + } + break; + } + case OPCODE_DISCARD: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DISCARD\n"); +#endif + AddIndentation(psContext); + if(psContext->psShader->ui32MajorVersion <= 3) + { + bcatcstr(glsl, "if(any(lessThan(("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + + if(psContext->psShader->ui32MajorVersion == 1) + { + /* SM1.X only kills based on the rgb channels */ + bcatcstr(glsl, ").xyz, vec3(0)))){discard;}\n"); + } + else + { + bcatcstr(glsl, "), vec4(0)))){discard;}\n"); + } + } + else if(psInst->eBooleanTestType == INSTRUCTION_TEST_ZERO) + { + bcatcstr(glsl, "if(("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl, ")==0){discard;}\n"); + } + else + { + ASSERT(psInst->eBooleanTestType == INSTRUCTION_TEST_NONZERO); + bcatcstr(glsl, "if(("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl, ")!=0){discard;}\n"); + } + break; + } + case OPCODE_LOD: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LOD\n"); +#endif + //LOD computes the following vector (ClampedLOD, NonClampedLOD, 0, 0) + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + + //If the core language does not have query-lod feature, + //then the extension is used. The name of the function + //changed between extension and core. + if(HaveQueryLod(psContext->psShader->eTargetLanguage)) + { + bcatcstr(glsl, " = textureQueryLod("); + } + else + { + bcatcstr(glsl, " = textureQueryLOD("); + } + + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ","); + TranslateTexCoord(psContext, + psContext->psShader->aeResourceDims[psInst->asOperands[2].ui32RegisterNumber], + &psInst->asOperands[1]); + bcatcstr(glsl, ")"); + + //The swizzle on srcResource allows the returned values to be swizzled arbitrarily before they are written to the destination. + + // iWriteMaskEnabled is forced off during DecodeOperand because swizzle on sampler uniforms + // does not make sense. But need to re-enable to correctly swizzle this particular instruction. + psInst->asOperands[2].iWriteMaskEnabled = 1; + TranslateOperandSwizzle(psContext, &psInst->asOperands[2]); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_EVAL_CENTROID: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EVAL_CENTROID\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = interpolateAtCentroid("); + //interpolateAtCentroid accepts in-qualified variables. + //As long as bytecode only writes vX registers in declarations + //we should be able to use the declared name directly. + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_DECLARATION_NAME); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_EVAL_SAMPLE_INDEX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EVAL_SAMPLE_INDEX\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = interpolateAtSample("); + //interpolateAtSample accepts in-qualified variables. + //As long as bytecode only writes vX registers in declarations + //we should be able to use the declared name directly. + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_DECLARATION_NAME); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_INTEGER); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_EVAL_SNAPPED: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//EVAL_SNAPPED\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = interpolateAtOffset("); + //interpolateAtOffset accepts in-qualified variables. + //As long as bytecode only writes vX registers in declarations + //we should be able to use the declared name directly. + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_DECLARATION_NAME); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_INTEGER); + bcatcstr(glsl, ".xy);\n"); + break; + } + case OPCODE_LD_STRUCTURED: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LD_STRUCTURED\n"); +#endif + TranslateShaderStorageLoad(psContext, psInst); + break; + } + case OPCODE_LD_UAV_TYPED: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LD_UAV_TYPED\n"); +#endif + switch(psInst->eResDim) + { + case RESOURCE_DIMENSION_TEXTURE1D: + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = imageLoad("); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, ", ("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bformata(glsl, ").x)"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + case RESOURCE_DIMENSION_TEXTURECUBE: + case RESOURCE_DIMENSION_TEXTURE1DARRAY: + case RESOURCE_DIMENSION_TEXTURE2D: + case RESOURCE_DIMENSION_TEXTURE2DMS: + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = imageLoad("); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, ", ("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bformata(glsl, ").xy)"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + case RESOURCE_DIMENSION_TEXTURE3D: + case RESOURCE_DIMENSION_TEXTURE2DARRAY: + case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = imageLoad("); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, ", ("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bformata(glsl, ").xyz)"); + TranslateOperandSwizzle(psContext, &psInst->asOperands[0]); + bcatcstr(glsl, ";\n"); + break; + } + break; + } + case OPCODE_STORE_RAW: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//STORE_RAW\n"); +#endif + TranslateShaderStorageStore(psContext, psInst); + break; + } + case OPCODE_STORE_STRUCTURED: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//STORE_STRUCTURED\n"); +#endif + TranslateShaderStorageStore(psContext, psInst); + break; + } + + case OPCODE_STORE_UAV_TYPED: + { + ResourceBinding* psRes; + int foundResource; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//STORE_UAV_TYPED\n"); +#endif + AddIndentation(psContext); + + foundResource = GetResourceFromBindingPoint(RGROUP_UAV, + psInst->asOperands[0].ui32RegisterNumber, + &psContext->psShader->sInfo, + &psRes); + + ASSERT(foundResource); + + bcatcstr(glsl, "imageStore("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NAME_ONLY); + switch(psRes->eDimension) + { + case REFLECT_RESOURCE_DIMENSION_TEXTURE1D: + bcatcstr(glsl, ", int("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, "), "); + break; + case REFLECT_RESOURCE_DIMENSION_TEXTURE2D: + case REFLECT_RESOURCE_DIMENSION_TEXTURE1DARRAY: + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DMS: + bcatcstr(glsl, ", ivec2("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, ".xy), "); + break; + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DARRAY: + case REFLECT_RESOURCE_DIMENSION_TEXTURE3D: + case REFLECT_RESOURCE_DIMENSION_TEXTURE2DMSARRAY: + case REFLECT_RESOURCE_DIMENSION_TEXTURECUBE: + bcatcstr(glsl, ", ivec3("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, ".xyz), "); + break; + case REFLECT_RESOURCE_DIMENSION_TEXTURECUBEARRAY: + bcatcstr(glsl, ", ivec4("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NAME_ONLY); + bcatcstr(glsl, ".xyzw) "); + break; + }; + + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bformata(glsl, ");\n"); + + break; + } + case OPCODE_LD_RAW: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LD_RAW\n"); +#endif + + TranslateShaderStorageLoad(psContext, psInst); + break; + } + + case OPCODE_ATOMIC_CMP_STORE: + case OPCODE_IMM_ATOMIC_AND: + case OPCODE_ATOMIC_AND: + case OPCODE_IMM_ATOMIC_IADD: + case OPCODE_ATOMIC_IADD: + case OPCODE_ATOMIC_OR: + case OPCODE_ATOMIC_XOR: + case OPCODE_ATOMIC_IMIN: + case OPCODE_ATOMIC_UMIN: + case OPCODE_IMM_ATOMIC_IMAX: + case OPCODE_IMM_ATOMIC_IMIN: + case OPCODE_IMM_ATOMIC_UMAX: + case OPCODE_IMM_ATOMIC_UMIN: + case OPCODE_IMM_ATOMIC_OR: + case OPCODE_IMM_ATOMIC_XOR: + case OPCODE_IMM_ATOMIC_EXCH: + case OPCODE_IMM_ATOMIC_CMP_EXCH: + { + TranslateAtomicMemOp(psContext, psInst); + break; + } + case OPCODE_UBFE: + case OPCODE_IBFE: + { +#ifdef _DEBUG + AddIndentation(psContext); + if(psInst->eOpcode == OPCODE_UBFE) + bcatcstr(glsl, "//OPCODE_UBFE\n"); + else + bcatcstr(glsl, "//OPCODE_IBFE\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = bitfieldExtract("); + TranslateOperand(psContext, &psInst->asOperands[3], TO_FLAG_NONE); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ", "); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_RCP: + { + const uint32_t destElemCount = GetNumSwizzleElements(&psInst->asOperands[0]); +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//RCP\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = (vec4(1.0) / vec4("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, "))"); + AddSwizzleUsingElementCount(psContext, destElemCount); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_F32TOF16: + { + const uint32_t destElemCount = GetNumSwizzleElements(&psInst->asOperands[0]); + const uint32_t s0ElemCount = GetNumSwizzleElements(&psInst->asOperands[1]); + uint32_t destElem; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//F32TOF16\n"); +#endif + for(destElem=0; destElem < destElemCount; ++destElem) + { + const char* swizzle[] = {".x", ".y", ".z", ".w"}; + + //unpackHalf2x16 converts two f16s packed into uint to two f32s. + + //dest.swiz.x = unpackHalf2x16(src.swiz.x).x + //dest.swiz.y = unpackHalf2x16(src.swiz.y).x + //dest.swiz.z = unpackHalf2x16(src.swiz.z).x + //dest.swiz.w = unpackHalf2x16(src.swiz.w).x + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + if(destElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + + bcatcstr(glsl, " = unpackHalf2x16("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_UNSIGNED_INTEGER); + if(s0ElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + bcatcstr(glsl, ").x;\n"); + + } + break; + } + case OPCODE_F16TOF32: + { + const uint32_t destElemCount = GetNumSwizzleElements(&psInst->asOperands[0]); + const uint32_t s0ElemCount = GetNumSwizzleElements(&psInst->asOperands[1]); + uint32_t destElem; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//F16TOF32\n"); +#endif + for(destElem=0; destElem < destElemCount; ++destElem) + { + const char* swizzle[] = {".x", ".y", ".z", ".w"}; + + //packHalf2x16 converts two f32s to two f16s packed into a uint. + + //dest.swiz.x = packHalf2x16(vec2(src.swiz.x)) & 0xFFFF + //dest.swiz.y = packHalf2x16(vec2(src.swiz.y)) & 0xFFFF + //dest.swiz.z = packHalf2x16(vec2(src.swiz.z)) & 0xFFFF + //dest.swiz.w = packHalf2x16(vec2(src.swiz.w)) & 0xFFFF + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION|TO_FLAG_UNSIGNED_INTEGER); + if(destElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + + bcatcstr(glsl, " = packHalf2x16(vec2("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + if(s0ElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + bcatcstr(glsl, ")) & 0xFFFF;\n"); + + } + break; + } + case OPCODE_INEG: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//INEG\n"); +#endif + //dest = 0 - src0 + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION|TO_FLAG_INTEGER); + bcatcstr(glsl, " = 0 - "); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE|TO_FLAG_INTEGER); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_DERIV_RTX_COARSE: + case OPCODE_DERIV_RTX_FINE: + case OPCODE_DERIV_RTX: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DERIV_RTX\n"); +#endif + CallHelper1(psContext, "dFdx", psInst, 0, 1); + break; + } + case OPCODE_DERIV_RTY_COARSE: + case OPCODE_DERIV_RTY_FINE: + case OPCODE_DERIV_RTY: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DERIV_RTY\n"); +#endif + CallHelper1(psContext, "dFdy", psInst, 0, 1); + break; + } + case OPCODE_LRP: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//LRP\n"); +#endif + CallHelper3(psContext, "mix", psInst, 0, 2, 3, 1); + break; + } + case OPCODE_DP2ADD: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//DP2ADD\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = dot(vec2("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, "), vec2("); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ")) + "); + TranslateOperand(psContext, &psInst->asOperands[3], TO_FLAG_NONE); + bcatcstr(glsl, ";\n"); + break; + } + case OPCODE_POW: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//POW\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = pow(abs("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_NONE); + bcatcstr(glsl, "), "); + TranslateOperand(psContext, &psInst->asOperands[2], TO_FLAG_NONE); + bcatcstr(glsl, ");\n"); + break; + } + + case OPCODE_IMM_ATOMIC_ALLOC: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_ALLOC\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = atomicCounterIncrement("); + bformata(glsl, "UAV%d_counter", psInst->asOperands[1].ui32RegisterNumber); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_IMM_ATOMIC_CONSUME: + { +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//IMM_ATOMIC_CONSUME\n"); +#endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + bcatcstr(glsl, " = atomicCounterDecrement("); + bformata(glsl, "UAV%d_counter", psInst->asOperands[1].ui32RegisterNumber); + bcatcstr(glsl, ");\n"); + break; + } + + case OPCODE_NOT: + { + #ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//INOT\n"); + #endif + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + + bcatcstr(glsl, " = ~("); + TranslateOperand(psContext, &psInst->asOperands[1], TO_FLAG_INTEGER); + bcatcstr(glsl, ");\n"); + break; + } + case OPCODE_XOR: + { + #ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//XOR\n"); + #endif + + CallBinaryOp(psContext, "^", psInst, 0, 1, 2, TO_FLAG_INTEGER); + break; + } + case OPCODE_RESINFO: + { + + const RESOURCE_DIMENSION eResDim = psContext->psShader->aeResourceDims[psInst->asOperands[2].ui32RegisterNumber]; + const RESINFO_RETURN_TYPE eResInfoReturnType = psInst->eResInfoReturnType; + uint32_t destElemCount = GetNumSwizzleElements(&psInst->asOperands[0]); + uint32_t destElem; +#ifdef _DEBUG + AddIndentation(psContext); + bcatcstr(glsl, "//RESINFO\n"); +#endif + + //ASSERT(psInst->asOperands[0].eSelMode == OPERAND_4_COMPONENT_MASK_MODE); + //ASSERT(psInst->asOperands[0].ui32CompMask == OPERAND_4_COMPONENT_MASK_ALL); + + + + + for(destElem=0; destElem < destElemCount; ++destElem) + { + const char* swizzle[] = {".x", ".y", ".z", ".w"}; + + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_DESTINATION); + + if(destElemCount>1) + bcatcstr(glsl, swizzle[destElem]); + + bcatcstr(glsl, " = "); + + GetResInfoData(psContext, psInst, psInst->asOperands[2].aui32Swizzle[destElem]); + } + + break; + } + + + case OPCODE_DMAX: + case OPCODE_DMIN: + case OPCODE_DMUL: + case OPCODE_DEQ: + case OPCODE_DGE: + case OPCODE_DLT: + case OPCODE_DNE: + case OPCODE_DMOV: + case OPCODE_DMOVC: + case OPCODE_DTOF: + case OPCODE_FTOD: + case OPCODE_DDIV: + case OPCODE_DFMA: + case OPCODE_DRCP: + case OPCODE_MSAD: + case OPCODE_DTOI: + case OPCODE_DTOU: + case OPCODE_ITOD: + case OPCODE_UTOD: + default: + { + ASSERT(0); + break; + } + } + + if(psInst->bSaturate) + { + AddIndentation(psContext); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl ," = clamp("); + TranslateOperand(psContext, &psInst->asOperands[0], TO_FLAG_NONE); + bcatcstr(glsl, ", 0.0, 1.0);\n"); + } +} + +static int IsIntegerOpcode(OPCODE_TYPE eOpcode) +{ + switch(eOpcode) + { + case OPCODE_IADD: + case OPCODE_IF: + case OPCODE_IEQ: + case OPCODE_IGE: + case OPCODE_ILT: + case OPCODE_IMAD: + case OPCODE_IMAX: + case OPCODE_IMIN: + case OPCODE_IMUL: + case OPCODE_INE: + case OPCODE_INEG: + case OPCODE_ISHL: + case OPCODE_ISHR: + case OPCODE_ITOF: + { + return 1; + } + default: + { + return 0; + } + } +} + +int InstructionUsesRegister(const Instruction* psInst, const Operand* psOperand) +{ + uint32_t operand; + for(operand=0; operand < psInst->ui32NumOperands; ++operand) + { + if(psInst->asOperands[operand].eType == psOperand->eType) + { + if(psInst->asOperands[operand].ui32RegisterNumber == psOperand->ui32RegisterNumber) + { + if(CompareOperandSwizzles(&psInst->asOperands[operand], psOperand)) + { + return 1; + } + } + } + } + return 0; +} + +void MarkIntegerImmediates(HLSLCrossCompilerContext* psContext) +{ + const uint32_t count = psContext->psShader->ui32InstCount; + Instruction* psInst = psContext->psShader->psInst; + uint32_t i; + + for(i=0; i < count;) + { + if(psInst[i].eOpcode == OPCODE_MOV && psInst[i].asOperands[1].eType == OPERAND_TYPE_IMMEDIATE32 && + psInst[i].asOperands[0].eType == OPERAND_TYPE_TEMP) + { + uint32_t k; + + for(k=i+1; k < count; ++k) + { + if(psInst[k].eOpcode == OPCODE_ILT) + { + k = k; + } + if(InstructionUsesRegister(&psInst[k], &psInst[i].asOperands[0])) + { + if(IsIntegerOpcode(psInst[k].eOpcode)) + { + psInst[i].asOperands[1].iIntegerImmediate = 1; + } + + goto next_iteration; + } + } + } +next_iteration: + ++i; + } +} diff --git a/build/tools/HLSLcc/May_2014/src/toGLSLOperand.c b/build/tools/HLSLcc/May_2014/src/toGLSLOperand.c new file mode 100644 index 0000000..d16b889 --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/toGLSLOperand.c @@ -0,0 +1,1557 @@ +#include "internal_includes/toGLSLOperand.h" +#include "internal_includes/toGLSLDeclaration.h" +#include "bstrlib.h" +#include "hlslcc.h" +#include "internal_includes/debug.h" + +#include + +#ifdef _MSC_VER +#define isnan(x) _isnan(x) +#define isinf(x) (!_finite(x)) +#endif + +#define fpcheck(x) (isnan(x) || isinf(x)) + +extern void AddIndentation(HLSLCrossCompilerContext* psContext); + +int GetMaxComponentFromComponentMask(const Operand* psOperand) +{ + if(psOperand->iWriteMaskEnabled && + psOperand->iNumComponents == 4) + { + //Comonent Mask + if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + if(psOperand->ui32CompMask != 0 && psOperand->ui32CompMask != (OPERAND_4_COMPONENT_MASK_X|OPERAND_4_COMPONENT_MASK_Y|OPERAND_4_COMPONENT_MASK_Z|OPERAND_4_COMPONENT_MASK_W)) + { + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_W) + { + return 4; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Z) + { + return 3; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Y) + { + return 2; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_X) + { + return 1; + } + } + } + else + //Component Swizzle + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + return 4; + } + else + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + return 1; + } + } + + return 4; +} + +//Single component repeated +//e..g .wwww +uint32_t IsSwizzleReplacated(const Operand* psOperand) +{ + if(psOperand->iWriteMaskEnabled && + psOperand->iNumComponents == 4) + { + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle == WWWW_SWIZZLE || + psOperand->ui32Swizzle == ZZZZ_SWIZZLE || + psOperand->ui32Swizzle == YYYY_SWIZZLE || + psOperand->ui32Swizzle == XXXX_SWIZZLE) + { + return 1; + } + } + } + return 0; +} + +//e.g. +//.z = 1 +//.x = 1 +//.yw = 2 +uint32_t GetNumSwizzleElements(const Operand* psOperand) +{ + uint32_t count = 0; + + switch(psOperand->eType) + { + case OPERAND_TYPE_IMMEDIATE32: + case OPERAND_TYPE_IMMEDIATE64: + case OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL: + case OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL: + case OPERAND_TYPE_OUTPUT_DEPTH: + { + return psOperand->iNumComponents; + } + default: + { + break; + } + } + + if(psOperand->iWriteMaskEnabled && + psOperand->iNumComponents == 4) + { + //Comonent Mask + if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + if(psOperand->ui32CompMask != 0 && psOperand->ui32CompMask != (OPERAND_4_COMPONENT_MASK_X|OPERAND_4_COMPONENT_MASK_Y|OPERAND_4_COMPONENT_MASK_Z|OPERAND_4_COMPONENT_MASK_W)) + { + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_X) + { + count++; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Y) + { + count++; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Z) + { + count++; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_W) + { + count++; + } + } + } + else + //Component Swizzle + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle != (NO_SWIZZLE)) + { + uint32_t i; + + for(i=0; i< 4; ++i) + { + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_X) + { + count++; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Y) + { + count++; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Z) + { + count++; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_W) + { + count++; + } + } + } + } + else + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_X) + { + count++; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Y) + { + count++; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Z) + { + count++; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_W) + { + count++; + } + } + + //Component Select 1 + } + + if(!count) + { + return psOperand->iNumComponents; + } + + return count; +} + +void AddSwizzleUsingElementCount(HLSLCrossCompilerContext* psContext, uint32_t count) +{ + bstring glsl = *psContext->currentGLSLString; + if(count) + { + bcatcstr(glsl, "."); + bcatcstr(glsl, "x"); + count--; + } + if(count) + { + bcatcstr(glsl, "y"); + count--; + } + if(count) + { + bcatcstr(glsl, "z"); + count--; + } + if(count) + { + bcatcstr(glsl, "w"); + count--; + } +} + +static uint32_t ConvertOperandSwizzleToComponentMask(const Operand* psOperand) +{ + uint32_t mask = 0; + + if(psOperand->iWriteMaskEnabled && + psOperand->iNumComponents == 4) + { + //Comonent Mask + if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + mask = psOperand->ui32CompMask; + } + else + //Component Swizzle + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle != (NO_SWIZZLE)) + { + uint32_t i; + + for(i=0; i< 4; ++i) + { + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_X) + { + mask |= OPERAND_4_COMPONENT_MASK_X; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Y) + { + mask |= OPERAND_4_COMPONENT_MASK_Y; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Z) + { + mask |= OPERAND_4_COMPONENT_MASK_Z; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_W) + { + mask |= OPERAND_4_COMPONENT_MASK_W; + } + } + } + } + else + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_X) + { + mask |= OPERAND_4_COMPONENT_MASK_X; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Y) + { + mask |= OPERAND_4_COMPONENT_MASK_Y; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Z) + { + mask |= OPERAND_4_COMPONENT_MASK_Z; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_W) + { + mask |= OPERAND_4_COMPONENT_MASK_W; + } + } + + //Component Select 1 + } + + return mask; +} + +//Non-zero means the components overlap +int CompareOperandSwizzles(const Operand* psOperandA, const Operand* psOperandB) +{ + uint32_t maskA = ConvertOperandSwizzleToComponentMask(psOperandA); + uint32_t maskB = ConvertOperandSwizzleToComponentMask(psOperandB); + + return maskA & maskB; +} + + +void TranslateOperandSwizzle(HLSLCrossCompilerContext* psContext, const Operand* psOperand) +{ + bstring glsl = *psContext->currentGLSLString; + + if(psOperand->eType == OPERAND_TYPE_INPUT) + { + if(psContext->psShader->abScalarInput[psOperand->ui32RegisterNumber]) + { + return; + } + } + + if(psOperand->eType == OPERAND_TYPE_CONSTANT_BUFFER) + { + /*ConstantBuffer* psCBuf = NULL; + ShaderVar* psVar = NULL; + int32_t index = -1; + GetConstantBufferFromBindingPoint(psOperand->aui32ArraySizes[0], &psContext->psShader->sInfo, &psCBuf); + + //Access the Nth vec4 (N=psOperand->aui32ArraySizes[1]) + //then apply the sizzle. + + GetShaderVarFromOffset(psOperand->aui32ArraySizes[1], psOperand->aui32Swizzle, psCBuf, &psVar, &index); + + bformata(glsl, ".%s", psVar->Name); + if(index != -1) + { + bformata(glsl, "[%d]", index); + }*/ + + //return; + } + + if(psOperand->iWriteMaskEnabled && + psOperand->iNumComponents == 4) + { + //Comonent Mask + if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + if(psOperand->ui32CompMask != 0 && psOperand->ui32CompMask != (OPERAND_4_COMPONENT_MASK_X|OPERAND_4_COMPONENT_MASK_Y|OPERAND_4_COMPONENT_MASK_Z|OPERAND_4_COMPONENT_MASK_W)) + { + bcatcstr(glsl, "."); + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_X) + { + bcatcstr(glsl, "x"); + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Y) + { + bcatcstr(glsl, "y"); + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Z) + { + bcatcstr(glsl, "z"); + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_W) + { + bcatcstr(glsl, "w"); + } + } + } + else + //Component Swizzle + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle != (NO_SWIZZLE)) + { + uint32_t i; + + bcatcstr(glsl, "."); + + for(i=0; i< 4; ++i) + { + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_X) + { + bcatcstr(glsl, "x"); + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Y) + { + bcatcstr(glsl, "y"); + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Z) + { + bcatcstr(glsl, "z"); + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_W) + { + bcatcstr(glsl, "w"); + } + } + } + } + else + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + bcatcstr(glsl, "."); + + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_X) + { + bcatcstr(glsl, "x"); + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Y) + { + bcatcstr(glsl, "y"); + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Z) + { + bcatcstr(glsl, "z"); + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_W) + { + bcatcstr(glsl, "w"); + } + } + + //Component Select 1 + } +} + +int GetFirstOperandSwizzle(HLSLCrossCompilerContext* psContext, const Operand* psOperand) +{ + if(psOperand->eType == OPERAND_TYPE_INPUT) + { + if(psContext->psShader->abScalarInput[psOperand->ui32RegisterNumber]) + { + return - 1; + } + } + + if(psOperand->iWriteMaskEnabled && + psOperand->iNumComponents == 4) + { + //Comonent Mask + if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + if(psOperand->ui32CompMask != 0 && psOperand->ui32CompMask != (OPERAND_4_COMPONENT_MASK_X|OPERAND_4_COMPONENT_MASK_Y|OPERAND_4_COMPONENT_MASK_Z|OPERAND_4_COMPONENT_MASK_W)) + { + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_X) + { + return 0; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Y) + { + return 1; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_Z) + { + return 2; + } + if(psOperand->ui32CompMask & OPERAND_4_COMPONENT_MASK_W) + { + return 3; + } + } + } + else + //Component Swizzle + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle != (NO_SWIZZLE)) + { + uint32_t i; + + for(i=0; i< 4; ++i) + { + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_X) + { + return 0; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Y) + { + return 1; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_Z) + { + return 2; + } + else + if(psOperand->aui32Swizzle[i] == OPERAND_4_COMPONENT_W) + { + return 3; + } + } + } + } + else + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_X) + { + return 0; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Y) + { + return 1; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_Z) + { + return 2; + } + else + if(psOperand->aui32Swizzle[0] == OPERAND_4_COMPONENT_W) + { + return 3; + } + } + + //Component Select 1 + } + + return -1; +} + +void TranslateOperandIndex(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index) +{ + int i = index; + int isGeoShader = psContext->psShader->eShaderType == GEOMETRY_SHADER ? 1 : 0; + + bstring glsl = *psContext->currentGLSLString; + + ASSERT(index < psOperand->iIndexDims); + + switch(psOperand->eIndexRep[i]) + { + case OPERAND_INDEX_IMMEDIATE32: + { + if(i > 0 || isGeoShader) + { + bformata(glsl, "[%d]", psOperand->aui32ArraySizes[i]); + } + else + { + bformata(glsl, "%d", psOperand->aui32ArraySizes[i]); + } + break; + } + case OPERAND_INDEX_RELATIVE: + { + bcatcstr(glsl, "[int("); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[i], TO_FLAG_NONE); + bcatcstr(glsl, ")]"); + break; + } + case OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE: + { + bcatcstr(glsl, "[int("); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[i], TO_FLAG_NONE); + bformata(glsl, ") + %d]", psOperand->aui32ArraySizes[i]); + break; + } + default: + { + break; + } + } +} + +void TranslateOperandIndexMAD(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index, uint32_t multiply, uint32_t add) +{ + int i = index; + int isGeoShader = psContext->psShader->eShaderType == GEOMETRY_SHADER ? 1 : 0; + + bstring glsl = *psContext->currentGLSLString; + + ASSERT(index < psOperand->iIndexDims); + + switch(psOperand->eIndexRep[i]) + { + case OPERAND_INDEX_IMMEDIATE32: + { + if(i > 0 || isGeoShader) + { + bformata(glsl, "[%d*%d+%d]", psOperand->aui32ArraySizes[i], multiply, add); + } + else + { + bformata(glsl, "%d*%d+%d", psOperand->aui32ArraySizes[i], multiply, add); + } + break; + } + case OPERAND_INDEX_RELATIVE: + { + bcatcstr(glsl, "[int("); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[i], TO_FLAG_NONE); + bformata(glsl, ")*%d+%d]", multiply, add); + break; + } + case OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE: + { + bcatcstr(glsl, "[(int("); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[i], TO_FLAG_NONE); + bformata(glsl, ") + %d)*%d+%d]", psOperand->aui32ArraySizes[i], multiply, add); + break; + } + default: + { + break; + } + } +} + +static void TranslateVariableName(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle) +{ + int integerConstructor = 0; + bstring glsl = *psContext->currentGLSLString; + + *pui32IgnoreSwizzle = 0; + + if(psOperand->eType != OPERAND_TYPE_IMMEDIATE32 && + psOperand->eType != OPERAND_TYPE_IMMEDIATE64 && + psOperand->eType != OPERAND_TYPE_CONSTANT_BUFFER) + { + const uint32_t swizCount = psOperand->iNumComponents; + SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand); + + if( (ui32TOFlag & (TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER)) == (TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER)) + { + //Can be either int or uint + if(eType != SVT_INT && eType != SVT_UINT) + { + if(swizCount == 1) + bformata(glsl, "int("); + else + bformata(glsl, "ivec%d(", swizCount); + + integerConstructor = 1; + } + } + else + { + if((ui32TOFlag & (TO_FLAG_INTEGER|TO_FLAG_DESTINATION))==TO_FLAG_INTEGER && + eType != SVT_INT) + { + //Convert to int + if(swizCount == 1) + bformata(glsl, "int("); + else + bformata(glsl, "ivec%d(", swizCount); + + integerConstructor = 1; + } + if((ui32TOFlag & (TO_FLAG_UNSIGNED_INTEGER|TO_FLAG_DESTINATION))==TO_FLAG_UNSIGNED_INTEGER && + eType != SVT_UINT) + { + //Convert to uint + if(swizCount == 1) + bformata(glsl, "uint("); + else + bformata(glsl, "uvec%d(", swizCount); + integerConstructor = 1; + } + } + } + + switch(psOperand->eType) + { + case OPERAND_TYPE_IMMEDIATE32: + { + if(psOperand->iNumComponents == 1) + { + if(ui32TOFlag & TO_FLAG_UNSIGNED_INTEGER) + { + bformata(glsl, "%uu", + *((unsigned int*)(&psOperand->afImmediates[0]))); + } + else + if((ui32TOFlag & TO_FLAG_INTEGER) || psOperand->iIntegerImmediate || fpcheck(psOperand->afImmediates[0])) + { + bformata(glsl, "%d", + *((int*)(&psOperand->afImmediates[0]))); + } + else + { + bformata(glsl, "%f", + psOperand->afImmediates[0]); + } + } + else + { + if(ui32TOFlag & TO_FLAG_UNSIGNED_INTEGER) + { + bformata(glsl, "uvec4(%uu, %uu, %uu, %uu)", + *(unsigned int*)&psOperand->afImmediates[0], + *(unsigned int*)&psOperand->afImmediates[1], + *(unsigned int*)&psOperand->afImmediates[2], + *(unsigned int*)&psOperand->afImmediates[3]); + } + else + if((ui32TOFlag & TO_FLAG_INTEGER) || + psOperand->iIntegerImmediate || + fpcheck(psOperand->afImmediates[0]) || + fpcheck(psOperand->afImmediates[1]) || + fpcheck(psOperand->afImmediates[2]) || + fpcheck(psOperand->afImmediates[3])) + { + bformata(glsl, "ivec4(%d, %d, %d, %d)", + *(int*)&psOperand->afImmediates[0], + *(int*)&psOperand->afImmediates[1], + *(int*)&psOperand->afImmediates[2], + *(int*)&psOperand->afImmediates[3]); + } + else + { + bformata(glsl, "vec4(%f, %f, %f, %f)", + psOperand->afImmediates[0], + psOperand->afImmediates[1], + psOperand->afImmediates[2], + psOperand->afImmediates[3]); + } + if(psOperand->iNumComponents != 4) + { + AddSwizzleUsingElementCount(psContext, psOperand->iNumComponents); + } + } + break; + } + case OPERAND_TYPE_IMMEDIATE64: + { + if(psOperand->iNumComponents == 1) + { + bformata(glsl, "%f", + psOperand->adImmediates[0]); + } + else + { + bformata(glsl, "dvec4(%f, %f, %f, %f)", + psOperand->adImmediates[0], + psOperand->adImmediates[1], + psOperand->adImmediates[2], + psOperand->adImmediates[3]); + if(psOperand->iNumComponents != 4) + { + AddSwizzleUsingElementCount(psContext, psOperand->iNumComponents); + } + } + break; + } + case OPERAND_TYPE_INPUT: + { + switch(psOperand->iIndexDims) + { + case INDEX_2D: + { + if(psOperand->aui32ArraySizes[1] == 0)//Input index zero - position. + { + bcatcstr(glsl, "gl_in"); + TranslateOperandIndex(psContext, psOperand, TO_FLAG_NONE);//Vertex index + bcatcstr(glsl, ".gl_Position"); + } + else + { + const char* name = "Input"; + if(ui32TOFlag & TO_FLAG_DECLARATION_NAME) + { + name = GetDeclaredInputName(psContext, psContext->psShader->eShaderType, psOperand); + } + + bformata(glsl, "%s%d", name, psOperand->aui32ArraySizes[1]); + TranslateOperandIndex(psContext, psOperand, TO_FLAG_NONE);//Vertex index + } + break; + } + default: + { + if(psOperand->eIndexRep[0] == OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE) + { + bformata(glsl, "Input%d[int(", psOperand->ui32RegisterNumber); + TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE); + bcatcstr(glsl, ")]"); + } + else + { + if(psContext->psShader->aIndexedInput[psOperand->ui32RegisterNumber] != 0) + { + const uint32_t parentIndex = psContext->psShader->aIndexedInputParents[psOperand->ui32RegisterNumber]; + bformata(glsl, "Input%d[%d]", parentIndex, + psOperand->ui32RegisterNumber - parentIndex); + } + else + { + if(ui32TOFlag & TO_FLAG_DECLARATION_NAME) + { + const char* name = GetDeclaredInputName(psContext, psContext->psShader->eShaderType, psOperand); + bcatcstr(glsl, name); + } + else + { + bformata(glsl, "Input%d", psOperand->ui32RegisterNumber); + } + } + } + break; + } + } + break; + } + case OPERAND_TYPE_OUTPUT: + { + bformata(glsl, "Output%d", psOperand->ui32RegisterNumber); + if(psOperand->psSubOperand[0]) + { + bcatcstr(glsl, "[int("); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE); + bcatcstr(glsl, ")]"); + } + break; + } + case OPERAND_TYPE_OUTPUT_DEPTH: + case OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL: + case OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL: + { + bcatcstr(glsl, "gl_FragDepth"); + break; + } + case OPERAND_TYPE_TEMP: + { + SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand); + bcatcstr(glsl, "Temp"); + + if(eType == SVT_INT) + { + bcatcstr(glsl, "_int"); + } + else if(eType == SVT_UINT) + { + bcatcstr(glsl, "_uint"); + } + else if(eType == SVT_DOUBLE) + { + bcatcstr(glsl, "_double"); + } + else if(eType == SVT_VOID || + (ui32TOFlag & TO_FLAG_DESTINATION)) + { + if(ui32TOFlag & TO_FLAG_INTEGER) + { + bcatcstr(glsl, "_int"); + } + else + if(ui32TOFlag & TO_FLAG_UNSIGNED_INTEGER) + { + bcatcstr(glsl, "_uint"); + } + } + + bformata(glsl, "[%d]", psOperand->ui32RegisterNumber); + + break; + } + case OPERAND_TYPE_SPECIAL_IMMCONSTINT: + { + bformata(glsl, "IntImmConst%d", psOperand->ui32RegisterNumber); + break; + } + case OPERAND_TYPE_SPECIAL_IMMCONST: + { + if(psOperand->psSubOperand[0] != NULL) + { + bformata(glsl, "ImmConstArray[%d + ", psContext->psShader->aui32Dx9ImmConstArrayRemap[psOperand->ui32RegisterNumber]); + TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE); + bcatcstr(glsl, "]"); + } + else + { + bformata(glsl, "ImmConst%d", psOperand->ui32RegisterNumber); + } + break; + } + case OPERAND_TYPE_SPECIAL_OUTBASECOLOUR: + { + bcatcstr(glsl, "BaseColour"); + break; + } + case OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR: + { + bcatcstr(glsl, "OffsetColour"); + break; + } + case OPERAND_TYPE_SPECIAL_POSITION: + { + bcatcstr(glsl, "gl_Position"); + break; + } + case OPERAND_TYPE_SPECIAL_FOG: + { + bcatcstr(glsl, "Fog"); + break; + } + case OPERAND_TYPE_SPECIAL_POINTSIZE: + { + bcatcstr(glsl, "gl_PointSize"); + break; + } + case OPERAND_TYPE_SPECIAL_ADDRESS: + { + bcatcstr(glsl, "Address"); + break; + } + case OPERAND_TYPE_SPECIAL_LOOPCOUNTER: + { + bcatcstr(glsl, "LoopCounter"); + pui32IgnoreSwizzle[0] = 1; + break; + } + case OPERAND_TYPE_SPECIAL_TEXCOORD: + { + bformata(glsl, "TexCoord%d", psOperand->ui32RegisterNumber); + break; + } + case OPERAND_TYPE_CONSTANT_BUFFER: + { + const char* StageName = "VS"; + ConstantBuffer* psCBuf = NULL; + ShaderVarType* psVarType = NULL; + int32_t index = -1; + GetConstantBufferFromBindingPoint(RGROUP_CBUFFER, psOperand->aui32ArraySizes[0], &psContext->psShader->sInfo, &psCBuf); + + switch(psContext->psShader->eShaderType) + { + case PIXEL_SHADER: + { + StageName = "PS"; + break; + } + case HULL_SHADER: + { + StageName = "HS"; + break; + } + case DOMAIN_SHADER: + { + StageName = "DS"; + break; + } + case GEOMETRY_SHADER: + { + StageName = "GS"; + break; + } + case COMPUTE_SHADER: + { + StageName = "CS"; + break; + } + default: + { + break; + } + } + + if(ui32TOFlag & TO_FLAG_DECLARATION_NAME) + { + pui32IgnoreSwizzle[0] = 1; + } + + if((psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT)!=HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT) + { + if(psCBuf) + { + //$Globals. + if(psCBuf->Name[0] == '$') + { + bformata(glsl, "Globals%s", StageName); + } + else + { + bformata(glsl, "%s%s", psCBuf->Name, StageName); + } + if((ui32TOFlag & TO_FLAG_DECLARATION_NAME) != TO_FLAG_DECLARATION_NAME) + { + bcatcstr(glsl, "."); + } + } + else + { + //bformata(glsl, "cb%d", psOperand->aui32ArraySizes[0]); + } + } + + if((ui32TOFlag & TO_FLAG_DECLARATION_NAME) != TO_FLAG_DECLARATION_NAME) + { + //Work out the variable name. Don't apply swizzle to that variable yet. + int32_t rebase = 0; + + if(psCBuf) + { + GetShaderVarFromOffset(psOperand->aui32ArraySizes[1], psOperand->aui32Swizzle, psCBuf, &psVarType, &index, &rebase); + + bformata(glsl, "%s", psVarType->FullName); + } + else // We don't have a semantic for this variable, so try the raw dump appoach. + { + bformata(glsl, "cb%d.data", psOperand->aui32ArraySizes[0]);// + index = psOperand->aui32ArraySizes[1]; + } + + //Dx9 only? + if(psOperand->psSubOperand[0] != NULL) + { + SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand->psSubOperand[0]); + if(eType != SVT_INT && eType != SVT_UINT) + { + bcatcstr(glsl, "[int("); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE); + bcatcstr(glsl, ")]"); + } + else + { + bcatcstr(glsl, "["); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE); + bcatcstr(glsl, "]"); + } + } + else + if(index != -1 && psOperand->psSubOperand[1] != NULL) + { + //Array of matrices is treated as array of vec4s + if(index != -1) + { + SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand->psSubOperand[1]); + if(eType != SVT_INT && eType != SVT_UINT) + { + bcatcstr(glsl, "[int("); + TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE); + bformata(glsl, ") + %d]", index); + } + else + { + bcatcstr(glsl, "["); + TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE); + bformata(glsl, " + %d]", index); + } + } + } + else if(index != -1) + { + bformata(glsl, "[%d]", index); + } + else if(psOperand->psSubOperand[1] != NULL) + { + SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand->psSubOperand[1]); + if(eType != SVT_INT && eType != SVT_UINT) + { + bcatcstr(glsl, "["); + TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE); + bcatcstr(glsl, "]"); + } + else + { + bcatcstr(glsl, "[int("); + TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE); + bcatcstr(glsl, ")]"); + } + } + + if(psVarType && psVarType->Class == SVC_VECTOR) + { + switch(rebase) + { + case 4: + { + if(psVarType->Columns == 2) + { + //.x(GLSL) is .y(HLSL). .y(GLSL) is .z(HLSL) + bcatcstr(glsl, ".xxyx"); + } + else if(psVarType->Columns == 3) + { + //.x(GLSL) is .y(HLSL). .y(GLSL) is .z(HLSL) .z(GLSL) is .w(HLSL) + bcatcstr(glsl, ".xxyz"); + } + break; + } + case 8: + { + if(psVarType->Columns == 2) + { + //.x(GLSL) is .z(HLSL). .y(GLSL) is .w(HLSL) + bcatcstr(glsl, ".xxxy"); + } + break; + } + case 0: + default: + { + //No rebase, but extend to vec4. + if(psVarType->Columns == 2) + { + bcatcstr(glsl, ".xyxx"); + } + else if(psVarType->Columns == 3) + { + bcatcstr(glsl, ".xyzx"); + } + break; + } + + } + } + + if(psVarType && psVarType->Class == SVC_SCALAR) + { + *pui32IgnoreSwizzle = 1; + } + } + break; + } + case OPERAND_TYPE_RESOURCE: + { + TextureName(psContext, psOperand->ui32RegisterNumber, 0); + *pui32IgnoreSwizzle = 1; + break; + } + case OPERAND_TYPE_SAMPLER: + { + bformata(glsl, "Sampler%d", psOperand->ui32RegisterNumber); + *pui32IgnoreSwizzle = 1; + break; + } + case OPERAND_TYPE_FUNCTION_BODY: + { + const uint32_t ui32FuncBody = psOperand->ui32RegisterNumber; + const uint32_t ui32FuncTable = psContext->psShader->aui32FuncBodyToFuncTable[ui32FuncBody]; + //const uint32_t ui32FuncPointer = psContext->psShader->aui32FuncTableToFuncPointer[ui32FuncTable]; + const uint32_t ui32ClassType = psContext->psShader->sInfo.aui32TableIDToTypeID[ui32FuncTable]; + const char* ClassTypeName = &psContext->psShader->sInfo.psClassTypes[ui32ClassType].Name[0]; + const uint32_t ui32UniqueClassFuncIndex = psContext->psShader->ui32NextClassFuncName[ui32ClassType]++; + + bformata(glsl, "%s_Func%d", ClassTypeName, ui32UniqueClassFuncIndex); + break; + } + case OPERAND_TYPE_INPUT_FORK_INSTANCE_ID: + { + bcatcstr(glsl, "forkInstanceID"); + *pui32IgnoreSwizzle = 1; + return; + } + case OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER: + { + bcatcstr(glsl, "immediateConstBufferF"); + + if(psOperand->psSubOperand[0]) + { + bcatcstr(glsl, "(int("); //Indexes must be integral. + TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE); + bcatcstr(glsl, "))"); + } + break; + } + case OPERAND_TYPE_INPUT_DOMAIN_POINT: + { + bcatcstr(glsl, "gl_TessCoord"); + break; + } + case OPERAND_TYPE_INPUT_CONTROL_POINT: + { + if(psOperand->aui32ArraySizes[1] == 0)//Input index zero - position. + { + bformata(glsl, "gl_in[%d].gl_Position", psOperand->aui32ArraySizes[0]); + } + else + { + bformata(glsl, "Input%d[%d]", psOperand->aui32ArraySizes[1], psOperand->aui32ArraySizes[0]); + } + break; + } + case OPERAND_TYPE_NULL: + { + // Null register, used to discard results of operations + bcatcstr(glsl, "//null"); + break; + } + case OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID: + { + bcatcstr(glsl, "gl_InvocationID"); + *pui32IgnoreSwizzle = 1; + break; + } + case OPERAND_TYPE_OUTPUT_COVERAGE_MASK: + { + bcatcstr(glsl, "gl_SampleMask[0]"); + *pui32IgnoreSwizzle = 1; + break; + } + case OPERAND_TYPE_INPUT_COVERAGE_MASK: + { + bcatcstr(glsl, "gl_SampleMaskIn[0]"); + //Skip swizzle on scalar types. + *pui32IgnoreSwizzle = 1; + break; + } + case OPERAND_TYPE_INPUT_THREAD_ID://SV_DispatchThreadID + { + bcatcstr(glsl, "gl_GlobalInvocationID"); + break; + } + case OPERAND_TYPE_INPUT_THREAD_GROUP_ID://SV_GroupThreadID + { + bcatcstr(glsl, "gl_LocalInvocationID"); + break; + } + case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP://SV_GroupID + { + bcatcstr(glsl, "gl_WorkGroupID"); + break; + } + case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED://SV_GroupIndex + { + bcatcstr(glsl, "gl_LocalInvocationIndex"); + break; + } + case OPERAND_TYPE_UNORDERED_ACCESS_VIEW: + { + bformata(glsl, "UAV%d", psOperand->ui32RegisterNumber); + break; + } + case OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY: + { + bformata(glsl, "TGSM%d", psOperand->ui32RegisterNumber); + *pui32IgnoreSwizzle = 1; + break; + } + case OPERAND_TYPE_INPUT_PRIMITIVEID: + { + bcatcstr(glsl, "gl_PrimitiveID"); + break; + } + case OPERAND_TYPE_INDEXABLE_TEMP: + { + bformata(glsl, "TempArray%d", psOperand->aui32ArraySizes[0]); + bformata(glsl, "[%d", psOperand->aui32ArraySizes[1]); + + if(psOperand->psSubOperand[1]) + { + bcatcstr(glsl, "+"); + TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE); + + } + bcatcstr(glsl, "]"); + break; + } + case OPERAND_TYPE_STREAM: + { + bformata(glsl, "%d", psOperand->ui32RegisterNumber); + break; + } + case OPERAND_TYPE_INPUT_GS_INSTANCE_ID: + { + bcatcstr(glsl, "gl_InvocationID"); + break; + } + case OPERAND_TYPE_THIS_POINTER: + { + /* + The "this" register is a register that provides up to 4 pieces of information: + X: Which CB holds the instance data + Y: Base element offset of the instance data within the instance CB + Z: Base sampler index + W: Base Texture index + + Can be different for each function call + */ + break; + } + default: + { + ASSERT(0); + break; + } + } + + if(integerConstructor) + { + bcatcstr(glsl, ")"); + } +} +SHADER_VARIABLE_TYPE GetOperandDataType(HLSLCrossCompilerContext* psContext, const Operand* psOperand) +{ + switch(psOperand->eType) + { + case OPERAND_TYPE_TEMP: + { + SHADER_VARIABLE_TYPE eCurrentType; + int i = 0; + + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE) + { + return psOperand->aeDataType[psOperand->aui32Swizzle[0]]; + } + if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE) + { + if(psOperand->ui32Swizzle == (NO_SWIZZLE)) + { + return psOperand->aeDataType[0]; + } + + return psOperand->aeDataType[psOperand->aui32Swizzle[0]]; + } + + if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE) + { + uint32_t ui32CompMask = psOperand->ui32CompMask; + if(!psOperand->ui32CompMask) + { + ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL; + } + for(;i<4;++i) + { + if(ui32CompMask & (1<aeDataType[i]; + break; + } + } + + #ifdef _DEBUG + //Check if all elements have the same basic type. + for(;i<4;++i) + { + if(psOperand->ui32CompMask & (1<aeDataType[i]) + { + ASSERT(0); + } + } + } + #endif + return eCurrentType; + } + + ASSERT(0); + + break; + } + case OPERAND_TYPE_OUTPUT: + { + const uint32_t ui32Register = psOperand->aui32ArraySizes[psOperand->iIndexDims-1]; + InOutSignature* psOut; + + if(GetOutputSignatureFromRegister(ui32Register, psOperand->ui32CompMask, 0, &psContext->psShader->sInfo, &psOut)) + { + if( psOut->eComponentType == INOUT_COMPONENT_UINT32) + { + return SVT_UINT; + } + else if( psOut->eComponentType == INOUT_COMPONENT_SINT32) + { + return SVT_INT; + } + } + break; + } + case OPERAND_TYPE_INPUT: + { + const uint32_t ui32Register = psOperand->aui32ArraySizes[psOperand->iIndexDims-1]; + InOutSignature* psIn; + + //UINT in DX, INT in GL. + if(psOperand->eSpecialName == NAME_PRIMITIVE_ID) + { + return SVT_INT; + } + + if(GetInputSignatureFromRegister(ui32Register, &psContext->psShader->sInfo, &psIn)) + { + if( psIn->eComponentType == INOUT_COMPONENT_UINT32) + { + return SVT_UINT; + } + else if( psIn->eComponentType == INOUT_COMPONENT_SINT32) + { + return SVT_INT; + } + } + break; + } + case OPERAND_TYPE_CONSTANT_BUFFER: + { + ConstantBuffer* psCBuf = NULL; + ShaderVarType* psVarType = NULL; + int32_t index = -1; + int32_t rebase = -1; + int foundVar; + GetConstantBufferFromBindingPoint(RGROUP_CBUFFER, psOperand->aui32ArraySizes[0], &psContext->psShader->sInfo, &psCBuf); + if(psCBuf) + { + foundVar = GetShaderVarFromOffset(psOperand->aui32ArraySizes[1], psOperand->aui32Swizzle, psCBuf, &psVarType, &index, &rebase); + if(foundVar && index == -1 && psOperand->psSubOperand[1] == NULL) + { + return psVarType->Type; + } + } + else + { + // Todo: this isn't correct yet. + return SVT_FLOAT; + } + break; + } + case OPERAND_TYPE_IMMEDIATE32: + { + return psOperand->iIntegerImmediate ? SVT_INT : SVT_FLOAT; + } + + case OPERAND_TYPE_INPUT_THREAD_ID: + case OPERAND_TYPE_INPUT_THREAD_GROUP_ID: + case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP: + case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED: + { + return SVT_UINT; + } + case OPERAND_TYPE_SPECIAL_ADDRESS: + { + return SVT_INT; + } + default: + { + return SVT_FLOAT; + } + } + + return SVT_FLOAT; +} + +void TranslateOperand(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag) +{ + bstring glsl = *psContext->currentGLSLString; + uint32_t ui32IgnoreSwizzle = 0; + + if(ui32TOFlag & TO_FLAG_NAME_ONLY) + { + TranslateVariableName(psContext, psOperand, ui32TOFlag, &ui32IgnoreSwizzle); + return; + } + + switch(psOperand->eModifier) + { + case OPERAND_MODIFIER_NONE: + { + break; + } + case OPERAND_MODIFIER_NEG: + { + bcatcstr(glsl, "-"); + break; + } + case OPERAND_MODIFIER_ABS: + { + bcatcstr(glsl, "abs("); + break; + } + case OPERAND_MODIFIER_ABSNEG: + { + bcatcstr(glsl, "-abs("); + break; + } + } + + TranslateVariableName(psContext, psOperand, ui32TOFlag, &ui32IgnoreSwizzle); + + if(!ui32IgnoreSwizzle) + { + TranslateOperandSwizzle(psContext, psOperand); + } + + switch(psOperand->eModifier) + { + case OPERAND_MODIFIER_NONE: + { + break; + } + case OPERAND_MODIFIER_NEG: + { + break; + } + case OPERAND_MODIFIER_ABS: + { + bcatcstr(glsl, ")"); + break; + } + case OPERAND_MODIFIER_ABSNEG: + { + bcatcstr(glsl, ")"); + break; + } + } +} + +void TextureName(HLSLCrossCompilerContext* psContext, const uint32_t ui32RegisterNumber, const int bZCompare) +{ + bstring glsl = *psContext->currentGLSLString; + ResourceBinding* psBinding = 0; + int found; + + found = GetResourceFromBindingPoint(RGROUP_TEXTURE, ui32RegisterNumber, &psContext->psShader->sInfo, &psBinding); + + if(bZCompare) + { + bcatcstr(glsl, "hlslcc_zcmp"); + } + + if(found) + { + int i = 0; + char name[MAX_REFLECT_STRING_LENGTH]; + uint32_t ui32ArrayOffset = ui32RegisterNumber - psBinding->ui32BindPoint; + + while(psBinding->Name[i] != '\0' && i < (MAX_REFLECT_STRING_LENGTH-1)) + { + name[i] = psBinding->Name[i]; + + //array syntax [X] becomes _0_ + //Otherwise declarations could end up as: + //uniform sampler2D SomeTextures[0]; + //uniform sampler2D SomeTextures[1]; + if(name[i] == '[' || name[i] == ']') + name[i] = '_'; + + ++i; + } + + name[i] = '\0'; + + if(ui32ArrayOffset) + { + bformata(glsl, "%s%d", name, ui32ArrayOffset); + } + else + { + bformata(glsl, "%s", name); + } + } + else + { + bformata(glsl, "UnknownResource%d", ui32RegisterNumber); + } +} diff --git a/build/tools/ShaderBuildTool/ShaderBuildTool.cpp b/build/tools/ShaderBuildTool/ShaderBuildTool.cpp new file mode 100644 index 0000000..f30f9f9 --- /dev/null +++ b/build/tools/ShaderBuildTool/ShaderBuildTool.cpp @@ -0,0 +1,388 @@ +// ShaderBuildTool.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include +#include +#include +#include +#include +#include + +#define PERMUTATION_KEYWORD "#permutation " +#define SEPARATORS " \n" +#define INDENT " " + +namespace +{ + struct CShaderPermutation + { + std::string Key; + std::vector Values; + }; + + struct CShaderDefine + { + std::string Key; + std::string Value; + }; + + struct CShaderInstance + { + std::string GlobalVariableName; + std::vector Defines; + }; + + typedef std::vector CShaderInstances; + typedef std::vector CShaderPermutations; +}; + +FILE *OpenFile(std::string Path, const char* Mode) +{ + FILE *fp = NULL; + if (fopen_s(&fp, Path.c_str(), Mode) || !fp) + { + fprintf(stderr, "Failed to open file %s\n", Path.c_str()); + exit(1); + } + return fp; +} + +CShaderInstances ExpandShaderInstances(CShaderInstances In, CShaderPermutation Permutation) +{ + CShaderInstances Out; + for (unsigned int InstanceIndex = 0; InstanceIndex < In.size(); ++InstanceIndex) + { + for (unsigned int ValueIndex = 0; ValueIndex < Permutation.Values.size(); ++ValueIndex) + { + CShaderDefine D; + D.Key = Permutation.Key; + D.Value = Permutation.Values[ValueIndex]; + + CShaderInstance Tmp = In[InstanceIndex]; + Tmp.Defines.push_back(D); + Out.push_back(Tmp); + } + } + + return Out; +} + +void MySystem(const char *Command) +{ + //printf("%s\n", Command); + + if (system(Command) != 0) + { + fprintf(stderr, "Failed command: %s\n", Command); + exit(1); + } +} + +struct CArgs +{ + std::string Profile; + std::string Input; + std::string EntryPoint; + std::string OutputDir; + std::string Output_H; + std::string Output_CPP; + std::string CompileTool; + std::string API; + std::string ClassName; +}; + +void ParseInput( + const CArgs& Args, + CShaderPermutations& ShaderPermutations) +{ + FILE *fp = OpenFile(Args.Input, "r"); + + char row[1024]; + while (fgets(row, sizeof(row), fp)) + { + if (strncmp(row, PERMUTATION_KEYWORD, strlen(PERMUTATION_KEYWORD)) == 0) + { + char *Keyword = strtok(row, SEPARATORS); + char *DefineKey = strtok(NULL, SEPARATORS); + if (!DefineKey) break; + + CShaderPermutation P; + P.Key = DefineKey; + + while (1) + { + char *DefineValue = strtok(NULL, SEPARATORS); + if (!DefineValue) break; + + P.Values.push_back(DefineValue); + } + + ShaderPermutations.push_back(P); + } + } + + fclose(fp); +} + +void InitShaderInstances( + const CShaderPermutations& ShaderPermutations, + CShaderInstances& ShaderInstances + ) +{ + ShaderInstances.clear(); + ShaderInstances.push_back(CShaderInstance()); + + for (unsigned int PermutationIndex = 0; PermutationIndex < ShaderPermutations.size(); ++PermutationIndex) + { + CShaderPermutation P = ShaderPermutations[PermutationIndex]; + ShaderInstances = ExpandShaderInstances(ShaderInstances, P); + } +} + +void WriteCPP( + const CArgs& Args, + const CShaderPermutations& ShaderPermutations, + CShaderInstances& ShaderInstances) +{ + remove(Args.Output_CPP.c_str()); + + for (unsigned int InstanceIndex = 0; InstanceIndex < ShaderInstances.size(); ++InstanceIndex) + { + CShaderInstance& Instance = ShaderInstances[InstanceIndex]; + std::string DefineString = "/DAPI_" + Args.API + "=1"; + std::string ShaderName = Args.EntryPoint; + + for (unsigned int i = 0; i < ShaderInstances[i].Defines.size(); ++i) + { + DefineString += " /D" + Instance.Defines[i].Key + "=" + Instance.Defines[i].Value; + ShaderName += "_" + Instance.Defines[i].Key + "_" + Instance.Defines[i].Value; + } + + Instance.GlobalVariableName = "g_" + ShaderName + "_" + Args.API; + + std::string OutputTmp = Args.Output_CPP + ".tmp"; + std::string Command; + Command += "SET SBT_PROFILE=" + Args.Profile; + Command += "& SET SBT_INPUT=" + Args.Input; + Command += "& SET SBT_ENTRY_POINT=" + Args.EntryPoint; + Command += "& SET SBT_DEFINES=" + DefineString; + Command += "& SET SBT_VARIABLE_NAME=" + Instance.GlobalVariableName; + Command += "& SET SBT_OUTPUT=" + OutputTmp; + Command += "& " + Args.CompileTool; + MySystem(Command.c_str()); + + Command = "type " + OutputTmp + " >> " + Args.Output_CPP; + MySystem(Command.c_str()); + + Command = "del " + OutputTmp; + MySystem(Command.c_str()); + } + + FILE *fp = OpenFile(Args.Output_CPP, "a+"); + + fprintf(fp, "\n"); + fprintf(fp, "namespace Generated\n"); + fprintf(fp, "{\n"); + + fprintf(fp, INDENT "void %s::Create(DevicePointer Device)\n", Args.EntryPoint.c_str()); + fprintf(fp, INDENT "{\n"); + for (unsigned int i = 0; i < ShaderInstances.size(); ++i) + { + CShaderInstance Instance = ShaderInstances[i]; + + fprintf(fp, INDENT INDENT "m_Shader"); + for (unsigned int j = 0; j < Instance.Defines.size(); ++j) + { + fprintf(fp, "[ShaderPermutations::%s", Instance.Defines[j].Key.c_str()); + fprintf(fp, "_%s]", Instance.Defines[j].Value.c_str()); + } + fprintf(fp, ".Create(Device, %s, sizeof(%s));\n", Instance.GlobalVariableName.c_str(), Instance.GlobalVariableName.c_str()); + } + fprintf(fp, INDENT "}\n"); + fprintf(fp, "\n"); + + fprintf(fp, INDENT "void %s::Release(DevicePointer Device)\n", Args.EntryPoint.c_str()); + fprintf(fp, INDENT "{\n"); + for (unsigned int i = 0; i < ShaderInstances.size(); ++i) + { + fprintf(fp, INDENT INDENT "m_Shader"); + CShaderInstance Instance = ShaderInstances[i]; + for (unsigned int j = 0; j < Instance.Defines.size(); ++j) + { + fprintf(fp, "[ShaderPermutations::%s", Instance.Defines[j].Key.c_str()); + fprintf(fp, "_%s]", Instance.Defines[j].Value.c_str()); + } + fprintf(fp, ".Release(Device);\n"); + } + fprintf(fp, INDENT "}\n"); + + fprintf(fp, "}\n"); + + fclose(fp); +} + +void WriteHeader( + const CArgs& Args, + const CShaderPermutations& ShaderPermutations, + const CShaderInstances& ShaderInstances) +{ + remove(Args.Output_H.c_str()); + + std::string ClassName = Args.ClassName; + + FILE *fp = OpenFile(Args.Output_H, "a+"); + + fprintf(fp, "//! This file was auto-generated. Do not modify manually.\n"); + fprintf(fp, "#pragma once"); + fprintf(fp, "\n"); + + fprintf(fp, "\n"); + fprintf(fp, "namespace Generated\n"); + fprintf(fp, "{\n"); + fprintf(fp, "\n"); + + fprintf(fp, "namespace ShaderPermutations\n"); + fprintf(fp, "{\n"); + fprintf(fp, "\n"); + + for (unsigned int i = 0; i < ShaderPermutations.size(); ++i) + { + const CShaderPermutation& Permutation = ShaderPermutations[i]; + + std::string PermutationDefine = Permutation.Key + "_DEFINED"; + fprintf(fp, "#ifndef %s\n", PermutationDefine.c_str()); + fprintf(fp, "#define %s\n", PermutationDefine.c_str()); + + fprintf(fp, INDENT "enum %s\n", Permutation.Key.c_str()); + fprintf(fp, INDENT "{\n"); + for (unsigned int j = 0; j < Permutation.Values.size(); ++j) + { + fprintf(fp, INDENT INDENT "%s_%s,\n", Permutation.Key.c_str(), Permutation.Values[j].c_str()); + } + fprintf(fp, INDENT INDENT "%s_COUNT,\n", Permutation.Key.c_str()); + fprintf(fp, INDENT "};\n"); + + fprintf(fp, "#endif\n"); + fprintf(fp, "\n"); + } + + fprintf(fp, "};\n"); + fprintf(fp, "\n"); + + fprintf(fp, "struct %s\n", Args.EntryPoint.c_str()); + fprintf(fp, "{\n"); + + fprintf(fp, INDENT "void Create(DevicePointer Device);\n"); + fprintf(fp, INDENT "void Release(DevicePointer Device);\n"); + + fprintf(fp, INDENT "%s& Get(", ClassName.c_str()); + for (unsigned int i = 0; i < ShaderPermutations.size(); ++i) + { + if (i != 0) + { + fprintf(fp, ", "); + } + fprintf(fp, "ShaderPermutations::%s %c", ShaderPermutations[i].Key.c_str(), 'A' + i); + } + fprintf(fp, ")\n"); + fprintf(fp, INDENT "{\n"); + fprintf(fp, INDENT INDENT "return m_Shader"); + for (unsigned int i = 0; i < ShaderPermutations.size(); ++i) + { + fprintf(fp, "[%c]", 'A' + i); + } + fprintf(fp, ";\n"); + fprintf(fp, INDENT "}\n"); + + fprintf(fp, "\n"); + fprintf(fp, "private:\n"); + + fprintf(fp, INDENT "%s m_Shader", ClassName.c_str()); + for (unsigned int i = 0; i < ShaderPermutations.size(); ++i) + { + fprintf(fp, "[ShaderPermutations::%s_COUNT]", ShaderPermutations[i].Key.c_str()); + } + fprintf(fp, ";\n"); + + fprintf(fp, "#if _WIN32\n"); + for (unsigned int i = 0; i < ShaderPermutations.size(); ++i) + { + fprintf(fp, INDENT "static_assert(ShaderPermutations::%s_COUNT == %d, \"\");\n", + ShaderPermutations[i].Key.c_str(), + (int) ShaderPermutations[i].Values.size()); + } + fprintf(fp, "#endif\n"); + + fprintf(fp, "};\n"); + fprintf(fp, "\n"); + + fprintf(fp, "};\n"); + + fclose(fp); +} + +int main(int argc, char **argv) +{ + if (argc < 7) + { + fprintf(stderr, "Usage: %s PROFILE INPUT_HLSL ENTRY_POINT OUTPUT_DIR COMPILE_TOOL API [CLASS_NAME]\n", argv[0]); + exit(1); + } + + CArgs Args; + int ArgIndex = 1; + if (ArgIndex < argc) + { + Args.Profile = argv[ArgIndex++]; + } + if (ArgIndex < argc) + { + Args.Input = argv[ArgIndex++]; + } + if (ArgIndex < argc) + { + Args.EntryPoint = argv[ArgIndex++]; + } + if (ArgIndex < argc) + { + Args.OutputDir = argv[ArgIndex++]; + } + if (ArgIndex < argc) + { + Args.CompileTool = argv[ArgIndex++]; + } + if (ArgIndex < argc) + { + Args.API = argv[ArgIndex++]; + } + if (ArgIndex < argc) + { + Args.ClassName = argv[ArgIndex++]; + } + + if (Args.ClassName.size() == 0) + { + const bool IsVS = !strcmp(Args.Profile.c_str(), "vs_5_0"); + const bool IsGS = !strcmp(Args.Profile.c_str(), "gs_5_0"); + Args.ClassName = + IsVS ? "VertexShader" : + IsGS ? "GeometryShader" : + "PixelShader"; + } + + CShaderPermutations ShaderPermutations; + ParseInput(Args, ShaderPermutations); + + Args.Output_H = Args.OutputDir + "\\" + Args.EntryPoint + ".h"; + Args.Output_CPP = Args.OutputDir + "\\" + Args.EntryPoint + ".cpp"; + + CShaderInstances ShaderInstances; + InitShaderInstances(ShaderPermutations, ShaderInstances); + + WriteHeader(Args, ShaderPermutations, ShaderInstances); + + WriteCPP(Args, ShaderPermutations, ShaderInstances); + + return 0; +} diff --git a/build/tools/ShaderBuildTool/ShaderBuildTool.sln b/build/tools/ShaderBuildTool/ShaderBuildTool.sln new file mode 100644 index 0000000..9ca8bfc --- /dev/null +++ b/build/tools/ShaderBuildTool/ShaderBuildTool.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShaderBuildTool", "ShaderBuildTool.vcxproj", "{438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x64.ActiveCfg = Debug|x64 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x64.Build.0 = Debug|x64 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x86.ActiveCfg = Debug|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Debug|x86.Build.0 = Debug|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x64.ActiveCfg = Release|x64 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x64.Build.0 = Release|x64 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x86.ActiveCfg = Release|Win32 + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj b/build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj new file mode 100644 index 0000000..4976c48 --- /dev/null +++ b/build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {438B73C1-A960-4F8E-B23C-DB6E3AEBC0DE} + Win32Proj + ShaderBuildTool + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)..\..\..\src\shaders\ + + + true + + + false + $(SolutionDir)..\..\..\src\shaders\ + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + _CRT_NONSTDC_NO_WARNING;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + + + Console + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreaded + + + Console + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + _CRT_NONSTDC_NO_WARNING;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreaded + + + Console + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj.filters b/build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj.filters new file mode 100644 index 0000000..fe9d0e0 --- /dev/null +++ b/build/tools/ShaderBuildTool/ShaderBuildTool.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/build/tools/ShaderBuildTool/stdafx.cpp b/build/tools/ShaderBuildTool/stdafx.cpp new file mode 100644 index 0000000..fa5ec19 --- /dev/null +++ b/build/tools/ShaderBuildTool/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// ShaderBuildTool.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/build/tools/ShaderBuildTool/stdafx.h b/build/tools/ShaderBuildTool/stdafx.h new file mode 100644 index 0000000..35c5878 --- /dev/null +++ b/build/tools/ShaderBuildTool/stdafx.h @@ -0,0 +1,19 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "targetver.h" + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/build/tools/ShaderBuildTool/targetver.h b/build/tools/ShaderBuildTool/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/build/tools/ShaderBuildTool/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/build/tools/Stringify/Stringify.cpp b/build/tools/Stringify/Stringify.cpp new file mode 100644 index 0000000..ea3fe68 --- /dev/null +++ b/build/tools/Stringify/Stringify.cpp @@ -0,0 +1,49 @@ +// Stringify.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +int main(int argc, char* argv[]) +{ + if (argc != 4) + { + fprintf(stderr, "Usage: %s TEXT_FILENAME VARIABLE_NAME OUTPUT_FILE\n", argv[0]); + exit(1); + } + + const char* pFilenameIn = argv[1]; + const char* pVariableName = argv[2]; + const char *pFilenameOut = argv[3]; + + FILE *fpIn = fopen(pFilenameIn, "r"); + if (!fpIn) + { + fprintf(stderr, "Error: Failed to open %s\n", pFilenameIn); + exit(1); + } + + FILE *fpOut = fopen(pFilenameOut, "w"); + if (!fpOut) + { + fprintf(stderr, "Error: Failed to open %s\n", pFilenameOut); + exit(1); + } + + fprintf(fpOut, "static const char* %s =\n", pVariableName); + + char row[1024]; + while (fgets(row, sizeof(row), fpIn)) + { + row[strlen(row) - 1] = 0; // remove \n + + fprintf(fpOut, "\"%s\\n\"\n", row); + } + + fprintf(fpOut, ";\n"); + + fclose(fpIn); + fclose(fpOut); + return 0; +} + diff --git a/build/tools/Stringify/Stringify.sln b/build/tools/Stringify/Stringify.sln new file mode 100644 index 0000000..d11dcad --- /dev/null +++ b/build/tools/Stringify/Stringify.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Stringify", "Stringify\Stringify.vcxproj", "{199AEFC4-A2BC-4837-9D0D-69BEB794F681}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {199AEFC4-A2BC-4837-9D0D-69BEB794F681}.Debug|Win32.ActiveCfg = Debug|Win32 + {199AEFC4-A2BC-4837-9D0D-69BEB794F681}.Debug|Win32.Build.0 = Debug|Win32 + {199AEFC4-A2BC-4837-9D0D-69BEB794F681}.Release|Win32.ActiveCfg = Release|Win32 + {199AEFC4-A2BC-4837-9D0D-69BEB794F681}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/tools/Stringify/Stringify.vcxproj b/build/tools/Stringify/Stringify.vcxproj new file mode 100644 index 0000000..245cf4e --- /dev/null +++ b/build/tools/Stringify/Stringify.vcxproj @@ -0,0 +1,93 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {199AEFC4-A2BC-4837-9D0D-69BEB794F681} + Win32Proj + Stringify + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + true + $(SolutionDir)..\..\..\src\shaders\ + + + false + $(SolutionDir)..\..\..\src\shaders\ + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + Create + Create + + + + + + + \ No newline at end of file diff --git a/build/tools/Stringify/Stringify.vcxproj.filters b/build/tools/Stringify/Stringify.vcxproj.filters new file mode 100644 index 0000000..7827edd --- /dev/null +++ b/build/tools/Stringify/Stringify.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/build/tools/Stringify/stdafx.cpp b/build/tools/Stringify/stdafx.cpp new file mode 100644 index 0000000..6586fa8 --- /dev/null +++ b/build/tools/Stringify/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// Stringify.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/build/tools/Stringify/stdafx.h b/build/tools/Stringify/stdafx.h new file mode 100644 index 0000000..946f86c --- /dev/null +++ b/build/tools/Stringify/stdafx.h @@ -0,0 +1,19 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "targetver.h" + +#include +#include +#include + + +// TODO: reference additional headers your program requires here diff --git a/build/tools/Stringify/targetver.h b/build/tools/Stringify/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/build/tools/Stringify/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/doc/.buildinfo b/doc/.buildinfo new file mode 100644 index 0000000..5a19ffe --- /dev/null +++ b/doc/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: dc68e4490eb1fe0304cc688a6f2ca6f1 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/doc/_images/AOBias_0_0.png b/doc/_images/AOBias_0_0.png new file mode 100644 index 0000000..1e049c0 Binary files /dev/null and b/doc/_images/AOBias_0_0.png differ diff --git a/doc/_images/AOBias_0_3.png b/doc/_images/AOBias_0_3.png new file mode 100644 index 0000000..e9f0cb2 Binary files /dev/null and b/doc/_images/AOBias_0_3.png differ diff --git a/doc/_images/AO_Radius_1.png b/doc/_images/AO_Radius_1.png new file mode 100644 index 0000000..9e66615 Binary files /dev/null and b/doc/_images/AO_Radius_1.png differ diff --git a/doc/_images/AO_Radius_4.png b/doc/_images/AO_Radius_4.png new file mode 100644 index 0000000..c4bbd92 Binary files /dev/null and b/doc/_images/AO_Radius_4.png differ diff --git a/doc/_images/BackgroundAO_OFF.png b/doc/_images/BackgroundAO_OFF.png new file mode 100644 index 0000000..91e3452 Binary files /dev/null and b/doc/_images/BackgroundAO_OFF.png differ diff --git a/doc/_images/BackgroundAO_ON.png b/doc/_images/BackgroundAO_ON.png new file mode 100644 index 0000000..19d9f7a Binary files /dev/null and b/doc/_images/BackgroundAO_ON.png differ diff --git a/doc/_images/Blur_Radius_4.png b/doc/_images/Blur_Radius_4.png new file mode 100644 index 0000000..0b3f134 Binary files /dev/null and b/doc/_images/Blur_Radius_4.png differ diff --git a/doc/_images/Blur_Sharpness_0.png b/doc/_images/Blur_Sharpness_0.png new file mode 100644 index 0000000..84acbda Binary files /dev/null and b/doc/_images/Blur_Sharpness_0.png differ diff --git a/doc/_images/Blur_Sharpness_8.png b/doc/_images/Blur_Sharpness_8.png new file mode 100644 index 0000000..abba7a8 Binary files /dev/null and b/doc/_images/Blur_Sharpness_8.png differ diff --git a/doc/_images/ForegroundAO_OFF.png b/doc/_images/ForegroundAO_OFF.png new file mode 100644 index 0000000..a78be1a Binary files /dev/null and b/doc/_images/ForegroundAO_OFF.png differ diff --git a/doc/_images/ForegroundAO_ON.png b/doc/_images/ForegroundAO_ON.png new file mode 100644 index 0000000..396ce3c Binary files /dev/null and b/doc/_images/ForegroundAO_ON.png differ diff --git a/doc/_images/No_Blur.png b/doc/_images/No_Blur.png new file mode 100644 index 0000000..eb3b8ac Binary files /dev/null and b/doc/_images/No_Blur.png differ diff --git a/doc/_images/hbao-plus-in-tom-clancys-splinter-cell-blacklist-2.jpg b/doc/_images/hbao-plus-in-tom-clancys-splinter-cell-blacklist-2.jpg new file mode 100644 index 0000000..99c9324 Binary files /dev/null and b/doc/_images/hbao-plus-in-tom-clancys-splinter-cell-blacklist-2.jpg differ diff --git a/doc/_images/pipeline_with_input_normals.png b/doc/_images/pipeline_with_input_normals.png new file mode 100644 index 0000000..6e1a3b8 Binary files /dev/null and b/doc/_images/pipeline_with_input_normals.png differ diff --git a/doc/_images/pipeline_without_input_normals.png b/doc/_images/pipeline_without_input_normals.png new file mode 100644 index 0000000..665f7b1 Binary files /dev/null and b/doc/_images/pipeline_without_input_normals.png differ diff --git a/doc/_sources/changelog.txt b/doc/_sources/changelog.txt new file mode 100644 index 0000000..9ba95ec --- /dev/null +++ b/doc/_sources/changelog.txt @@ -0,0 +1,95 @@ + +Change Log +======================================= + +|PRODUCTNAMEDOCRELEASEBOLD| + +**New in release 3.0** + +* Added entry points for D3D12. +* Now shipping separate DLLs and LIB files for D3D11 and GL. +* Replaced the DetailAO & CoarseAO parameters with NearAO & FarAO. +* Replaced pointers with references in the API. +* Added the ForegroundAO & BackgroundAO parameters. +* Added per-component debug-normal visualization modes in GFSDK_SSAO_RenderMask. +* Added support for two-pass AO blending + depth-stencil masking. +* Removed the BLUR_RADIUS_8 mode (BLUR_RADIUS_4 looks better in general, and runs faster). +* Removed the PER_SAMPLE_AO MSAA mode. + +**New in release 2.4** + +* Added support for Mac OS X. +* Added the DepthClampMode parameter. +* Added the GFSDK_SSAO_GetVersion function. +* The input viewport and matrices are now passed by value instead of by pointer. +* The input viewport parameter is now optional. By default, a full-resolution viewport is used. + +**New in release 2.3** + +* The input normal data are now passed by value instead of by pointer (less error prone). +* Removed the INVALID_VIEWPORT_DIMENSIONS error code. Input viewports larger than the input textures are now supported. +* Added support for MSAA input VIEW_DEPTHS for DX11 and GL. +* Added support for VIEW_DEPTHS with partial input viewports for DX11. +* Added the DepthStorage parameter in GFSDK_SSAO_Parameters. + +**New in release 2.2** + +* GL: The RenderAO call now saves & restores all the relevant GL states it alters internally. +* GL: Added the GFSDK_SSAO_GLFunctions argument to GFSDK_SSAO_CreateContext_GL. +* GL: Added support for MSAA input textures. +* The GFSDK_SSAO_DRAW_DEBUG_N mode now outputs float4(-InternalViewNormal.xyz, 0). +* Changed the blur weights of BLUR_RADIUS_2 and BLUR_RADIUS_4 to support larger sharpness values. + +**New in release 2.1** + +* Optimize the case of Params.DetailAO == 0.f and Input.pNormalData != NULL. +* Added a parameter to control the sharpness of the optional GFSDK_SSAO_DepthThreshold. +* GL: Added quality/performance parameters in GFSDK_SSAO_Parameters_GL. + +**New in release 2.0** + +* Added entry points for OpenGL 3.2. +* Added support for non-zero input viewport origins. +* Added the GFSDK_SSAO_BLUR_RADIUS_2 mode. + +**New in release 1.5** + +* Renamed the SceneScale parameter to MetersToViewSpaceUnits. +* Added the GFSDK_SSAO_HARDWARE_DEPTHS_SUB_RANGE depth-texture type. +* Added option to supersample the AO when using MSAA input and output textures (GFSDK_SSAO_PER_SAMPLE_AO). +* Added PreCreateRenderTargets entry point (optional). + +**New in release 1.4** + +* Added error codes: GFSDK_SSAO_INVALID_VIEWPORT_DEPTH_RANGE and GFSDK_SSAO_UNSUPPORTED_VIEWPORT_DIMENSIONS. +* Removed the GFSDK_SSAO_PERFORMANCE mode. + +**New in release 1.3** + +* Moved the API to a class interface. +* Added an optional SSAO_DepthThreshold parameter, to hide potential z-buffer precision artifacts. +* Added support for input-texture dimensions being larger than the viewport dimensions. +* Added GFSDK_SSAO_BlurRadius option. +* Added GFSDK_SSAO_BlurSharpnessProfile option. +* Added GFSDK_SSAO_GPUConfiguration option. + +**New in release 1.2** + +* Merged the SetInputDepths and SetInputNormals functions into a single SetInputData. +* Removed the SetParameters function. The parameters are now passed as an argument to RenderAO. +* Let the user specify a BlendState for compositing the AO to the OutputRTV. See CustomBlendState. +* Added a normal-visualization debug mode: by calling RenderAO with RenderMask = RENDER_DEBUG_NORMAL_Z. +* Added a GetBuildString function. + +.. ----------------------- + +.. * `Forums`_ + +.. * `Report a bug`_ + +.. If links above are used, replace URL below. +.. _Forums: http://devtalk.nvidia.com +.. _Report a bug: http://developer.nvidia.com/contact + +.. toctree:: + :maxdepth: 1 diff --git a/doc/_sources/index.txt b/doc/_sources/index.txt new file mode 100644 index 0000000..72d68c0 --- /dev/null +++ b/doc/_sources/index.txt @@ -0,0 +1,37 @@ +.. Replace existing content with product specific content. Layout for this page should be consistent for all products. + Use the root `toctree` directive to include documents + +|PRODUCTNAME| +====================================== + +.. Replace the content. Layout should not change + +NVIDIA ShadowWorks - HBAO+ improves upon existing Ambient Occlusion techniques to add richer, more detailed, more realistic shadows around objects that occlude rays of light. Compared to previous techniques, HBAO+ is faster, more efficient, and significantly better. + + +Learn more about |PRODUCTNAME| +------------------------------ +* Visit the `product home page`_ on `NVIDIA Developer`_ + +* View Documentation :ref:`search` + +.. Other links to highlight: +.. Link to archived docs +.. Any other archived (version-specific) docs can be linked here as well. + +**Browse Documentation** + +.. toctree:: + :maxdepth: 1 + + product + changelog +.. releasenotes + +.. Reference only product TOT pages here. +.. productOld +.. productOlder + + + + diff --git a/doc/_sources/product.txt b/doc/_sources/product.txt new file mode 100644 index 0000000..b923912 --- /dev/null +++ b/doc/_sources/product.txt @@ -0,0 +1,294 @@ +.. Replace existing content with product specific content. Layout for this page should be consistent for all products. + +|PRODUCTNAME| |VERSION| +====================================== + +.. Replace the content. Layout should not change + +Overview +############## +HBAO+ is a SSAO algorithm designed to achieve high GPU efficiency. +The algorithm is based on HBAO [Bavoil and Sainz 2008], with the following differences: + +#. To minimize cache trashing, HBAO+ does not use any randomization texture. Instead, the algorithm uses an Interleaved Rendering approach, generating the AO in multiple passes with a unique jitter value per pass [Bavoil and Jansen 2013]. + +#. To avoid over-occlusion artifacts, HBAO+ uses a simpler AO approximation than HBAO, similar to "Scalable Ambient Obscurance" [McGuire et al. 2012] [Bukowski et al. 2012]. + +#. To minimize flickering, the HBAO+ is always rendered in full resolution, from full-resolution depths. + + +.. image:: \_static\hbao-plus-in-tom-clancys-splinter-cell-blacklist-2.jpg + +Package +############## + +``doc/``\—this documentation page. + +``lib/``\—header file, import libraries and DLLs, for Win32, Win64, Mac OS X and Linux. + +``samples/``\—source for sample applications demonstrating NVIDIA HBAO+. + +Getting Started +############### + +#. INITIALIZE THE LIBRARY:: + + GFSDK_SSAO_CustomHeap CustomHeap; + CustomHeap.new_ = ::operator new; + CustomHeap.delete_ = ::operator delete; + + GFSDK_SSAO_Status status; + GFSDK_SSAO_Context_D3D11* pAOContext; + status = GFSDK_SSAO_CreateContext_D3D11(pD3D11Device, &pAOContext, &CustomHeap); + assert(status == GFSDK_SSAO_OK); // HBAO+ requires feature level 11_0 or above + +#. SET INPUT DEPTHS:: + + GFSDK_SSAO_InputData_D3D11 Input; + Input.DepthData.DepthTextureType = GFSDK_SSAO_HARDWARE_DEPTHS; + Input.DepthData.pFullResDepthTextureSRV = pDepthStencilTextureSRV; + Input.DepthData.ProjectionMatrix.Data = GFSDK_SSAO_Float4x4(pProjectionMatrix); + Input.DepthData.ProjectionMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER; + Input.DepthData.MetersToViewSpaceUnits = SceneScale; + +#. SET AO PARAMETERS:: + + GFSDK_SSAO_Parameters_D3D11 Params; + Params.Radius = 2.f; + Params.Bias = 0.1f; + Params.PowerExponent = 2.f; + Params.Blur.Enable = true; + Params.Blur.Radius = GFSDK_SSAO_BLUR_RADIUS_4; + Params.Blur.Sharpness = 16.f; + +#. SET RENDER TARGET:: + + GFSDK_SSAO_Output_D3D11 Output; + Output.pRenderTargetView = pOutputColorRTV; + Output.Blend.Mode = GFSDK_SSAO_OVERWRITE_RGB; + +#. RENDER AO:: + + status = pAOContext->RenderAO(pD3D11Context, Input, Params, Output); + assert(status == GFSDK_SSAO_OK); + +Data Flow +############# + +Input Requirements +++++++++++++++++++++ + +* The library has entry points for D3D11, D3D12 and GL3.2+. + +* Requires a depth texture to be provided as input, along with associated projection info. + +* Optionally, can also take as input a GBuffer normal texture associated with the input depth texture: + + * Can add normal-mapping details to the AO. + + * Can be used to fix normal reconstruction artifacts with dithered LOD dissolves. + + * But makes the integration more complex. We recommend starting with input normals disabled. + +* Optionally, can also take as input a viewport rectangle associated with the input textures: + + * Defines a sub-area of the input & output full-resolution textures to be sourced and rendered to. + + * The library re-allocates its internal render targets if the Viewport.Width or Viewport.Height changes for a given AO context. + +MSAA Support +++++++++++++++++++++ + +* Requirements + + * The input depth & normal textures are required to have matching dimensions and MSAA sample count. + + * The output render target can have arbitrary dimensions and MSAA sample count. + +* Per-Pixel AO Algorithm + + * If the input textures are MSAA, only sample 0 is used to render the AO. + + * If the output render target is MSAA, a per-pixel AO value is written to all samples. + + * In practice, we have found this strategy to not cause any objectionable artifacts, even when using HBAO+ with TXAA. + +HBAO+ Pipeline +++++++++++++++++++++ + +.. image:: \_static\pipeline_without_input_normals.png + +.. image:: \_static\pipeline_with_input_normals.png + +Occlusion Samples +++++++++++++++++++++ + +* For each pixel, 32 occlusion samples are taken in a variable-radius disk, with a minimum of 4 full-resolution pixels between the center pixel and the sample coordinates. + +* The 8 nearest samples to the center pixel are weighted by the NearAO parameter. + +* The other samples are weighted by the FarAO parameter. + +Parameters +########## + +AO Radius +++++++++++++++++++++ + +Definition + For a given AO receiver point P and AO Radius R, sample point S is ignored if ||P-S|| > R + +Impact on search area + The AO radius is a multiplier for the screen-space search radius, and the number of samples is fixed. So if the AO radius is too large, under-sampling artifacts may appear. + +.. image:: \_static\AO_Radius_1.png + +.. image:: \_static\AO_Radius_4.png + +MetersToViewSpaceUnits +++++++++++++++++++++++++++++++++++ + +If you are not sure what to set this value to, you can: + +* Set the ``AO Radius`` parameter to 1.0 and + +* Increase ``MetersToViewSpaceUnits`` until the AO looks like it's being cast up to 1 meter away + +``MetersToViewSpaceUnits`` is used internally + +* To convert the AO radius parameter from meters to view-space units + +* To adjust the blur sharpness parameter + +Power Exponent +++++++++++++++++++++ + +* The PowerExponent parameter controls the darkness of the final AO: FinalAO = pow(AO, PowerExponent). + +* Typical PowerExponent values are in the range [2.0, 3.0]. + +AO Bias +++++++++++++++++++++ + +* The AO Bias parameter can be used to hide low-tessellation artifacts + +* Can also help reducing false-occlusion artifacts near screen borders + +* It weights the AO contributions more strongly for samples towards the normal direction + +.. image:: \_static\AOBias_0_0.png + +.. image:: \_static\AOBias_0_3.png + +Foreground AO +++++++++++++++++++++ + +* When this feature is enabled, the screen-space AO kernel radius is: + + * inversely proportional to ViewDepth for ViewDepth > ForegroundViewDepth + + * uniform in screen-space for ViewDepth <= ForegroundViewDepth (instead of getting arbitrarily large) + +* To tune the ForegroundViewDepth parameter + + * Start with ForegroundViewDepth = 0.f + + * Increase the ForegroundViewDepth to get less closer-scale occlusion on the foreground objects. + +.. image:: \_static\ForegroundAO_OFF.png + +.. image:: \_static\ForegroundAO_ON.png + +Background AO +++++++++++++++++++++ + +* When this feature is enabled, the screen-space AO kernel radius is: + + * inversely proportional to ViewDepth for ViewDepth < BackgroundViewDepth + + * uniform in screen-space for ViewDepth >= BackgroundViewDepth (instead of falling off to zero). + +* To tune the BackgroundViewDepth parameter + + * Start from a very large BackgroundViewDepth value (e.g. the camera's ZFar) + + * Decrease the BackgroundViewDepth to get larger-scale occlusion in the background. + +.. image:: \_static\BackgroundAO_OFF.png + +.. image:: \_static\BackgroundAO_ON.png + +AO Blur +++++++++++++++++++++ + +* Optional cross-bilateral filter + + * To remove jittered-sampling artifacts (noise) + + * To hide under-sampling artifacts (banding) & reduce jittering + +* 3 Modes + + * No Blur + + * Blur Radius 2 + + * Blur Radius 4 + +.. image:: \_static\No_Blur.png + +.. image:: \_static\Blur_Radius_4.png + +Blur Sharpness +++++++++++++++++++++ + +The greater the sharpness parameter, the more the blur preserves edges + +.. image:: \_static\Blur_Sharpness_0.png + +.. image:: \_static\Blur_Sharpness_8.png + +Integration Time Estimates +########################## + +* Initial integration (for a rendering engineer) + + * <1 man-day with no input normals + + * 1-2 man-days with input normals + +* Initial parameter tuning + + * <1 man-hour + + * Tuning the parameter should be quick once the input data are correctly fed into the library + + * The same HBAO+ parameters may be used globally across the whole game + +Additional Links +################ + +`[Bavoil et al. 2008] "Image-Space Horizon-Based Ambient Occlusion" `_ + +`[McGuire et al. 2012] "Scalable Ambient Obscurance" `_ + +`[Bukowski et al. 2012] "Scalable High-Quality Motion Blur and Ambient Occlusion" `_ + +`[Bavoil and Jansen 2013] "Particle Shadows & Cache-Efficient Post-Processing" `_ + + +.. Un-comment out if section is used +.. Additional Links +.. ################ + +.. Possible content here includes any of the following: +.. * User guide +.. * Videos +.. * Forums +.. * Etc. + +.. toctree:: + :maxdepth: 1 + +.. Example of Getting Start Guide link +.. _Getting Started Guide: gettingstarted.html diff --git a/doc/_sources/releasenotes.txt b/doc/_sources/releasenotes.txt new file mode 100644 index 0000000..8952ef6 --- /dev/null +++ b/doc/_sources/releasenotes.txt @@ -0,0 +1,35 @@ +.. Replace existing content with product specific content. Layout for this page should be consistent for all products. + +Release Notes +======================================= + +|PRODUCTNAMEDOCRELEASEBOLD| + +NVIDIA HBAO+ improves upon existing Ambient Occlusion techniques to add richer, more detailed, more realistic shadows around objects that occlude rays of light. Compared to previous techniques, HBAO+ is faster, more efficient, and significantly better. + + +What's New +----------------------- + +**General** + +|VERSIONBOLD| + +* Added entry points for D3D12. +* Now shipping separate DLLs and LIB files for D3D11 and GL. +* Added the BackgroundAO parameter, which can be used to add larger-scale occlusion in the distance. +* Removed the BLUR_RADIUS_8 mode (BLUR_RADIUS_4 looks better in general, and runs faster). +* Added per-component debug-normal visualization modes in GFSDK_SSAO_RenderMask. + +.. ----------------------- + +.. * `Forums`_ + +.. * `Report a bug`_ + +.. If links above are used, replace URL below. +.. _Forums: http://devtalk.nvidia.com +.. _Report a bug: http://developer.nvidia.com/contact + +.. toctree:: + :maxdepth: 1 diff --git a/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/Sphinx-1.2.dist-info/DESCRIPTION.txt b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/Sphinx-1.2.dist-info/DESCRIPTION.txt new file mode 100644 index 0000000..c526f08 --- /dev/null +++ b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/Sphinx-1.2.dist-info/DESCRIPTION.txt @@ -0,0 +1,31 @@ +Sphinx is a tool that makes it easy to create intelligent and beautiful +documentation for Python projects (or other documents consisting of multiple +reStructuredText sources), written by Georg Brandl. It was originally created +for the new Python documentation, and has excellent facilities for Python +project documentation, but C/C++ is supported as well, and more languages are +planned. + +Sphinx uses reStructuredText as its markup language, and many of its strengths +come from the power and straightforwardness of reStructuredText and its parsing +and translating suite, the Docutils. + +Among its features are the following: + +* Output formats: HTML (including derivative formats such as HTML Help, Epub + and Qt Help), plain text, manual pages and LaTeX or direct PDF output + using rst2pdf +* Extensive cross-references: semantic markup and automatic links + for functions, classes, glossary terms and similar pieces of information +* Hierarchical structure: easy definition of a document tree, with automatic + links to siblings, parents and children +* Automatic indices: general index as well as a module index +* Code handling: automatic highlighting using the Pygments highlighter +* Flexible HTML output using the Jinja 2 templating engine +* Various extensions are available, e.g. for automatic testing of snippets + and inclusion of appropriately formatted docstrings +* Setuptools integration + +A development egg can be found `here +`_. + + diff --git a/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/setuptools-2.1.dist-info/DESCRIPTION.txt b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/setuptools-2.1.dist-info/DESCRIPTION.txt new file mode 100644 index 0000000..8577264 --- /dev/null +++ b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/setuptools-2.1.dist-info/DESCRIPTION.txt @@ -0,0 +1,1742 @@ +=============================== +Installing and Using Setuptools +=============================== + +.. contents:: **Table of Contents** + + +------------------------- +Installation Instructions +------------------------- + +Upgrading from Distribute +========================= + +Currently, Distribute disallows installing Setuptools 0.7+ over Distribute. +You must first uninstall any active version of Distribute first (see +`Uninstalling`_). + +Upgrading from Setuptools 0.6 +============================= + +Upgrading from prior versions of Setuptools is supported. Initial reports +good success in this regard. + +Windows +======= + +The recommended way to install setuptools on Windows is to download +`ez_setup.py`_ and run it. The script will download the appropriate .egg +file and install it for you. + +.. _ez_setup.py: https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py + +For best results, uninstall previous versions FIRST (see `Uninstalling`_). + +Once installation is complete, you will find an ``easy_install`` program in +your Python ``Scripts`` subdirectory. For simple invocation and best results, +add this directory to your ``PATH`` environment variable, if it is not already +present. + + +Unix-based Systems including Mac OS X +===================================== + +Download `ez_setup.py`_ and run it using the target Python version. The script +will download the appropriate version and install it for you:: + + > wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python + +Note that you will may need to invoke the command with superuser privileges to +install to the system Python:: + + > wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | sudo python + +Alternatively, on Python 2.6 and later, Setuptools may be installed to a +user-local path:: + + > wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py + > python ez_setup.py --user + + +Python 2.4 and Python 2.5 support +================================= + +Setuptools 2.0 and later requires Python 2.6 or later. To install setuptools +on Python 2.4 or Python 2.5, use the bootstrap script for Setuptools 1.x: +https://bitbucket.org/pypa/setuptools/raw/bootstrap-py24/ez_setup.py. + + +Advanced Installation +===================== + +For more advanced installation options, such as installing to custom +locations or prefixes, download and extract the source +tarball from `Setuptools on PyPI `_ +and run setup.py with any supported distutils and Setuptools options. +For example:: + + setuptools-x.x$ python setup.py --prefix=/opt/setuptools + +Use ``--help`` to get a full options list, but we recommend consulting +the `EasyInstall manual`_ for detailed instructions, especially `the section +on custom installation locations`_. + +.. _EasyInstall manual: https://pythonhosted.org/setuptools/EasyInstall +.. _the section on custom installation locations: https://pythonhosted.org/setuptools/EasyInstall#custom-installation-locations + + +Downloads +========= + +All setuptools downloads can be found at `the project's home page in the Python +Package Index`_. Scroll to the very bottom of the page to find the links. + +.. _the project's home page in the Python Package Index: https://pypi.python.org/pypi/setuptools + +In addition to the PyPI downloads, the development version of ``setuptools`` +is available from the `Bitbucket repo`_, and in-development versions of the +`0.6 branch`_ are available as well. + +.. _Bitbucket repo: https://bitbucket.org/pypa/setuptools/get/default.tar.gz#egg=setuptools-dev +.. _0.6 branch: http://svn.python.org/projects/sandbox/branches/setuptools-0.6/#egg=setuptools-dev06 + +Uninstalling +============ + +On Windows, if Setuptools was installed using an ``.exe`` or ``.msi`` +installer, simply use the uninstall feature of "Add/Remove Programs" in the +Control Panel. + +Otherwise, to uninstall Setuptools or Distribute, regardless of the Python +version, delete all ``setuptools*`` and ``distribute*`` files and +directories from your system's ``site-packages`` directory +(and any other ``sys.path`` directories) FIRST. + +If you are upgrading or otherwise plan to re-install Setuptools or Distribute, +nothing further needs to be done. If you want to completely remove Setuptools, +you may also want to remove the 'easy_install' and 'easy_install-x.x' scripts +and associated executables installed to the Python scripts directory. + +-------------------------------- +Using Setuptools and EasyInstall +-------------------------------- + +Here are some of the available manuals, tutorials, and other resources for +learning about Setuptools, Python Eggs, and EasyInstall: + +* `The EasyInstall user's guide and reference manual`_ +* `The setuptools Developer's Guide`_ +* `The pkg_resources API reference`_ +* `Package Compatibility Notes`_ (user-maintained) +* `The Internal Structure of Python Eggs`_ + +Questions, comments, and bug reports should be directed to the `distutils-sig +mailing list`_. If you have written (or know of) any tutorials, documentation, +plug-ins, or other resources for setuptools users, please let us know about +them there, so this reference list can be updated. If you have working, +*tested* patches to correct problems or add features, you may submit them to +the `setuptools bug tracker`_. + +.. _setuptools bug tracker: https://bitbucket.org/pypa/setuptools/issues +.. _Package Compatibility Notes: https://pythonhosted.org/setuptools/PackageNotes +.. _The Internal Structure of Python Eggs: https://pythonhosted.org/setuptools/formats.html +.. _The setuptools Developer's Guide: https://pythonhosted.org/setuptools/setuptools.html +.. _The pkg_resources API reference: https://pythonhosted.org/setuptools/pkg_resources.html +.. _The EasyInstall user's guide and reference manual: https://pythonhosted.org/setuptools/easy_install.html +.. _distutils-sig mailing list: http://mail.python.org/pipermail/distutils-sig/ + + +------- +Credits +------- + +* The original design for the ``.egg`` format and the ``pkg_resources`` API was + co-created by Phillip Eby and Bob Ippolito. Bob also implemented the first + version of ``pkg_resources``, and supplied the OS X operating system version + compatibility algorithm. + +* Ian Bicking implemented many early "creature comfort" features of + easy_install, including support for downloading via Sourceforge and + Subversion repositories. Ian's comments on the Web-SIG about WSGI + application deployment also inspired the concept of "entry points" in eggs, + and he has given talks at PyCon and elsewhere to inform and educate the + community about eggs and setuptools. + +* Jim Fulton contributed time and effort to build automated tests of various + aspects of ``easy_install``, and supplied the doctests for the command-line + ``.exe`` wrappers on Windows. + +* Phillip J. Eby is the seminal author of setuptools, and + first proposed the idea of an importable binary distribution format for + Python application plug-ins. + +* Significant parts of the implementation of setuptools were funded by the Open + Source Applications Foundation, to provide a plug-in infrastructure for the + Chandler PIM application. In addition, many OSAF staffers (such as Mike + "Code Bear" Taylor) contributed their time and stress as guinea pigs for the + use of eggs and setuptools, even before eggs were "cool". (Thanks, guys!) + +* Since the merge with Distribute, Jason R. Coombs is the + maintainer of setuptools. The project is maintained in coordination with + the Python Packaging Authority (PyPA) and the larger Python community. + +.. _files: + +======= +CHANGES +======= + +--- +2.1 +--- + +* `Issue #129 `_: Suppress inspection of '*.whl' files when searching for files + in a zip-imported file. +* `Issue #131 `_: Fix RuntimeError when constructing an egg fetcher. + +----- +2.0.2 +----- + +* Fix NameError during installation with Python implementations (e.g. Jython) + not containing parser module. +* Fix NameError in ``sdist:re_finder``. + +----- +2.0.1 +----- + +* `Issue #124 `_: Fixed error in list detection in upload_docs. + +--- +2.0 +--- + +* `Issue #121 `_: Exempt lib2to3 pickled grammars from DirectorySandbox. +* `Issue #41 `_: Dropped support for Python 2.4 and Python 2.5. Clients requiring + setuptools for those versions of Python should use setuptools 1.x. +* Removed ``setuptools.command.easy_install.HAS_USER_SITE``. Clients + expecting this boolean variable should use ``site.ENABLE_USER_SITE`` + instead. +* Removed ``pkg_resources.ImpWrapper``. Clients that expected this class + should use ``pkgutil.ImpImporter`` instead. + +----- +1.4.2 +----- + +* `Issue #116 `_: Correct TypeError when reading a local package index on Python + 3. + +----- +1.4.1 +----- + +* `Issue #114 `_: Use ``sys.getfilesystemencoding`` for decoding config in + ``bdist_wininst`` distributions. + +* `Issue #105 `_ and `Issue #113 `_: Establish a more robust technique for + determining the terminal encoding:: + + 1. Try ``getpreferredencoding`` + 2. If that returns US_ASCII or None, try the encoding from + ``getdefaultlocale``. If that encoding was a "fallback" because Python + could not figure it out from the environment or OS, encoding remains + unresolved. + 3. If the encoding is resolved, then make sure Python actually implements + the encoding. + 4. On the event of an error or unknown codec, revert to fallbacks + (UTF-8 on Darwin, ASCII on everything else). + 5. On the encoding is 'mac-roman' on Darwin, use UTF-8 as 'mac-roman' was + a bug on older Python releases. + + On a side note, it would seem that the encoding only matters for when SVN + does not yet support ``--xml`` and when getting repository and svn version + numbers. The ``--xml`` technique should yield UTF-8 according to some + messages on the SVN mailing lists. So if the version numbers are always + 7-bit ASCII clean, it may be best to only support the file parsing methods + for legacy SVN releases and support for SVN without the subprocess command + would simple go away as support for the older SVNs does. + +--- +1.4 +--- + +* `Issue #27 `_: ``easy_install`` will now use credentials from .pypirc if + present for connecting to the package index. +* `Pull Request #21 `_: Omit unwanted newlines in ``package_index._encode_auth`` + when the username/password pair length indicates wrapping. + +----- +1.3.2 +----- + +* `Issue #99 `_: Fix filename encoding issues in SVN support. + +----- +1.3.1 +----- + +* Remove exuberant warning in SVN support when SVN is not used. + +--- +1.3 +--- + +* Address security vulnerability in SSL match_hostname check as reported in + `Python #17997 `_. +* Prefer `backports.ssl_match_hostname + `_ for backport + implementation if present. +* Correct NameError in ``ssl_support`` module (``socket.error``). + +--- +1.2 +--- + +* `Issue #26 `_: Add support for SVN 1.7. Special thanks to Philip Thiem for the + contribution. +* `Issue #93 `_: Wheels are now distributed with every release. Note that as + reported in `Issue #108 `_, as of Pip 1.4, scripts aren't installed properly + from wheels. Therefore, if using Pip to install setuptools from a wheel, + the ``easy_install`` command will not be available. +* Setuptools "natural" launcher support, introduced in 1.0, is now officially + supported. + +----- +1.1.7 +----- + +* Fixed behavior of NameError handling in 'script template (dev).py' (script + launcher for 'develop' installs). +* ``ez_setup.py`` now ensures partial downloads are cleaned up following + a failed download. +* `Distribute #363 `_ and `Issue #55 `_: Skip an sdist test that fails on locales + other than UTF-8. + +----- +1.1.6 +----- + +* `Distribute #349 `_: ``sandbox.execfile`` now opens the target file in binary + mode, thus honoring a BOM in the file when compiled. + +----- +1.1.5 +----- + +* `Issue #69 `_: Second attempt at fix (logic was reversed). + +----- +1.1.4 +----- + +* `Issue #77 `_: Fix error in upload command (Python 2.4). + +----- +1.1.3 +----- + +* Fix NameError in previous patch. + +----- +1.1.2 +----- + +* `Issue #69 `_: Correct issue where 404 errors are returned for URLs with + fragments in them (such as #egg=). + +----- +1.1.1 +----- + +* `Issue #75 `_: Add ``--insecure`` option to ez_setup.py to accommodate + environments where a trusted SSL connection cannot be validated. +* `Issue #76 `_: Fix AttributeError in upload command with Python 2.4. + +--- +1.1 +--- + +* `Issue #71 `_ (`Distribute #333 `_): EasyInstall now puts less emphasis on the + condition when a host is blocked via ``--allow-hosts``. +* `Issue #72 `_: Restored Python 2.4 compatibility in ``ez_setup.py``. + +--- +1.0 +--- + +* `Issue #60 `_: On Windows, Setuptools supports deferring to another launcher, + such as Vinay Sajip's `pylauncher `_ + (included with Python 3.3) to launch console and GUI scripts and not install + its own launcher executables. This experimental functionality is currently + only enabled if the ``SETUPTOOLS_LAUNCHER`` environment variable is set to + "natural". In the future, this behavior may become default, but only after + it has matured and seen substantial adoption. The ``SETUPTOOLS_LAUNCHER`` + also accepts "executable" to force the default behavior of creating launcher + executables. +* `Issue #63 `_: Bootstrap script (ez_setup.py) now prefers Powershell, curl, or + wget for retrieving the Setuptools tarball for improved security of the + install. The script will still fall back to a simple ``urlopen`` on + platforms that do not have these tools. +* `Issue #65 `_: Deprecated the ``Features`` functionality. +* `Issue #52 `_: In ``VerifyingHTTPSConn``, handle a tunnelled (proxied) + connection. + +Backward-Incompatible Changes +============================= + +This release includes a couple of backward-incompatible changes, but most if +not all users will find 1.0 a drop-in replacement for 0.9. + +* `Issue #50 `_: Normalized API of environment marker support. Specifically, + removed line number and filename from SyntaxErrors when returned from + `pkg_resources.invalid_marker`. Any clients depending on the specific + string representation of exceptions returned by that function may need to + be updated to account for this change. +* `Issue #50 `_: SyntaxErrors generated by `pkg_resources.invalid_marker` are + normalized for cross-implementation consistency. +* Removed ``--ignore-conflicts-at-my-risk`` and ``--delete-conflicting`` + options to easy_install. These options have been deprecated since 0.6a11. + +----- +0.9.8 +----- + +* `Issue #53 `_: Fix NameErrors in `_vcs_split_rev_from_url`. + +----- +0.9.7 +----- + +* `Issue #49 `_: Correct AttributeError on PyPy where a hashlib.HASH object does + not have a `.name` attribute. +* `Issue #34 `_: Documentation now refers to bootstrap script in code repository + referenced by bookmark. +* Add underscore-separated keys to environment markers (markerlib). + +----- +0.9.6 +----- + +* `Issue #44 `_: Test failure on Python 2.4 when MD5 hash doesn't have a `.name` + attribute. + +----- +0.9.5 +----- + +* `Python #17980 `_: Fix security vulnerability in SSL certificate validation. + +----- +0.9.4 +----- + +* `Issue #43 `_: Fix issue (introduced in 0.9.1) with version resolution when + upgrading over other releases of Setuptools. + +----- +0.9.3 +----- + +* `Issue #42 `_: Fix new ``AttributeError`` introduced in last fix. + +----- +0.9.2 +----- + +* `Issue #42 `_: Fix regression where blank checksums would trigger an + ``AttributeError``. + +----- +0.9.1 +----- + +* `Distribute #386 `_: Allow other positional and keyword arguments to os.open. +* Corrected dependency on certifi mis-referenced in 0.9. + +--- +0.9 +--- + +* `package_index` now validates hashes other than MD5 in download links. + +--- +0.8 +--- + +* Code base now runs on Python 2.4 - Python 3.3 without Python 2to3 + conversion. + +----- +0.7.8 +----- + +* `Distribute #375 `_: Yet another fix for yet another regression. + +----- +0.7.7 +----- + +* `Distribute #375 `_: Repair AttributeError created in last release (redo). +* `Issue #30 `_: Added test for get_cache_path. + +----- +0.7.6 +----- + +* `Distribute #375 `_: Repair AttributeError created in last release. + +----- +0.7.5 +----- + +* `Issue #21 `_: Restore Python 2.4 compatibility in ``test_easy_install``. +* `Distribute #375 `_: Merged additional warning from Distribute 0.6.46. +* Now honor the environment variable + ``SETUPTOOLS_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT`` in addition to the now + deprecated ``DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT``. + +----- +0.7.4 +----- + +* `Issue #20 `_: Fix comparison of parsed SVN version on Python 3. + +----- +0.7.3 +----- + +* `Issue #1 `_: Disable installation of Windows-specific files on non-Windows systems. +* Use new sysconfig module with Python 2.7 or >=3.2. + +----- +0.7.2 +----- + +* `Issue #14 `_: Use markerlib when the `parser` module is not available. +* `Issue #10 `_: ``ez_setup.py`` now uses HTTPS to download setuptools from PyPI. + +----- +0.7.1 +----- + +* Fix NameError (`Issue #3 `_) again - broken in bad merge. + +--- +0.7 +--- + +* Merged Setuptools and Distribute. See docs/merge.txt for details. + +Added several features that were slated for setuptools 0.6c12: + +* Index URL now defaults to HTTPS. +* Added experimental environment marker support. Now clients may designate a + PEP-426 environment marker for "extra" dependencies. Setuptools uses this + feature in ``setup.py`` for optional SSL and certificate validation support + on older platforms. Based on Distutils-SIG discussions, the syntax is + somewhat tentative. There should probably be a PEP with a firmer spec before + the feature should be considered suitable for use. +* Added support for SSL certificate validation when installing packages from + an HTTPS service. + +----- +0.7b4 +----- + +* `Issue #3 `_: Fixed NameError in SSL support. + +------ +0.6.49 +------ + +* Move warning check in ``get_cache_path`` to follow the directory creation + to avoid errors when the cache path does not yet exist. Fixes the error + reported in `Distribute #375 `_. + +------ +0.6.48 +------ + +* Correct AttributeError in ``ResourceManager.get_cache_path`` introduced in + 0.6.46 (redo). + +------ +0.6.47 +------ + +* Correct AttributeError in ``ResourceManager.get_cache_path`` introduced in + 0.6.46. + +------ +0.6.46 +------ + +* `Distribute #375 `_: Issue a warning if the PYTHON_EGG_CACHE or otherwise + customized egg cache location specifies a directory that's group- or + world-writable. + +------ +0.6.45 +------ + +* `Distribute #379 `_: ``distribute_setup.py`` now traps VersionConflict as well, + restoring ability to upgrade from an older setuptools version. + +------ +0.6.44 +------ + +* ``distribute_setup.py`` has been updated to allow Setuptools 0.7 to + satisfy use_setuptools. + +------ +0.6.43 +------ + +* `Distribute #378 `_: Restore support for Python 2.4 Syntax (regression in 0.6.42). + +------ +0.6.42 +------ + +* External links finder no longer yields duplicate links. +* `Distribute #337 `_: Moved site.py to setuptools/site-patch.py (graft of very old + patch from setuptools trunk which inspired PR `#31 `_). + +------ +0.6.41 +------ + +* `Distribute #27 `_: Use public api for loading resources from zip files rather than + the private method `_zip_directory_cache`. +* Added a new function ``easy_install.get_win_launcher`` which may be used by + third-party libraries such as buildout to get a suitable script launcher. + +------ +0.6.40 +------ + +* `Distribute #376 `_: brought back cli.exe and gui.exe that were deleted in the + previous release. + +------ +0.6.39 +------ + +* Add support for console launchers on ARM platforms. +* Fix possible issue in GUI launchers where the subsystem was not supplied to + the linker. +* Launcher build script now refactored for robustness. +* `Distribute #375 `_: Resources extracted from a zip egg to the file system now also + check the contents of the file against the zip contents during each + invocation of get_resource_filename. + +------ +0.6.38 +------ + +* `Distribute #371 `_: The launcher manifest file is now installed properly. + +------ +0.6.37 +------ + +* `Distribute #143 `_: Launcher scripts, including easy_install itself, are now + accompanied by a manifest on 32-bit Windows environments to avoid the + Installer Detection Technology and thus undesirable UAC elevation described + in `this Microsoft article + `_. + +------ +0.6.36 +------ + +* `Pull Request #35 `_: In `Buildout #64 `_, it was reported that + under Python 3, installation of distutils scripts could attempt to copy + the ``__pycache__`` directory as a file, causing an error, apparently only + under Windows. Easy_install now skips all directories when processing + metadata scripts. + +------ +0.6.35 +------ + + +Note this release is backward-incompatible with distribute 0.6.23-0.6.34 in +how it parses version numbers. + +* `Distribute #278 `_: Restored compatibility with distribute 0.6.22 and setuptools + 0.6. Updated the documentation to match more closely with the version + parsing as intended in setuptools 0.6. + +------ +0.6.34 +------ + +* `Distribute #341 `_: 0.6.33 fails to build under Python 2.4. + +------ +0.6.33 +------ + +* Fix 2 errors with Jython 2.5. +* Fix 1 failure with Jython 2.5 and 2.7. +* Disable workaround for Jython scripts on Linux systems. +* `Distribute #336 `_: `setup.py` no longer masks failure exit code when tests fail. +* Fix issue in pkg_resources where try/except around a platform-dependent + import would trigger hook load failures on Mercurial. See pull request 32 + for details. +* `Distribute #341 `_: Fix a ResourceWarning. + +------ +0.6.32 +------ + +* Fix test suite with Python 2.6. +* Fix some DeprecationWarnings and ResourceWarnings. +* `Distribute #335 `_: Backed out `setup_requires` superceding installed requirements + until regression can be addressed. + +------ +0.6.31 +------ + +* `Distribute #303 `_: Make sure the manifest only ever contains UTF-8 in Python 3. +* `Distribute #329 `_: Properly close files created by tests for compatibility with + Jython. +* Work around `Jython #1980 `_ and `Jython #1981 `_. +* `Distribute #334 `_: Provide workaround for packages that reference `sys.__stdout__` + such as numpy does. This change should address + `virtualenv `#359 `_ `_ as long + as the system encoding is UTF-8 or the IO encoding is specified in the + environment, i.e.:: + + PYTHONIOENCODING=utf8 pip install numpy + +* Fix for encoding issue when installing from Windows executable on Python 3. +* `Distribute #323 `_: Allow `setup_requires` requirements to supercede installed + requirements. Added some new keyword arguments to existing pkg_resources + methods. Also had to updated how __path__ is handled for namespace packages + to ensure that when a new egg distribution containing a namespace package is + placed on sys.path, the entries in __path__ are found in the same order they + would have been in had that egg been on the path when pkg_resources was + first imported. + +------ +0.6.30 +------ + +* `Distribute #328 `_: Clean up temporary directories in distribute_setup.py. +* Fix fatal bug in distribute_setup.py. + +------ +0.6.29 +------ + +* `Pull Request #14 `_: Honor file permissions in zip files. +* `Distribute #327 `_: Merged pull request `#24 `_ to fix a dependency problem with pip. +* Merged pull request `#23 `_ to fix https://github.com/pypa/virtualenv/issues/301. +* If Sphinx is installed, the `upload_docs` command now runs `build_sphinx` + to produce uploadable documentation. +* `Distribute #326 `_: `upload_docs` provided mangled auth credentials under Python 3. +* `Distribute #320 `_: Fix check for "createable" in distribute_setup.py. +* `Distribute #305 `_: Remove a warning that was triggered during normal operations. +* `Distribute #311 `_: Print metadata in UTF-8 independent of platform. +* `Distribute #303 `_: Read manifest file with UTF-8 encoding under Python 3. +* `Distribute #301 `_: Allow to run tests of namespace packages when using 2to3. +* `Distribute #304 `_: Prevent import loop in site.py under Python 3.3. +* `Distribute #283 `_: Reenable scanning of `*.pyc` / `*.pyo` files on Python 3.3. +* `Distribute #299 `_: The develop command didn't work on Python 3, when using 2to3, + as the egg link would go to the Python 2 source. Linking to the 2to3'd code + in build/lib makes it work, although you will have to rebuild the module + before testing it. +* `Distribute #306 `_: Even if 2to3 is used, we build in-place under Python 2. +* `Distribute #307 `_: Prints the full path when .svn/entries is broken. +* `Distribute #313 `_: Support for sdist subcommands (Python 2.7) +* `Distribute #314 `_: test_local_index() would fail an OS X. +* `Distribute #310 `_: Non-ascii characters in a namespace __init__.py causes errors. +* `Distribute #218 `_: Improved documentation on behavior of `package_data` and + `include_package_data`. Files indicated by `package_data` are now included + in the manifest. +* `distribute_setup.py` now allows a `--download-base` argument for retrieving + distribute from a specified location. + +------ +0.6.28 +------ + +* `Distribute #294 `_: setup.py can now be invoked from any directory. +* Scripts are now installed honoring the umask. +* Added support for .dist-info directories. +* `Distribute #283 `_: Fix and disable scanning of `*.pyc` / `*.pyo` files on + Python 3.3. + +------ +0.6.27 +------ + +* Support current snapshots of CPython 3.3. +* Distribute now recognizes README.rst as a standard, default readme file. +* Exclude 'encodings' modules when removing modules from sys.modules. + Workaround for `#285 `_. +* `Distribute #231 `_: Don't fiddle with system python when used with buildout + (bootstrap.py) + +------ +0.6.26 +------ + +* `Distribute #183 `_: Symlinked files are now extracted from source distributions. +* `Distribute #227 `_: Easy_install fetch parameters are now passed during the + installation of a source distribution; now fulfillment of setup_requires + dependencies will honor the parameters passed to easy_install. + +------ +0.6.25 +------ + +* `Distribute #258 `_: Workaround a cache issue +* `Distribute #260 `_: distribute_setup.py now accepts the --user parameter for + Python 2.6 and later. +* `Distribute #262 `_: package_index.open_with_auth no longer throws LookupError + on Python 3. +* `Distribute #269 `_: AttributeError when an exception occurs reading Manifest.in + on late releases of Python. +* `Distribute #272 `_: Prevent TypeError when namespace package names are unicode + and single-install-externally-managed is used. Also fixes PIP issue + 449. +* `Distribute #273 `_: Legacy script launchers now install with Python2/3 support. + +------ +0.6.24 +------ + +* `Distribute #249 `_: Added options to exclude 2to3 fixers + +------ +0.6.23 +------ + +* `Distribute #244 `_: Fixed a test +* `Distribute #243 `_: Fixed a test +* `Distribute #239 `_: Fixed a test +* `Distribute #240 `_: Fixed a test +* `Distribute #241 `_: Fixed a test +* `Distribute #237 `_: Fixed a test +* `Distribute #238 `_: easy_install now uses 64bit executable wrappers on 64bit Python +* `Distribute #208 `_: Fixed parsed_versions, it now honors post-releases as noted in the documentation +* `Distribute #207 `_: Windows cli and gui wrappers pass CTRL-C to child python process +* `Distribute #227 `_: easy_install now passes its arguments to setup.py bdist_egg +* `Distribute #225 `_: Fixed a NameError on Python 2.5, 2.4 + +------ +0.6.21 +------ + +* `Distribute #225 `_: FIxed a regression on py2.4 + +------ +0.6.20 +------ + +* `Distribute #135 `_: Include url in warning when processing URLs in package_index. +* `Distribute #212 `_: Fix issue where easy_instal fails on Python 3 on windows installer. +* `Distribute #213 `_: Fix typo in documentation. + +------ +0.6.19 +------ + +* `Distribute #206 `_: AttributeError: 'HTTPMessage' object has no attribute 'getheaders' + +------ +0.6.18 +------ + +* `Distribute #210 `_: Fixed a regression introduced by `Distribute #204 `_ fix. + +------ +0.6.17 +------ + +* Support 'DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT' environment + variable to allow to disable installation of easy_install-${version} script. +* Support Python >=3.1.4 and >=3.2.1. +* `Distribute #204 `_: Don't try to import the parent of a namespace package in + declare_namespace +* `Distribute #196 `_: Tolerate responses with multiple Content-Length headers +* `Distribute #205 `_: Sandboxing doesn't preserve working_set. Leads to setup_requires + problems. + +------ +0.6.16 +------ + +* Builds sdist gztar even on Windows (avoiding `Distribute #193 `_). +* `Distribute #192 `_: Fixed metadata omitted on Windows when package_dir + specified with forward-slash. +* `Distribute #195 `_: Cython build support. +* `Distribute #200 `_: Issues with recognizing 64-bit packages on Windows. + +------ +0.6.15 +------ + +* Fixed typo in bdist_egg +* Several issues under Python 3 has been solved. +* `Distribute #146 `_: Fixed missing DLL files after easy_install of windows exe package. + +------ +0.6.14 +------ + +* `Distribute #170 `_: Fixed unittest failure. Thanks to Toshio. +* `Distribute #171 `_: Fixed race condition in unittests cause deadlocks in test suite. +* `Distribute #143 `_: Fixed a lookup issue with easy_install. + Thanks to David and Zooko. +* `Distribute #174 `_: Fixed the edit mode when its used with setuptools itself + +------ +0.6.13 +------ + +* `Distribute #160 `_: 2.7 gives ValueError("Invalid IPv6 URL") +* `Distribute #150 `_: Fixed using ~/.local even in a --no-site-packages virtualenv +* `Distribute #163 `_: scan index links before external links, and don't use the md5 when + comparing two distributions + +------ +0.6.12 +------ + +* `Distribute #149 `_: Fixed various failures on 2.3/2.4 + +------ +0.6.11 +------ + +* Found another case of SandboxViolation - fixed +* `Distribute #15 `_ and `Distribute #48 `_: Introduced a socket timeout of 15 seconds on url openings +* Added indexsidebar.html into MANIFEST.in +* `Distribute #108 `_: Fixed TypeError with Python3.1 +* `Distribute #121 `_: Fixed --help install command trying to actually install. +* `Distribute #112 `_: Added an os.makedirs so that Tarek's solution will work. +* `Distribute #133 `_: Added --no-find-links to easy_install +* Added easy_install --user +* `Distribute #100 `_: Fixed develop --user not taking '.' in PYTHONPATH into account +* `Distribute #134 `_: removed spurious UserWarnings. Patch by VanLindberg +* `Distribute #138 `_: cant_write_to_target error when setup_requires is used. +* `Distribute #147 `_: respect the sys.dont_write_bytecode flag + +------ +0.6.10 +------ + +* Reverted change made for the DistributionNotFound exception because + zc.buildout uses the exception message to get the name of the + distribution. + +----- +0.6.9 +----- + +* `Distribute #90 `_: unknown setuptools version can be added in the working set +* `Distribute #87 `_: setupt.py doesn't try to convert distribute_setup.py anymore + Initial Patch by arfrever. +* `Distribute #89 `_: added a side bar with a download link to the doc. +* `Distribute #86 `_: fixed missing sentence in pkg_resources doc. +* Added a nicer error message when a DistributionNotFound is raised. +* `Distribute #80 `_: test_develop now works with Python 3.1 +* `Distribute #93 `_: upload_docs now works if there is an empty sub-directory. +* `Distribute #70 `_: exec bit on non-exec files +* `Distribute #99 `_: now the standalone easy_install command doesn't uses a + "setup.cfg" if any exists in the working directory. It will use it + only if triggered by ``install_requires`` from a setup.py call + (install, develop, etc). +* `Distribute #101 `_: Allowing ``os.devnull`` in Sandbox +* `Distribute #92 `_: Fixed the "no eggs" found error with MacPort + (platform.mac_ver() fails) +* `Distribute #103 `_: test_get_script_header_jython_workaround not run + anymore under py3 with C or POSIX local. Contributed by Arfrever. +* `Distribute #104 `_: remvoved the assertion when the installation fails, + with a nicer message for the end user. +* `Distribute #100 `_: making sure there's no SandboxViolation when + the setup script patches setuptools. + +----- +0.6.8 +----- + +* Added "check_packages" in dist. (added in Setuptools 0.6c11) +* Fixed the DONT_PATCH_SETUPTOOLS state. + +----- +0.6.7 +----- + +* `Distribute #58 `_: Added --user support to the develop command +* `Distribute #11 `_: Generated scripts now wrap their call to the script entry point + in the standard "if name == 'main'" +* Added the 'DONT_PATCH_SETUPTOOLS' environment variable, so virtualenv + can drive an installation that doesn't patch a global setuptools. +* Reviewed unladen-swallow specific change from + http://code.google.com/p/unladen-swallow/source/detail?spec=svn875&r=719 + and determined that it no longer applies. Distribute should work fine with + Unladen Swallow 2009Q3. +* `Distribute #21 `_: Allow PackageIndex.open_url to gracefully handle all cases of a + httplib.HTTPException instead of just InvalidURL and BadStatusLine. +* Removed virtual-python.py from this distribution and updated documentation + to point to the actively maintained virtualenv instead. +* `Distribute #64 `_: use_setuptools no longer rebuilds the distribute egg every + time it is run +* use_setuptools now properly respects the requested version +* use_setuptools will no longer try to import a distribute egg for the + wrong Python version +* `Distribute #74 `_: no_fake should be True by default. +* `Distribute #72 `_: avoid a bootstrapping issue with easy_install -U + +----- +0.6.6 +----- + +* Unified the bootstrap file so it works on both py2.x and py3k without 2to3 + (patch by Holger Krekel) + +----- +0.6.5 +----- + +* `Distribute #65 `_: cli.exe and gui.exe are now generated at build time, + depending on the platform in use. + +* `Distribute #67 `_: Fixed doc typo (PEP 381/382) + +* Distribute no longer shadows setuptools if we require a 0.7-series + setuptools. And an error is raised when installing a 0.7 setuptools with + distribute. + +* When run from within buildout, no attempt is made to modify an existing + setuptools egg, whether in a shared egg directory or a system setuptools. + +* Fixed a hole in sandboxing allowing builtin file to write outside of + the sandbox. + +----- +0.6.4 +----- + +* Added the generation of `distribute_setup_3k.py` during the release. + This closes `Distribute #52 `_. + +* Added an upload_docs command to easily upload project documentation to + PyPI's https://pythonhosted.org. This close issue `Distribute #56 `_. + +* Fixed a bootstrap bug on the use_setuptools() API. + +----- +0.6.3 +----- + +setuptools +========== + +* Fixed a bunch of calls to file() that caused crashes on Python 3. + +bootstrapping +============= + +* Fixed a bug in sorting that caused bootstrap to fail on Python 3. + +----- +0.6.2 +----- + +setuptools +========== + +* Added Python 3 support; see docs/python3.txt. + This closes `Old Setuptools #39 `_. + +* Added option to run 2to3 automatically when installing on Python 3. + This closes issue `Distribute #31 `_. + +* Fixed invalid usage of requirement.parse, that broke develop -d. + This closes `Old Setuptools #44 `_. + +* Fixed script launcher for 64-bit Windows. + This closes `Old Setuptools #2 `_. + +* KeyError when compiling extensions. + This closes `Old Setuptools #41 `_. + +bootstrapping +============= + +* Fixed bootstrap not working on Windows. This closes issue `Distribute #49 `_. + +* Fixed 2.6 dependencies. This closes issue `Distribute #50 `_. + +* Make sure setuptools is patched when running through easy_install + This closes `Old Setuptools #40 `_. + +----- +0.6.1 +----- + +setuptools +========== + +* package_index.urlopen now catches BadStatusLine and malformed url errors. + This closes `Distribute #16 `_ and `Distribute #18 `_. + +* zip_ok is now False by default. This closes `Old Setuptools #33 `_. + +* Fixed invalid URL error catching. `Old Setuptools #20 `_. + +* Fixed invalid bootstraping with easy_install installation (`Distribute #40 `_). + Thanks to Florian Schulze for the help. + +* Removed buildout/bootstrap.py. A new repository will create a specific + bootstrap.py script. + + +bootstrapping +============= + +* The boostrap process leave setuptools alone if detected in the system + and --root or --prefix is provided, but is not in the same location. + This closes `Distribute #10 `_. + +--- +0.6 +--- + +setuptools +========== + +* Packages required at build time where not fully present at install time. + This closes `Distribute #12 `_. + +* Protected against failures in tarfile extraction. This closes `Distribute #10 `_. + +* Made Jython api_tests.txt doctest compatible. This closes `Distribute #7 `_. + +* sandbox.py replaced builtin type file with builtin function open. This + closes `Distribute #6 `_. + +* Immediately close all file handles. This closes `Distribute #3 `_. + +* Added compatibility with Subversion 1.6. This references `Distribute #1 `_. + +pkg_resources +============= + +* Avoid a call to /usr/bin/sw_vers on OSX and use the official platform API + instead. Based on a patch from ronaldoussoren. This closes issue `#5 `_. + +* Fixed a SandboxViolation for mkdir that could occur in certain cases. + This closes `Distribute #13 `_. + +* Allow to find_on_path on systems with tight permissions to fail gracefully. + This closes `Distribute #9 `_. + +* Corrected inconsistency between documentation and code of add_entry. + This closes `Distribute #8 `_. + +* Immediately close all file handles. This closes `Distribute #3 `_. + +easy_install +============ + +* Immediately close all file handles. This closes `Distribute #3 `_. + +----- +0.6c9 +----- + + * Fixed a missing files problem when using Windows source distributions on + non-Windows platforms, due to distutils not handling manifest file line + endings correctly. + + * Updated Pyrex support to work with Pyrex 0.9.6 and higher. + + * Minor changes for Jython compatibility, including skipping tests that can't + work on Jython. + + * Fixed not installing eggs in ``install_requires`` if they were also used for + ``setup_requires`` or ``tests_require``. + + * Fixed not fetching eggs in ``install_requires`` when running tests. + + * Allow ``ez_setup.use_setuptools()`` to upgrade existing setuptools + installations when called from a standalone ``setup.py``. + + * Added a warning if a namespace package is declared, but its parent package + is not also declared as a namespace. + + * Support Subversion 1.5 + + * Removed use of deprecated ``md5`` module if ``hashlib`` is available + + * Fixed ``bdist_wininst upload`` trying to upload the ``.exe`` twice + + * Fixed ``bdist_egg`` putting a ``native_libs.txt`` in the source package's + ``.egg-info``, when it should only be in the built egg's ``EGG-INFO``. + + * Ensure that _full_name is set on all shared libs before extensions are + checked for shared lib usage. (Fixes a bug in the experimental shared + library build support.) + + * Fix to allow unpacked eggs containing native libraries to fail more + gracefully under Google App Engine (with an ``ImportError`` loading the + C-based module, instead of getting a ``NameError``). + +----- +0.6c7 +----- + + * Fixed ``distutils.filelist.findall()`` crashing on broken symlinks, and + ``egg_info`` command failing on new, uncommitted SVN directories. + + * Fix import problems with nested namespace packages installed via + ``--root`` or ``--single-version-externally-managed``, due to the + parent package not having the child package as an attribute. + +----- +0.6c6 +----- + + * Added ``--egg-path`` option to ``develop`` command, allowing you to force + ``.egg-link`` files to use relative paths (allowing them to be shared across + platforms on a networked drive). + + * Fix not building binary RPMs correctly. + + * Fix "eggsecutables" (such as setuptools' own egg) only being runnable with + bash-compatible shells. + + * Fix ``#!`` parsing problems in Windows ``.exe`` script wrappers, when there + was whitespace inside a quoted argument or at the end of the ``#!`` line + (a regression introduced in 0.6c4). + + * Fix ``test`` command possibly failing if an older version of the project + being tested was installed on ``sys.path`` ahead of the test source + directory. + + * Fix ``find_packages()`` treating ``ez_setup`` and directories with ``.`` in + their names as packages. + +----- +0.6c5 +----- + + * Fix uploaded ``bdist_rpm`` packages being described as ``bdist_egg`` + packages under Python versions less than 2.5. + + * Fix uploaded ``bdist_wininst`` packages being described as suitable for + "any" version by Python 2.5, even if a ``--target-version`` was specified. + +----- +0.6c4 +----- + + * Overhauled Windows script wrapping to support ``bdist_wininst`` better. + Scripts installed with ``bdist_wininst`` will always use ``#!python.exe`` or + ``#!pythonw.exe`` as the executable name (even when built on non-Windows + platforms!), and the wrappers will look for the executable in the script's + parent directory (which should find the right version of Python). + + * Fix ``upload`` command not uploading files built by ``bdist_rpm`` or + ``bdist_wininst`` under Python 2.3 and 2.4. + + * Add support for "eggsecutable" headers: a ``#!/bin/sh`` script that is + prepended to an ``.egg`` file to allow it to be run as a script on Unix-ish + platforms. (This is mainly so that setuptools itself can have a single-file + installer on Unix, without doing multiple downloads, dealing with firewalls, + etc.) + + * Fix problem with empty revision numbers in Subversion 1.4 ``entries`` files + + * Use cross-platform relative paths in ``easy-install.pth`` when doing + ``develop`` and the source directory is a subdirectory of the installation + target directory. + + * Fix a problem installing eggs with a system packaging tool if the project + contained an implicit namespace package; for example if the ``setup()`` + listed a namespace package ``foo.bar`` without explicitly listing ``foo`` + as a namespace package. + +----- +0.6c3 +----- + + * Fixed breakages caused by Subversion 1.4's new "working copy" format + +----- +0.6c2 +----- + + * The ``ez_setup`` module displays the conflicting version of setuptools (and + its installation location) when a script requests a version that's not + available. + + * Running ``setup.py develop`` on a setuptools-using project will now install + setuptools if needed, instead of only downloading the egg. + +----- +0.6c1 +----- + + * Fixed ``AttributeError`` when trying to download a ``setup_requires`` + dependency when a distribution lacks a ``dependency_links`` setting. + + * Made ``zip-safe`` and ``not-zip-safe`` flag files contain a single byte, so + as to play better with packaging tools that complain about zero-length + files. + + * Made ``setup.py develop`` respect the ``--no-deps`` option, which it + previously was ignoring. + + * Support ``extra_path`` option to ``setup()`` when ``install`` is run in + backward-compatibility mode. + + * Source distributions now always include a ``setup.cfg`` file that explicitly + sets ``egg_info`` options such that they produce an identical version number + to the source distribution's version number. (Previously, the default + version number could be different due to the use of ``--tag-date``, or if + the version was overridden on the command line that built the source + distribution.) + +----- +0.6b4 +----- + + * Fix ``register`` not obeying name/version set by ``egg_info`` command, if + ``egg_info`` wasn't explicitly run first on the same command line. + + * Added ``--no-date`` and ``--no-svn-revision`` options to ``egg_info`` + command, to allow suppressing tags configured in ``setup.cfg``. + + * Fixed redundant warnings about missing ``README`` file(s); it should now + appear only if you are actually a source distribution. + +----- +0.6b3 +----- + + * Fix ``bdist_egg`` not including files in subdirectories of ``.egg-info``. + + * Allow ``.py`` files found by the ``include_package_data`` option to be + automatically included. Remove duplicate data file matches if both + ``include_package_data`` and ``package_data`` are used to refer to the same + files. + +----- +0.6b1 +----- + + * Strip ``module`` from the end of compiled extension modules when computing + the name of a ``.py`` loader/wrapper. (Python's import machinery ignores + this suffix when searching for an extension module.) + +------ +0.6a11 +------ + + * Added ``test_loader`` keyword to support custom test loaders + + * Added ``setuptools.file_finders`` entry point group to allow implementing + revision control plugins. + + * Added ``--identity`` option to ``upload`` command. + + * Added ``dependency_links`` to allow specifying URLs for ``--find-links``. + + * Enhanced test loader to scan packages as well as modules, and call + ``additional_tests()`` if present to get non-unittest tests. + + * Support namespace packages in conjunction with system packagers, by omitting + the installation of any ``__init__.py`` files for namespace packages, and + adding a special ``.pth`` file to create a working package in + ``sys.modules``. + + * Made ``--single-version-externally-managed`` automatic when ``--root`` is + used, so that most system packagers won't require special support for + setuptools. + + * Fixed ``setup_requires``, ``tests_require``, etc. not using ``setup.cfg`` or + other configuration files for their option defaults when installing, and + also made the install use ``--multi-version`` mode so that the project + directory doesn't need to support .pth files. + + * ``MANIFEST.in`` is now forcibly closed when any errors occur while reading + it. Previously, the file could be left open and the actual error would be + masked by problems trying to remove the open file on Windows systems. + +------ +0.6a10 +------ + + * Fixed the ``develop`` command ignoring ``--find-links``. + +----- +0.6a9 +----- + + * The ``sdist`` command no longer uses the traditional ``MANIFEST`` file to + create source distributions. ``MANIFEST.in`` is still read and processed, + as are the standard defaults and pruning. But the manifest is built inside + the project's ``.egg-info`` directory as ``SOURCES.txt``, and it is rebuilt + every time the ``egg_info`` command is run. + + * Added the ``include_package_data`` keyword to ``setup()``, allowing you to + automatically include any package data listed in revision control or + ``MANIFEST.in`` + + * Added the ``exclude_package_data`` keyword to ``setup()``, allowing you to + trim back files included via the ``package_data`` and + ``include_package_data`` options. + + * Fixed ``--tag-svn-revision`` not working when run from a source + distribution. + + * Added warning for namespace packages with missing ``declare_namespace()`` + + * Added ``tests_require`` keyword to ``setup()``, so that e.g. packages + requiring ``nose`` to run unit tests can make this dependency optional + unless the ``test`` command is run. + + * Made all commands that use ``easy_install`` respect its configuration + options, as this was causing some problems with ``setup.py install``. + + * Added an ``unpack_directory()`` driver to ``setuptools.archive_util``, so + that you can process a directory tree through a processing filter as if it + were a zipfile or tarfile. + + * Added an internal ``install_egg_info`` command to use as part of old-style + ``install`` operations, that installs an ``.egg-info`` directory with the + package. + + * Added a ``--single-version-externally-managed`` option to the ``install`` + command so that you can more easily wrap a "flat" egg in a system package. + + * Enhanced ``bdist_rpm`` so that it installs single-version eggs that + don't rely on a ``.pth`` file. The ``--no-egg`` option has been removed, + since all RPMs are now built in a more backwards-compatible format. + + * Support full roundtrip translation of eggs to and from ``bdist_wininst`` + format. Running ``bdist_wininst`` on a setuptools-based package wraps the + egg in an .exe that will safely install it as an egg (i.e., with metadata + and entry-point wrapper scripts), and ``easy_install`` can turn the .exe + back into an ``.egg`` file or directory and install it as such. + + +----- +0.6a8 +----- + + * Fixed some problems building extensions when Pyrex was installed, especially + with Python 2.4 and/or packages using SWIG. + + * Made ``develop`` command accept all the same options as ``easy_install``, + and use the ``easy_install`` command's configuration settings as defaults. + + * Made ``egg_info --tag-svn-revision`` fall back to extracting the revision + number from ``PKG-INFO`` in case it is being run on a source distribution of + a snapshot taken from a Subversion-based project. + + * Automatically detect ``.dll``, ``.so`` and ``.dylib`` files that are being + installed as data, adding them to ``native_libs.txt`` automatically. + + * Fixed some problems with fresh checkouts of projects that don't include + ``.egg-info/PKG-INFO`` under revision control and put the project's source + code directly in the project directory. If such a package had any + requirements that get processed before the ``egg_info`` command can be run, + the setup scripts would fail with a "Missing 'Version:' header and/or + PKG-INFO file" error, because the egg runtime interpreted the unbuilt + metadata in a directory on ``sys.path`` (i.e. the current directory) as + being a corrupted egg. Setuptools now monkeypatches the distribution + metadata cache to pretend that the egg has valid version information, until + it has a chance to make it actually be so (via the ``egg_info`` command). + +----- +0.6a5 +----- + + * Fixed missing gui/cli .exe files in distribution. Fixed bugs in tests. + +----- +0.6a3 +----- + + * Added ``gui_scripts`` entry point group to allow installing GUI scripts + on Windows and other platforms. (The special handling is only for Windows; + other platforms are treated the same as for ``console_scripts``.) + +----- +0.6a2 +----- + + * Added ``console_scripts`` entry point group to allow installing scripts + without the need to create separate script files. On Windows, console + scripts get an ``.exe`` wrapper so you can just type their name. On other + platforms, the scripts are written without a file extension. + +----- +0.6a1 +----- + + * Added support for building "old-style" RPMs that don't install an egg for + the target package, using a ``--no-egg`` option. + + * The ``build_ext`` command now works better when using the ``--inplace`` + option and multiple Python versions. It now makes sure that all extensions + match the current Python version, even if newer copies were built for a + different Python version. + + * The ``upload`` command no longer attaches an extra ``.zip`` when uploading + eggs, as PyPI now supports egg uploads without trickery. + + * The ``ez_setup`` script/module now displays a warning before downloading + the setuptools egg, and attempts to check the downloaded egg against an + internal MD5 checksum table. + + * Fixed the ``--tag-svn-revision`` option of ``egg_info`` not finding the + latest revision number; it was using the revision number of the directory + containing ``setup.py``, not the highest revision number in the project. + + * Added ``eager_resources`` setup argument + + * The ``sdist`` command now recognizes Subversion "deleted file" entries and + does not include them in source distributions. + + * ``setuptools`` now embeds itself more thoroughly into the distutils, so that + other distutils extensions (e.g. py2exe, py2app) will subclass setuptools' + versions of things, rather than the native distutils ones. + + * Added ``entry_points`` and ``setup_requires`` arguments to ``setup()``; + ``setup_requires`` allows you to automatically find and download packages + that are needed in order to *build* your project (as opposed to running it). + + * ``setuptools`` now finds its commands, ``setup()`` argument validators, and + metadata writers using entry points, so that they can be extended by + third-party packages. See `Creating distutils Extensions + `_ + for more details. + + * The vestigial ``depends`` command has been removed. It was never finished + or documented, and never would have worked without EasyInstall - which it + pre-dated and was never compatible with. + +------ +0.5a12 +------ + + * The zip-safety scanner now checks for modules that might be used with + ``python -m``, and marks them as unsafe for zipping, since Python 2.4 can't + handle ``-m`` on zipped modules. + +------ +0.5a11 +------ + + * Fix breakage of the "develop" command that was caused by the addition of + ``--always-unzip`` to the ``easy_install`` command. + +----- +0.5a9 +----- + + * Include ``svn:externals`` directories in source distributions as well as + normal subversion-controlled files and directories. + + * Added ``exclude=patternlist`` option to ``setuptools.find_packages()`` + + * Changed --tag-svn-revision to include an "r" in front of the revision number + for better readability. + + * Added ability to build eggs without including source files (except for any + scripts, of course), using the ``--exclude-source-files`` option to + ``bdist_egg``. + + * ``setup.py install`` now automatically detects when an "unmanaged" package + or module is going to be on ``sys.path`` ahead of a package being installed, + thereby preventing the newer version from being imported. If this occurs, + a warning message is output to ``sys.stderr``, but installation proceeds + anyway. The warning message informs the user what files or directories + need deleting, and advises them they can also use EasyInstall (with the + ``--delete-conflicting`` option) to do it automatically. + + * The ``egg_info`` command now adds a ``top_level.txt`` file to the metadata + directory that lists all top-level modules and packages in the distribution. + This is used by the ``easy_install`` command to find possibly-conflicting + "unmanaged" packages when installing the distribution. + + * Added ``zip_safe`` and ``namespace_packages`` arguments to ``setup()``. + Added package analysis to determine zip-safety if the ``zip_safe`` flag + is not given, and advise the author regarding what code might need changing. + + * Fixed the swapped ``-d`` and ``-b`` options of ``bdist_egg``. + +----- +0.5a8 +----- + + * The "egg_info" command now always sets the distribution metadata to "safe" + forms of the distribution name and version, so that distribution files will + be generated with parseable names (i.e., ones that don't include '-' in the + name or version). Also, this means that if you use the various ``--tag`` + options of "egg_info", any distributions generated will use the tags in the + version, not just egg distributions. + + * Added support for defining command aliases in distutils configuration files, + under the "[aliases]" section. To prevent recursion and to allow aliases to + call the command of the same name, a given alias can be expanded only once + per command-line invocation. You can define new aliases with the "alias" + command, either for the local, global, or per-user configuration. + + * Added "rotate" command to delete old distribution files, given a set of + patterns to match and the number of files to keep. (Keeps the most + recently-modified distribution files matching each pattern.) + + * Added "saveopts" command that saves all command-line options for the current + invocation to the local, global, or per-user configuration file. Useful for + setting defaults without having to hand-edit a configuration file. + + * Added a "setopt" command that sets a single option in a specified distutils + configuration file. + +----- +0.5a7 +----- + + * Added "upload" support for egg and source distributions, including a bug + fix for "upload" and a temporary workaround for lack of .egg support in + PyPI. + +----- +0.5a6 +----- + + * Beefed up the "sdist" command so that if you don't have a MANIFEST.in, it + will include all files under revision control (CVS or Subversion) in the + current directory, and it will regenerate the list every time you create a + source distribution, not just when you tell it to. This should make the + default "do what you mean" more often than the distutils' default behavior + did, while still retaining the old behavior in the presence of MANIFEST.in. + + * Fixed the "develop" command always updating .pth files, even if you + specified ``-n`` or ``--dry-run``. + + * Slightly changed the format of the generated version when you use + ``--tag-build`` on the "egg_info" command, so that you can make tagged + revisions compare *lower* than the version specified in setup.py (e.g. by + using ``--tag-build=dev``). + +----- +0.5a5 +----- + + * Added ``develop`` command to ``setuptools``-based packages. This command + installs an ``.egg-link`` pointing to the package's source directory, and + script wrappers that ``execfile()`` the source versions of the package's + scripts. This lets you put your development checkout(s) on sys.path without + having to actually install them. (To uninstall the link, use + use ``setup.py develop --uninstall``.) + + * Added ``egg_info`` command to ``setuptools``-based packages. This command + just creates or updates the "projectname.egg-info" directory, without + building an egg. (It's used by the ``bdist_egg``, ``test``, and ``develop`` + commands.) + + * Enhanced the ``test`` command so that it doesn't install the package, but + instead builds any C extensions in-place, updates the ``.egg-info`` + metadata, adds the source directory to ``sys.path``, and runs the tests + directly on the source. This avoids an "unmanaged" installation of the + package to ``site-packages`` or elsewhere. + + * Made ``easy_install`` a standard ``setuptools`` command, moving it from + the ``easy_install`` module to ``setuptools.command.easy_install``. Note + that if you were importing or extending it, you must now change your imports + accordingly. ``easy_install.py`` is still installed as a script, but not as + a module. + +----- +0.5a4 +----- + + * Setup scripts using setuptools can now list their dependencies directly in + the setup.py file, without having to manually create a ``depends.txt`` file. + The ``install_requires`` and ``extras_require`` arguments to ``setup()`` + are used to create a dependencies file automatically. If you are manually + creating ``depends.txt`` right now, please switch to using these setup + arguments as soon as practical, because ``depends.txt`` support will be + removed in the 0.6 release cycle. For documentation on the new arguments, + see the ``setuptools.dist.Distribution`` class. + + * Setup scripts using setuptools now always install using ``easy_install`` + internally, for ease of uninstallation and upgrading. + +----- +0.5a1 +----- + + * Added support for "self-installation" bootstrapping. Packages can now + include ``ez_setup.py`` in their source distribution, and add the following + to their ``setup.py``, in order to automatically bootstrap installation of + setuptools as part of their setup process:: + + from ez_setup import use_setuptools + use_setuptools() + + from setuptools import setup + # etc... + +----- +0.4a2 +----- + + * Added ``ez_setup.py`` installer/bootstrap script to make initial setuptools + installation easier, and to allow distributions using setuptools to avoid + having to include setuptools in their source distribution. + + * All downloads are now managed by the ``PackageIndex`` class (which is now + subclassable and replaceable), so that embedders can more easily override + download logic, give download progress reports, etc. The class has also + been moved to the new ``setuptools.package_index`` module. + + * The ``Installer`` class no longer handles downloading, manages a temporary + directory, or tracks the ``zip_ok`` option. Downloading is now handled + by ``PackageIndex``, and ``Installer`` has become an ``easy_install`` + command class based on ``setuptools.Command``. + + * There is a new ``setuptools.sandbox.run_setup()`` API to invoke a setup + script in a directory sandbox, and a new ``setuptools.archive_util`` module + with an ``unpack_archive()`` API. These were split out of EasyInstall to + allow reuse by other tools and applications. + + * ``setuptools.Command`` now supports reinitializing commands using keyword + arguments to set/reset options. Also, ``Command`` subclasses can now set + their ``command_consumes_arguments`` attribute to ``True`` in order to + receive an ``args`` option containing the rest of the command line. + +----- +0.3a2 +----- + + * Added new options to ``bdist_egg`` to allow tagging the egg's version number + with a subversion revision number, the current date, or an explicit tag + value. Run ``setup.py bdist_egg --help`` to get more information. + + * Misc. bug fixes + +----- +0.3a1 +----- + + * Initial release. + + diff --git a/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/base.txt b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/base.txt new file mode 100644 index 0000000..21a0ccd --- /dev/null +++ b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/base.txt @@ -0,0 +1,6 @@ +{{ fullname }} +{{ underline }} + +.. currentmodule:: {{ module }} + +.. auto{{ objtype }}:: {{ objname }} diff --git a/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/class.txt b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/class.txt new file mode 100644 index 0000000..40494da --- /dev/null +++ b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/class.txt @@ -0,0 +1,30 @@ +{{ fullname }} +{{ underline }} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} + + {% block methods %} + .. automethod:: __init__ + + {% if methods %} + .. rubric:: Methods + + .. autosummary:: + {% for item in methods %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + .. rubric:: Attributes + + .. autosummary:: + {% for item in attributes %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/module.txt b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/module.txt new file mode 100644 index 0000000..c14456b --- /dev/null +++ b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/sphinx/ext/autosummary/templates/autosummary/module.txt @@ -0,0 +1,37 @@ +{{ fullname }} +{{ underline }} + +.. automodule:: {{ fullname }} + + {% block functions %} + {% if functions %} + .. rubric:: Functions + + .. autosummary:: + {% for item in functions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block classes %} + {% if classes %} + .. rubric:: Classes + + .. autosummary:: + {% for item in classes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block exceptions %} + {% if exceptions %} + .. rubric:: Exceptions + + .. autosummary:: + {% for item in exceptions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/contents.txt b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/contents.txt new file mode 100644 index 0000000..9a93be9 --- /dev/null +++ b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/contents.txt @@ -0,0 +1,6 @@ +test-only-directive +=================== + +.. toctree:: + + only diff --git a/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/only.txt b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/only.txt new file mode 100644 index 0000000..4a3eb48 --- /dev/null +++ b/doc/_sources/sphinx/python-2.7.5/Lib/site-packages/tests/roots/test-only-directive/only.txt @@ -0,0 +1,203 @@ + +1. Sections in only directives +============================== + +Testing sections in only directives. + +.. only:: nonexisting_tag + + Skipped Section + --------------- + Should not be here. + +.. only:: not nonexisting_tag + + 1.1. Section + ------------ + Should be here. + +1.2. Section +------------ + +.. only:: not nonexisting_tag + + 1.2.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +.. only:: nonexisting_tag + + Skipped Subsection + ~~~~~~~~~~~~~~~~~~ + Should not be here. + +1.3. Section +------------ + +1.3.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.4. Section +------------ + +.. only:: not nonexisting_tag + + 1.4.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.5. Section +------------ + +.. only:: not nonexisting_tag + + 1.5.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.5.2. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.6. Section +------------ + +1.6.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +.. only:: not nonexisting_tag + + 1.6.2. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.6.3. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.7. Section +------------ + +1.7.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +.. only:: not nonexisting_tag + + 1.7.1.1. Subsubsection + ...................... + Should be here. + +1.8. Section +------------ + +1.8.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.8.1.1. Subsubsection +...................... +Should be here. + +.. only:: not nonexisting_tag + + 1.8.1.2. Subsubsection + ...................... + Should be here. + +1.9. Section +------------ + +.. only:: nonexisting_tag + + Skipped Subsection + ~~~~~~~~~~~~~~~~~~ + +1.9.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.9.1.1. Subsubsection +...................... +Should be here. + +.. only:: not nonexisting_tag + + 1.10. Section + ------------- + Should be here. + +1.11. Section +------------- + +Text before subsection 11.1. + +.. only:: not nonexisting_tag + + More text before subsection 11.1. + + 1.11.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + +Text after subsection 11.1. + +.. only:: not nonexisting_tag + + 1.12. Section + ------------- + Should be here. + + 1.12.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + + 1.13. Section + ------------- + Should be here. + +.. only:: not nonexisting_tag + + 1.14. Section + ------------- + Should be here. + + .. only:: not nonexisting_tag + + 1.14.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + + 1.15. Section + ------------- + Should be here. + +.. only:: nonexisting_tag + + Skipped document level heading + ============================== + Should not be here. + +.. only:: not nonexisting_tag + + 2. Included document level heading + ================================== + Should be here. + +3. Document level heading +========================= +Should be here. + +.. only:: nonexisting_tag + + Skipped document level heading + ============================== + Should not be here. + +.. only:: not nonexisting_tag + + 4. Another included document level heading + ========================================== + Should be here. diff --git a/doc/_static/AOBias_0_0.png b/doc/_static/AOBias_0_0.png new file mode 100644 index 0000000..1e049c0 Binary files /dev/null and b/doc/_static/AOBias_0_0.png differ diff --git a/doc/_static/AOBias_0_3.png b/doc/_static/AOBias_0_3.png new file mode 100644 index 0000000..e9f0cb2 Binary files /dev/null and b/doc/_static/AOBias_0_3.png differ diff --git a/doc/_static/AO_Radius_1.png b/doc/_static/AO_Radius_1.png new file mode 100644 index 0000000..9e66615 Binary files /dev/null and b/doc/_static/AO_Radius_1.png differ diff --git a/doc/_static/AO_Radius_4.png b/doc/_static/AO_Radius_4.png new file mode 100644 index 0000000..c4bbd92 Binary files /dev/null and b/doc/_static/AO_Radius_4.png differ diff --git a/doc/_static/BackgroundAO_OFF.png b/doc/_static/BackgroundAO_OFF.png new file mode 100644 index 0000000..91e3452 Binary files /dev/null and b/doc/_static/BackgroundAO_OFF.png differ diff --git a/doc/_static/BackgroundAO_ON.png b/doc/_static/BackgroundAO_ON.png new file mode 100644 index 0000000..19d9f7a Binary files /dev/null and b/doc/_static/BackgroundAO_ON.png differ diff --git a/doc/_static/Blur_Radius_4.png b/doc/_static/Blur_Radius_4.png new file mode 100644 index 0000000..0b3f134 Binary files /dev/null and b/doc/_static/Blur_Radius_4.png differ diff --git a/doc/_static/Blur_Sharpness_0.png b/doc/_static/Blur_Sharpness_0.png new file mode 100644 index 0000000..84acbda Binary files /dev/null and b/doc/_static/Blur_Sharpness_0.png differ diff --git a/doc/_static/Blur_Sharpness_8.png b/doc/_static/Blur_Sharpness_8.png new file mode 100644 index 0000000..abba7a8 Binary files /dev/null and b/doc/_static/Blur_Sharpness_8.png differ diff --git a/doc/_static/DINWebPro-Black.woff b/doc/_static/DINWebPro-Black.woff new file mode 100644 index 0000000..2758601 Binary files /dev/null and b/doc/_static/DINWebPro-Black.woff differ diff --git a/doc/_static/DINWebPro-BlackIta.woff b/doc/_static/DINWebPro-BlackIta.woff new file mode 100644 index 0000000..b623216 Binary files /dev/null and b/doc/_static/DINWebPro-BlackIta.woff differ diff --git a/doc/_static/DINWebPro-Bold.woff b/doc/_static/DINWebPro-Bold.woff new file mode 100644 index 0000000..324419c Binary files /dev/null and b/doc/_static/DINWebPro-Bold.woff differ diff --git a/doc/_static/DINWebPro-BoldIta.woff b/doc/_static/DINWebPro-BoldIta.woff new file mode 100644 index 0000000..755a367 Binary files /dev/null and b/doc/_static/DINWebPro-BoldIta.woff differ diff --git a/doc/_static/DINWebPro-Ita.woff b/doc/_static/DINWebPro-Ita.woff new file mode 100644 index 0000000..12fee2f Binary files /dev/null and b/doc/_static/DINWebPro-Ita.woff differ diff --git a/doc/_static/DINWebPro-Light.woff b/doc/_static/DINWebPro-Light.woff new file mode 100644 index 0000000..2ddb1ba Binary files /dev/null and b/doc/_static/DINWebPro-Light.woff differ diff --git a/doc/_static/DINWebPro-LightIta.woff b/doc/_static/DINWebPro-LightIta.woff new file mode 100644 index 0000000..5da47d6 Binary files /dev/null and b/doc/_static/DINWebPro-LightIta.woff differ diff --git a/doc/_static/DINWebPro-Medium.woff b/doc/_static/DINWebPro-Medium.woff new file mode 100644 index 0000000..d720c48 Binary files /dev/null and b/doc/_static/DINWebPro-Medium.woff differ diff --git a/doc/_static/DINWebPro-MediumIta.woff b/doc/_static/DINWebPro-MediumIta.woff new file mode 100644 index 0000000..b340634 Binary files /dev/null and b/doc/_static/DINWebPro-MediumIta.woff differ diff --git a/doc/_static/DINWebPro.woff b/doc/_static/DINWebPro.woff new file mode 100644 index 0000000..2056687 Binary files /dev/null and b/doc/_static/DINWebPro.woff differ diff --git a/doc/_static/ForegroundAO_OFF.png b/doc/_static/ForegroundAO_OFF.png new file mode 100644 index 0000000..a78be1a Binary files /dev/null and b/doc/_static/ForegroundAO_OFF.png differ diff --git a/doc/_static/ForegroundAO_ON.png b/doc/_static/ForegroundAO_ON.png new file mode 100644 index 0000000..396ce3c Binary files /dev/null and b/doc/_static/ForegroundAO_ON.png differ diff --git a/doc/_static/No_Blur.png b/doc/_static/No_Blur.png new file mode 100644 index 0000000..eb3b8ac Binary files /dev/null and b/doc/_static/No_Blur.png differ diff --git a/doc/_static/application.css b/doc/_static/application.css new file mode 100644 index 0000000..dfc7d45 --- /dev/null +++ b/doc/_static/application.css @@ -0,0 +1,8998 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} +audio, +canvas, +video { + display: inline-block; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +body { + margin: 0; +} +a { + background: transparent; +} +a:focus { + outline: thin dotted; +} +a:active, +a:hover { + outline: 0; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} +mark { + background: #ff0; + color: #000; +} +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} +pre { + white-space: pre-wrap; +} +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 0; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +button, +input, +select, +textarea { + font-family: inherit; + font-size: 100%; + margin: 0; +} +button, +input { + line-height: normal; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +textarea { + overflow: auto; + vertical-align: top; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 2cm .5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +*, +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 62.5%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "DINWebPro", Trebuchet, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 1.5; + color: #333333; + background-color: #fcfcfc; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #76b900; + text-decoration: none; +} +a:hover, +a:focus { + color: #76b900; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +img { + vertical-align: middle; +} +.img-responsive { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 0px; +} +.img-thumbnail { + padding: 4px; + line-height: 1.5; + background-color: #fcfcfc; + border: 1px solid #dddddd; + border-radius: 0px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 24px; + margin-bottom: 24px; + border: 0; + border-top: 1px solid #efefef; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: "DINWebPro", Trebuchet, Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 1.1; + color: #004e49; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #999999; +} +h1, +h2, +h3 { + margin-top: 24px; + margin-bottom: 12px; +} +h1 small, +h2 small, +h3 small, +h1 .small, +h2 .small, +h3 .small { + font-size: 65%; +} +h4, +h5, +h6 { + margin-top: 12px; + margin-bottom: 12px; +} +h4 small, +h5 small, +h6 small, +h4 .small, +h5 .small, +h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 41px; +} +h2, +.h2 { + font-size: 34px; +} +h3, +.h3 { + font-size: 28px; +} +h4, +.h4 { + font-size: 20px; +} +h5, +.h5 { + font-size: 16px; +} +h6, +.h6 { + font-size: 14px; +} +p { + margin: 0 0 12px; +} +.lead { + margin-bottom: 24px; + font-size: 18px; + font-weight: 200; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 24px; + } +} +small, +.small { + font-size: 85%; +} +cite { + font-style: normal; +} +.text-muted { + color: #999999; +} +.text-primary { + color: #76b900; +} +.text-primary:hover { + color: #558600; +} +.text-warning { + color: #8a6d3b; +} +.text-warning:hover { + color: #66512c; +} +.text-danger { + color: #a94442; +} +.text-danger:hover { + color: #843534; +} +.text-success { + color: #3c763d; +} +.text-success:hover { + color: #2b542c; +} +.text-info { + color: #31708f; +} +.text-info:hover { + color: #245269; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.page-header { + padding-bottom: 11px; + margin: 48px 0 24px; + border-bottom: 1px solid #efefef; +} +ul, +ol { + margin-top: 0; + margin-bottom: 12px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; +} +.list-inline > li:first-child { + padding-left: 0; +} +dl { + margin-top: 0; + margin-bottom: 24px; +} +dt, +dd { + line-height: 1.5; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 992px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + content: " "; + display: table; + } + .dl-horizontal dd:after { + clear: both; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + content: " "; + display: table; + } + .dl-horizontal dd:after { + clear: both; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 12px 24px; + margin: 0 0 24px; + border-left: 5px solid #efefef; +} +blockquote p { + font-size: 20px; + font-weight: 300; + line-height: 1.25; +} +blockquote p:last-child { + margin-bottom: 0; +} +blockquote small, +blockquote .small { + display: block; + line-height: 1.5; + color: #999999; +} +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #efefef; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small, +blockquote.pull-right .small { + text-align: right; +} +blockquote.pull-right small:before, +blockquote.pull-right .small:before { + content: ''; +} +blockquote.pull-right small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +blockquote:before, +blockquote:after { + content: ""; +} +address { + margin-bottom: 24px; + font-style: normal; + line-height: 1.5; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + white-space: nowrap; + border-radius: 0px; +} +pre { + display: block; + padding: 11.5px; + margin: 0 0 12px; + font-size: 15px; + line-height: 1.5; + word-break: break-all; + word-wrap: break-word; + color: #595959; + background-color: #f5f5f5; + border: 1px solid #cccccc; + border-radius: 0px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + margin-right: auto; + margin-left: auto; + padding-left: 10px; + padding-right: 10px; +} +.container:before, +.container:after { + content: " "; + display: table; +} +.container:after { + clear: both; +} +.container:before, +.container:after { + content: " "; + display: table; +} +.container:after { + clear: both; +} +@media (min-width: 768px) { + .container { + width: 740px; + } +} +@media (min-width: 992px) { + .container { + width: 960px; + } +} +@media (min-width: 1200px) { + .container { + width: 1160px; + } +} +.row { + margin-left: 10px; + margin-right: -10px; +} +.row:before, +.row:after { + content: " "; + display: table; +} +.row:after { + clear: both; +} +.row:before, +.row:after { + content: " "; + display: table; +} +.row:after { + clear: both; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 10px; + padding-right: 10px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666666666666%; +} +.col-xs-10 { + width: 83.33333333333334%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666666666666%; +} +.col-xs-7 { + width: 58.333333333333336%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666666666667%; +} +.col-xs-4 { + width: 33.33333333333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.666666666666664%; +} +.col-xs-1 { + width: 8.333333333333332%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666666666666%; +} +.col-xs-pull-10 { + right: 83.33333333333334%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666666666666%; +} +.col-xs-pull-7 { + right: 58.333333333333336%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666666666667%; +} +.col-xs-pull-4 { + right: 33.33333333333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.666666666666664%; +} +.col-xs-pull-1 { + right: 8.333333333333332%; +} +.col-xs-pull-0 { + right: 0%; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666666666666%; +} +.col-xs-push-10 { + left: 83.33333333333334%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666666666666%; +} +.col-xs-push-7 { + left: 58.333333333333336%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666666666667%; +} +.col-xs-push-4 { + left: 33.33333333333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.666666666666664%; +} +.col-xs-push-1 { + left: 8.333333333333332%; +} +.col-xs-push-0 { + left: 0%; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666666666666%; +} +.col-xs-offset-10 { + margin-left: 83.33333333333334%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666666666666%; +} +.col-xs-offset-7 { + margin-left: 58.333333333333336%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666666666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.666666666666664%; +} +.col-xs-offset-1 { + margin-left: 8.333333333333332%; +} +.col-xs-offset-0 { + margin-left: 0%; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666666666666%; + } + .col-sm-10 { + width: 83.33333333333334%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666666666666%; + } + .col-sm-7 { + width: 58.333333333333336%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666666666667%; + } + .col-sm-4 { + width: 33.33333333333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.666666666666664%; + } + .col-sm-1 { + width: 8.333333333333332%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666666666666%; + } + .col-sm-pull-10 { + right: 83.33333333333334%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666666666666%; + } + .col-sm-pull-7 { + right: 58.333333333333336%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666666666667%; + } + .col-sm-pull-4 { + right: 33.33333333333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.666666666666664%; + } + .col-sm-pull-1 { + right: 8.333333333333332%; + } + .col-sm-pull-0 { + right: 0%; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666666666666%; + } + .col-sm-push-10 { + left: 83.33333333333334%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666666666666%; + } + .col-sm-push-7 { + left: 58.333333333333336%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666666666667%; + } + .col-sm-push-4 { + left: 33.33333333333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.666666666666664%; + } + .col-sm-push-1 { + left: 8.333333333333332%; + } + .col-sm-push-0 { + left: 0%; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666666666666%; + } + .col-sm-offset-10 { + margin-left: 83.33333333333334%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666666666666%; + } + .col-sm-offset-7 { + margin-left: 58.333333333333336%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666666666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.666666666666664%; + } + .col-sm-offset-1 { + margin-left: 8.333333333333332%; + } + .col-sm-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666666666666%; + } + .col-md-10 { + width: 83.33333333333334%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666666666666%; + } + .col-md-7 { + width: 58.333333333333336%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666666666667%; + } + .col-md-4 { + width: 33.33333333333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.666666666666664%; + } + .col-md-1 { + width: 8.333333333333332%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666666666666%; + } + .col-md-pull-10 { + right: 83.33333333333334%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666666666666%; + } + .col-md-pull-7 { + right: 58.333333333333336%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666666666667%; + } + .col-md-pull-4 { + right: 33.33333333333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.666666666666664%; + } + .col-md-pull-1 { + right: 8.333333333333332%; + } + .col-md-pull-0 { + right: 0%; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666666666666%; + } + .col-md-push-10 { + left: 83.33333333333334%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666666666666%; + } + .col-md-push-7 { + left: 58.333333333333336%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666666666667%; + } + .col-md-push-4 { + left: 33.33333333333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.666666666666664%; + } + .col-md-push-1 { + left: 8.333333333333332%; + } + .col-md-push-0 { + left: 0%; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666666666666%; + } + .col-md-offset-10 { + margin-left: 83.33333333333334%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666666666666%; + } + .col-md-offset-7 { + margin-left: 58.333333333333336%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666666666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.666666666666664%; + } + .col-md-offset-1 { + margin-left: 8.333333333333332%; + } + .col-md-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666666666666%; + } + .col-lg-10 { + width: 83.33333333333334%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666666666666%; + } + .col-lg-7 { + width: 58.333333333333336%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666666666667%; + } + .col-lg-4 { + width: 33.33333333333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.666666666666664%; + } + .col-lg-1 { + width: 8.333333333333332%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666666666666%; + } + .col-lg-pull-10 { + right: 83.33333333333334%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666666666666%; + } + .col-lg-pull-7 { + right: 58.333333333333336%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666666666667%; + } + .col-lg-pull-4 { + right: 33.33333333333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.666666666666664%; + } + .col-lg-pull-1 { + right: 8.333333333333332%; + } + .col-lg-pull-0 { + right: 0%; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666666666666%; + } + .col-lg-push-10 { + left: 83.33333333333334%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666666666666%; + } + .col-lg-push-7 { + left: 58.333333333333336%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666666666667%; + } + .col-lg-push-4 { + left: 33.33333333333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.666666666666664%; + } + .col-lg-push-1 { + left: 8.333333333333332%; + } + .col-lg-push-0 { + left: 0%; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666666666666%; + } + .col-lg-offset-10 { + margin-left: 83.33333333333334%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666666666666%; + } + .col-lg-offset-7 { + margin-left: 58.333333333333336%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666666666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.666666666666664%; + } + .col-lg-offset-1 { + margin-left: 8.333333333333332%; + } + .col-lg-offset-0 { + margin-left: 0%; + } +} +table { + max-width: 100%; + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + margin-bottom: 24px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.5; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #dddddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #dddddd; +} +.table .table { + background-color: #fcfcfc; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + float: none; + display: table-cell; +} +.table > thead > tr > .active, +.table > tbody > tr > .active, +.table > tfoot > tr > .active, +.table > thead > .active > td, +.table > tbody > .active > td, +.table > tfoot > .active > td, +.table > thead > .active > th, +.table > tbody > .active > th, +.table > tfoot > .active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > .active:hover, +.table-hover > tbody > .active:hover > td, +.table-hover > tbody > .active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > .success, +.table > tbody > tr > .success, +.table > tfoot > tr > .success, +.table > thead > .success > td, +.table > tbody > .success > td, +.table > tfoot > .success > td, +.table > thead > .success > th, +.table > tbody > .success > th, +.table > tfoot > .success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > .success:hover, +.table-hover > tbody > .success:hover > td, +.table-hover > tbody > .success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > .danger, +.table > tbody > tr > .danger, +.table > tfoot > tr > .danger, +.table > thead > .danger > td, +.table > tbody > .danger > td, +.table > tfoot > .danger > td, +.table > thead > .danger > th, +.table > tbody > .danger > th, +.table > tfoot > .danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > .danger:hover, +.table-hover > tbody > .danger:hover > td, +.table-hover > tbody > .danger:hover > th { + background-color: #ebcccc; +} +.table > thead > tr > .warning, +.table > tbody > tr > .warning, +.table > tfoot > tr > .warning, +.table > thead > .warning > td, +.table > tbody > .warning > td, +.table > tfoot > .warning > td, +.table > thead > .warning > th, +.table > tbody > .warning > th, +.table > tfoot > .warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > .warning:hover, +.table-hover > tbody > .warning:hover > td, +.table-hover > tbody > .warning:hover > th { + background-color: #faf2cc; +} +@media (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 18px; + overflow-y: hidden; + overflow-x: scroll; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #dddddd; + -webkit-overflow-scrolling: touch; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 24px; + font-size: 24px; + line-height: inherit; + color: #595959; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + /* IE8-9 */ + line-height: normal; +} +input[type="file"] { + display: block; +} +select[multiple], +select[size] { + height: auto; +} +select optgroup { + font-size: inherit; + font-style: inherit; + font-family: inherit; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +input[type="number"]::-webkit-outer-spin-button, +input[type="number"]::-webkit-inner-spin-button { + height: auto; +} +output { + display: block; + padding-top: 7px; + font-size: 16px; + line-height: 1.5; + color: #999999; + vertical-align: middle; +} +.form-control { + display: block; + height: 38px; + padding: 6px 12px; + font-size: 16px; + line-height: 1.5; + color: #999999; + vertical-align: middle; + background-color: #ffffff; + background-image: none; + border: 1px solid #cccccc; + border-radius: 0px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control:-moz-placeholder { + color: #999999; +} +.form-control::-moz-placeholder { + color: #999999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999999; +} +.form-control::-webkit-input-placeholder { + color: #999999; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #efefef; +} +textarea.form-control { + height: auto; +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + display: block; + min-height: 24px; + margin-top: 10px; + margin-bottom: 10px; + padding-left: 20px; + vertical-align: middle; +} +.radio label, +.checkbox label { + display: inline; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +.radio[disabled], +.radio-inline[disabled], +.checkbox[disabled], +.checkbox-inline[disabled], +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"], +fieldset[disabled] .radio, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.input-sm { + height: 33px; + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 0px; +} +select.input-sm { + height: 33px; + line-height: 33px; +} +textarea.input-sm { + height: auto; +} +.input-lg { + height: 45px; + padding: 8px 16px; + font-size: 20px; + line-height: 1.33; + border-radius: 0px; +} +select.input-lg { + height: 45px; + line-height: 45px; +} +textarea.input-lg { + height: auto; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + border-color: #8a6d3b; + background-color: #fcf8e3; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + border-color: #a94442; + background-color: #f2dede; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + border-color: #3c763d; + background-color: #dff0d8; +} +.form-control-static { + margin-bottom: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + } + .form-inline select.form-control { + width: auto; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} +.form-horizontal .control-label, +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 31px; +} +.form-horizontal .form-group { + margin-left: -10px; + margin-right: -10px; +} +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + content: " "; + display: table; +} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + content: " "; + display: table; +} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-control-static { + padding-top: 7px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + } +} +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 16px; + line-height: 1.5; + border-radius: 0px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.btn:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + pointer-events: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #cccccc; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + color: #333333; + background-color: #ebebeb; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #ffffff; + border-color: #cccccc; +} +.btn-default .badge { + color: #ffffff; + background-color: #fff; +} +.btn-primary { + color: #ffffff; + background-color: #76b900; + border-color: #76b900; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #5c9000; + border-color: #4f7c00; +} +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #76b900; + border-color: #76b900; +} +.btn-primary .badge { + color: #76b900; + background-color: #fff; +} +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ed9c28; + border-color: #eb9316; +} +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d9534f; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #d2322d; + border-color: #c12e2a; +} +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d9534f; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-success { + color: #ffffff; + background-color: #76b900; + border-color: #76b900; +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #5c9000; + border-color: #4f7c00; +} +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #76b900; + border-color: #76b900; +} +.btn-success .badge { + color: #76b900; + background-color: #fff; +} +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #39b3d7; + border-color: #2aabd2; +} +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-link { + color: #76b900; + font-weight: normal; + cursor: pointer; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #76b900; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #999999; + text-decoration: none; +} +.btn-lg { + padding: 8px 16px; + font-size: 20px; + line-height: 1.33; + border-radius: 0px; +} +.btn-sm { + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 0px; +} +.btn-xs { + padding: 4px 6px; + font-size: 14px; + line-height: 1.5; + border-radius: 0px; +} +.btn-block { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + transition: height 0.35s ease; +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('glyphicons-halflings-regular.eot'); + src: url('glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('glyphicons-halflings-regular.woff') format('woff'), url('glyphicons-halflings-regular.ttf') format('truetype'), url('glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon:empty { + width: 1em; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 16px; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 11px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.5; + color: #595959; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + text-decoration: none; + color: #4c4c4c; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #76b900; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 14px; + line-height: 1.5; + color: #999999; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media (min-width: 992px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: none; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar:before, +.btn-toolbar:after { + content: " "; + display: table; +} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, +.btn-toolbar:after { + content: " "; + display: table; +} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar .btn-group { + float: left; +} +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group, +.btn-toolbar > .btn-group + .btn-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group-xs > .btn { + padding: 4px 6px; + font-size: 14px; + line-height: 1.5; + border-radius: 0px; + padding-top: 6.384px; + padding-bottom: 4.8px; +} +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 0px; + padding-top: 7.98px; + padding-bottom: 6px; +} +.btn-group-lg > .btn { + padding: 8px 16px; + font-size: 20px; + line-height: 1.33; + border-radius: 0px; + padding-top: 12.768px; + padding-bottom: 9.6px; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + content: " "; + display: table; +} +.btn-group-vertical > .btn-group:after { + clear: both; +} +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + content: " "; + display: table; +} +.btn-group-vertical > .btn-group:after { + clear: both; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 0px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-bottom-left-radius: 0px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child > .btn:last-child, +.btn-group-vertical > .btn-group:first-child > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + display: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-left: 0; + padding-right: 0; +} +.input-group .form-control { + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 45px; + padding: 8px 16px; + font-size: 20px; + line-height: 1.33; + border-radius: 0px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 45px; + line-height: 45px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 33px; + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 0px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 33px; + line-height: 33px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 16px; + font-weight: normal; + line-height: 1; + color: #999999; + text-align: center; + background-color: #efefef; + border: 1px solid #cccccc; + border-radius: 0px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 14px; + border-radius: 0px; +} +.input-group-addon.input-lg { + padding: 8px 16px; + font-size: 20px; + border-radius: 0px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + white-space: nowrap; +} +.input-group-btn:first-child > .btn { + margin-right: -1px; +} +.input-group-btn:last-child > .btn { + margin-left: -1px; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -4px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:active { + z-index: 2; +} +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.nav:before, +.nav:after { + content: " "; + display: table; +} +.nav:after { + clear: both; +} +.nav:before, +.nav:after { + content: " "; + display: table; +} +.nav:after { + clear: both; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #efefef; +} +.nav > li.disabled > a { + color: #999999; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #999999; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #efefef; + border-color: #76b900; +} +.nav .nav-divider { + height: 1px; + margin: 11px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #dddddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.5; + border: 1px solid transparent; + border-radius: 0px 0px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #efefef #efefef #dddddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #999999; + background-color: #fcfcfc; + border: 1px solid #dddddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 0px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 0px 0px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fcfcfc; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 0px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #ffffff; + background-color: #76b900; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 0px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 0px 0px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fcfcfc; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 24px; + border: 1px solid transparent; +} +.navbar:before, +.navbar:after { + content: " "; + display: table; +} +.navbar:after { + clear: both; +} +.navbar:before, +.navbar:after { + content: " "; + display: table; +} +.navbar:after { + clear: both; +} +@media (min-width: 992px) { + .navbar { + border-radius: 0px; + } +} +.navbar-header:before, +.navbar-header:after { + content: " "; + display: table; +} +.navbar-header:after { + clear: both; +} +.navbar-header:before, +.navbar-header:after { + content: " "; + display: table; +} +.navbar-header:after { + clear: both; +} +@media (min-width: 992px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + max-height: 340px; + overflow-x: visible; + padding-right: 10px; + padding-left: 10px; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse:before, +.navbar-collapse:after { + content: " "; + display: table; +} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, +.navbar-collapse:after { + content: " "; + display: table; +} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 992px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } +} +.container > .navbar-header, +.container > .navbar-collapse { + margin-right: -10px; + margin-left: -10px; +} +@media (min-width: 992px) { + .container > .navbar-header, + .container > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 992px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 992px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + padding: 13px 10px; + font-size: 20px; + line-height: 24px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +@media (min-width: 992px) { + .navbar > .container .navbar-brand { + margin-left: -10px; + } +} +.navbar-toggle { + position: relative; + float: right; + margin-right: 10px; + padding: 9px 10px; + margin-top: 8px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 0px; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 992px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 6.5px -10px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 24px; +} +@media (max-width: 991px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 24px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 992px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 13px; + padding-bottom: 13px; + } + .navbar-nav.navbar-right:last-child { + margin-right: -10px; + } +} +@media (min-width: 992px) { + .navbar-left { + float: left !important; + float: left; + } + .navbar-right { + float: right !important; + float: right; + } +} +.navbar-form { + margin-left: -10px; + margin-right: -10px; + padding: 10px 10px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 6px; + margin-bottom: 6px; +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + } + .navbar-form select.form-control { + width: auto; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} +@media (max-width: 991px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} +@media (min-width: 992px) { + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-form.navbar-right:last-child { + margin-right: -10px; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-nav.pull-right > li > .dropdown-menu, +.navbar-nav > li > .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar-btn { + margin-top: 6px; + margin-bottom: 6px; +} +.navbar-btn.btn-sm { + margin-top: 8.5px; + margin-bottom: 8.5px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 13px; + margin-bottom: 13px; +} +@media (min-width: 992px) { + .navbar-text { + float: left; + margin-left: 10px; + margin-right: 10px; + } + .navbar-text.navbar-right:last-child { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777777; +} +.navbar-default .navbar-nav > li > a { + color: #777777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #cccccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #dddddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #dddddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #cccccc; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: #e7e7e7; + color: #555555; +} +@media (max-width: 991px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #cccccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777777; +} +.navbar-default .navbar-link:hover { + color: #333333; +} +.navbar-inverse { + background-color: #000000; + border-color: #000000; +} +.navbar-inverse .navbar-brand { + color: #999999; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #ffffff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #707070; +} +.navbar-inverse .navbar-nav > li > a { + color: #999999; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #ffffff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #ffffff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #ffffff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #000000; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + background-color: transparent; + color: #ffffff; +} +@media (max-width: 991px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #000000; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #000000; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #999999; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #ffffff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #ffffff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #999999; +} +.navbar-inverse .navbar-link:hover { + color: #ffffff; +} +.breadcrumb { + padding: 8px 15px; + margin-top: 17px; + list-style: none; + background-color: #f5f5f5; + border-radius: 0px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + content: ">\00a0"; + padding: 0 5px; + color: #cccccc; +} +.breadcrumb > .active { + color: #999999; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 24px 0; + border-radius: 0px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + line-height: 1.5; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + margin-left: -1px; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 0px; + border-top-left-radius: 0px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-bottom-right-radius: 0px; + border-top-right-radius: 0px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + background-color: #efefef; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #ffffff; + background-color: #76b900; + border-color: #76b900; + cursor: default; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #999999; + background-color: #ffffff; + border-color: #dddddd; + cursor: not-allowed; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 8px 16px; + font-size: 20px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 0px; + border-top-left-radius: 0px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-bottom-right-radius: 0px; + border-top-right-radius: 0px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 14px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 0px; + border-top-left-radius: 0px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-bottom-right-radius: 0px; + border-top-right-radius: 0px; +} +.pager { + padding-left: 0; + margin: 24px 0; + list-style: none; + text-align: center; +} +.pager:before, +.pager:after { + content: " "; + display: table; +} +.pager:after { + clear: both; +} +.pager:before, +.pager:after { + content: " "; + display: table; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 0px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #efefef; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + background-color: #ffffff; + cursor: not-allowed; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +.label[href]:hover, +.label[href]:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #999999; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #808080; +} +.label-primary { + background-color: #76b900; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #558600; +} +.label-success { + background-color: #76b900; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #558600; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 14px; + font-weight: bold; + color: #ffffff; + line-height: 1; + vertical-align: baseline; + white-space: nowrap; + text-align: center; + background-color: #999999; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #76b900; + background-color: #ffffff; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + font-size: 24px; + font-weight: 200; + line-height: 2.25; + color: inherit; + background-color: #efefef; +} +.jumbotron h1, +.jumbotron .h1 { + line-height: 1; + color: inherit; +} +.jumbotron p { + line-height: 1.4; +} +.container .jumbotron { + border-radius: 0px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-left: 60px; + padding-right: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 72px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 24px; + line-height: 1.5; + background-color: #fcfcfc; + border: 1px solid #dddddd; + border-radius: 0px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + display: block; + max-width: 100%; + height: auto; + margin-left: auto; + margin-right: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #76b900; +} +.thumbnail .caption { + padding: 9px; + color: #333333; +} +.alert { + padding: 15px; + margin-bottom: 24px; + border: 1px solid transparent; + border-radius: 0px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable { + padding-right: 35px; +} +.alert-dismissable .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + background-color: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 24px; + margin-bottom: 24px; + background-color: #f5f5f5; + border-radius: 0px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 14px; + line-height: 24px; + color: #ffffff; + text-align: center; + background-color: #76b900; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .progress-bar { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #76b900; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + margin-bottom: 20px; + padding-left: 0; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; +} +.list-group-item:first-child { + border-top-right-radius: 0px; + border-top-left-radius: 0px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0px; + border-bottom-left-radius: 0px; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +a.list-group-item { + color: #555555; +} +a.list-group-item .list-group-item-heading { + color: #333333; +} +a.list-group-item:hover, +a.list-group-item:focus { + text-decoration: none; + background-color: #f5f5f5; +} +a.list-group-item.active, +a.list-group-item.active:hover, +a.list-group-item.active:focus { + z-index: 2; + color: #ffffff; + background-color: #76b900; + border-color: #76b900; +} +a.list-group-item.active .list-group-item-heading, +a.list-group-item.active:hover .list-group-item-heading, +a.list-group-item.active:focus .list-group-item-heading { + color: inherit; +} +a.list-group-item.active .list-group-item-text, +a.list-group-item.active:hover .list-group-item-text, +a.list-group-item.active:focus .list-group-item-text { + color: #d3ff86; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 24px; + background-color: #ffffff; + border: 1px solid transparent; + border-radius: 0px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-body:before, +.panel-body:after { + content: " "; + display: table; +} +.panel-body:after { + clear: both; +} +.panel-body:before, +.panel-body:after { + content: " "; + display: table; +} +.panel-body:after { + clear: both; +} +.panel > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item { + border-width: 1px 0; +} +.panel > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.panel > .list-group .list-group-item:last-child { + border-bottom: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table { + margin-bottom: 0; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive { + border-top: 1px solid #dddddd; +} +.panel > .table > tbody:first-child th, +.panel > .table > tbody:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:last-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:last-child > th, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-bordered > thead > tr:last-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; +} +.panel > .table-responsive { + border: 0; + margin-bottom: 0; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: -1px; + border-top-left-radius: -1px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 18px; + color: inherit; +} +.panel-title > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #dddddd; + border-bottom-right-radius: -1px; + border-bottom-left-radius: -1px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 0px; + overflow: hidden; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse .panel-body { + border-top: 1px solid #dddddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #dddddd; +} +.panel-default { + border-color: #dddddd; +} +.panel-default > .panel-heading { + color: #595959; + background-color: #f5f5f5; + border-color: #dddddd; +} +.panel-default > .panel-heading + .panel-collapse .panel-body { + border-top-color: #dddddd; +} +.panel-default > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #dddddd; +} +.panel-primary { + border-color: #76b900; +} +.panel-primary > .panel-heading { + color: #ffffff; + background-color: #76b900; + border-color: #76b900; +} +.panel-primary > .panel-heading + .panel-collapse .panel-body { + border-top-color: #76b900; +} +.panel-primary > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #76b900; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #ebccd1; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #bce8f1; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 0px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-lg { + padding: 24px; + border-radius: 0px; +} +.well-sm { + padding: 9px; + border-radius: 0px; +} +.close { + float: right; + font-size: 24px; + font-weight: bold; + line-height: 1; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + display: none; + overflow: auto; + overflow-y: scroll; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; +} +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; + z-index: 1050; +} +.modal-content { + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0px; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; + outline: none; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; + min-height: 16.5px; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.5; +} +.modal-body { + position: relative; + padding: 20px; +} +.modal-footer { + margin-top: 15px; + padding: 19px 20px 20px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.modal-footer:after { + clear: both; +} +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +@media screen and (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + visibility: visible; + font-size: 14px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + border-radius: 0px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + right: 5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 16px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0%), color-stop(rgba(0, 0, 0, 0.0001) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + left: auto; + right: 0; + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0%), color-stop(rgba(0, 0, 0, 0.5) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, +.carousel-control:focus { + outline: none; + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #ffffff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); +} +.carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: #ffffff; +} +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicons-chevron-left, + .carousel-control .glyphicons-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; + } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after { + content: " "; + display: table; +} +.clearfix:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +tr.visible-xs, +th.visible-xs, +td.visible-xs { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-xs.visible-sm { + display: block !important; + } + table.visible-xs.visible-sm { + display: table; + } + tr.visible-xs.visible-sm { + display: table-row !important; + } + th.visible-xs.visible-sm, + td.visible-xs.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-xs.visible-md { + display: block !important; + } + table.visible-xs.visible-md { + display: table; + } + tr.visible-xs.visible-md { + display: table-row !important; + } + th.visible-xs.visible-md, + td.visible-xs.visible-md { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-xs.visible-lg { + display: block !important; + } + table.visible-xs.visible-lg { + display: table; + } + tr.visible-xs.visible-lg { + display: table-row !important; + } + th.visible-xs.visible-lg, + td.visible-xs.visible-lg { + display: table-cell !important; + } +} +.visible-sm, +tr.visible-sm, +th.visible-sm, +td.visible-sm { + display: none !important; +} +@media (max-width: 767px) { + .visible-sm.visible-xs { + display: block !important; + } + table.visible-sm.visible-xs { + display: table; + } + tr.visible-sm.visible-xs { + display: table-row !important; + } + th.visible-sm.visible-xs, + td.visible-sm.visible-xs { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-sm.visible-md { + display: block !important; + } + table.visible-sm.visible-md { + display: table; + } + tr.visible-sm.visible-md { + display: table-row !important; + } + th.visible-sm.visible-md, + td.visible-sm.visible-md { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-sm.visible-lg { + display: block !important; + } + table.visible-sm.visible-lg { + display: table; + } + tr.visible-sm.visible-lg { + display: table-row !important; + } + th.visible-sm.visible-lg, + td.visible-sm.visible-lg { + display: table-cell !important; + } +} +.visible-md, +tr.visible-md, +th.visible-md, +td.visible-md { + display: none !important; +} +@media (max-width: 767px) { + .visible-md.visible-xs { + display: block !important; + } + table.visible-md.visible-xs { + display: table; + } + tr.visible-md.visible-xs { + display: table-row !important; + } + th.visible-md.visible-xs, + td.visible-md.visible-xs { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-md.visible-sm { + display: block !important; + } + table.visible-md.visible-sm { + display: table; + } + tr.visible-md.visible-sm { + display: table-row !important; + } + th.visible-md.visible-sm, + td.visible-md.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-md.visible-lg { + display: block !important; + } + table.visible-md.visible-lg { + display: table; + } + tr.visible-md.visible-lg { + display: table-row !important; + } + th.visible-md.visible-lg, + td.visible-md.visible-lg { + display: table-cell !important; + } +} +.visible-lg, +tr.visible-lg, +th.visible-lg, +td.visible-lg { + display: none !important; +} +@media (max-width: 767px) { + .visible-lg.visible-xs { + display: block !important; + } + table.visible-lg.visible-xs { + display: table; + } + tr.visible-lg.visible-xs { + display: table-row !important; + } + th.visible-lg.visible-xs, + td.visible-lg.visible-xs { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-lg.visible-sm { + display: block !important; + } + table.visible-lg.visible-sm { + display: table; + } + tr.visible-lg.visible-sm { + display: table-row !important; + } + th.visible-lg.visible-sm, + td.visible-lg.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-lg.visible-md { + display: block !important; + } + table.visible-lg.visible-md { + display: table; + } + tr.visible-lg.visible-md { + display: table-row !important; + } + th.visible-lg.visible-md, + td.visible-lg.visible-md { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +.hidden-xs { + display: block !important; +} +table.hidden-xs { + display: table; +} +tr.hidden-xs { + display: table-row !important; +} +th.hidden-xs, +td.hidden-xs { + display: table-cell !important; +} +@media (max-width: 767px) { + .hidden-xs, + tr.hidden-xs, + th.hidden-xs, + td.hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-xs.hidden-sm, + tr.hidden-xs.hidden-sm, + th.hidden-xs.hidden-sm, + td.hidden-xs.hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-xs.hidden-md, + tr.hidden-xs.hidden-md, + th.hidden-xs.hidden-md, + td.hidden-xs.hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-xs.hidden-lg, + tr.hidden-xs.hidden-lg, + th.hidden-xs.hidden-lg, + td.hidden-xs.hidden-lg { + display: none !important; + } +} +.hidden-sm { + display: block !important; +} +table.hidden-sm { + display: table; +} +tr.hidden-sm { + display: table-row !important; +} +th.hidden-sm, +td.hidden-sm { + display: table-cell !important; +} +@media (max-width: 767px) { + .hidden-sm.hidden-xs, + tr.hidden-sm.hidden-xs, + th.hidden-sm.hidden-xs, + td.hidden-sm.hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm, + tr.hidden-sm, + th.hidden-sm, + td.hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-sm.hidden-md, + tr.hidden-sm.hidden-md, + th.hidden-sm.hidden-md, + td.hidden-sm.hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-sm.hidden-lg, + tr.hidden-sm.hidden-lg, + th.hidden-sm.hidden-lg, + td.hidden-sm.hidden-lg { + display: none !important; + } +} +.hidden-md { + display: block !important; +} +table.hidden-md { + display: table; +} +tr.hidden-md { + display: table-row !important; +} +th.hidden-md, +td.hidden-md { + display: table-cell !important; +} +@media (max-width: 767px) { + .hidden-md.hidden-xs, + tr.hidden-md.hidden-xs, + th.hidden-md.hidden-xs, + td.hidden-md.hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-md.hidden-sm, + tr.hidden-md.hidden-sm, + th.hidden-md.hidden-sm, + td.hidden-md.hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md, + tr.hidden-md, + th.hidden-md, + td.hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-md.hidden-lg, + tr.hidden-md.hidden-lg, + th.hidden-md.hidden-lg, + td.hidden-md.hidden-lg { + display: none !important; + } +} +.hidden-lg { + display: block !important; +} +table.hidden-lg { + display: table; +} +tr.hidden-lg { + display: table-row !important; +} +th.hidden-lg, +td.hidden-lg { + display: table-cell !important; +} +@media (max-width: 767px) { + .hidden-lg.hidden-xs, + tr.hidden-lg.hidden-xs, + th.hidden-lg.hidden-xs, + td.hidden-lg.hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-lg.hidden-sm, + tr.hidden-lg.hidden-sm, + th.hidden-lg.hidden-sm, + td.hidden-lg.hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-lg.hidden-md, + tr.hidden-lg.hidden-md, + th.hidden-lg.hidden-md, + td.hidden-lg.hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg, + tr.hidden-lg, + th.hidden-lg, + td.hidden-lg { + display: none !important; + } +} +.visible-print, +tr.visible-print, +th.visible-print, +td.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } + .hidden-print, + tr.hidden-print, + th.hidden-print, + td.hidden-print { + display: none !important; + } +} +/*! + * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('fontawesome-webfont.eot?v=4.0.3'); + src: url('fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('fontawesome-webfont.woff?v=4.0.3') format('woff'), url('fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font-family: FontAwesome; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.3333333333333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.2857142857142858em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.142857142857143em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.142857142857143em; + width: 2.142857142857143em; + top: 0.14285714285714285em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.8571428571428572em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: spin 2s infinite linear; + -moz-animation: spin 2s infinite linear; + -o-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; +} +@-moz-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + } + 100% { + -moz-transform: rotate(359deg); + } +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + } +} +@-o-keyframes spin { + 0% { + -o-transform: rotate(0deg); + } + 100% { + -o-transform: rotate(359deg); + } +} +@-ms-keyframes spin { + 0% { + -ms-transform: rotate(0deg); + } + 100% { + -ms-transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(359deg); + } +} +.fa-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -ms-transform: rotate(180deg); + -o-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -ms-transform: rotate(270deg); + -o-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -moz-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + -o-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -moz-transform: scale(1, -1); + -ms-transform: scale(1, -1); + -o-transform: scale(1, -1); + transform: scale(1, -1); +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-asc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-desc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-reply-all:before { + content: "\f122"; +} +.fa-mail-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro.eot"); + src: url("DINWebPro.woff") format("woff"); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro-Ita.eot"); + src: url("DINWebPro-Ita.woff") format("woff"); + font-weight: 400; + font-style: italic; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro-Medium.eot"); + src: url("DINWebPro-Medium.woff") format("woff"); + font-weight: 600; + font-style: normal; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro-MediumIta.eot"); + src: url("DINWebPro-MediumIta.woff") format("woff"); + font-weight: 600; + font-style: italic; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro-Bold.eot"); + src: url("DINWebPro-Bold.woff") format("woff"); + font-weight: 700; + font-style: normal; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro-BoldIta.eot"); + src: url("DINWebPro-BoldIta.woff") format("woff"); + font-weight: 700; + font-style: italic; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro-Light.eot"); + src: url("DINWebPro-Light.woff") format("woff"); + font-weight: 300; + font-style: normal; +} +@font-face { + font-family: 'DINWebPro'; + src: url("DINWebPro-LightIta.eot"); + src: url("DINWebPro-LightIta.woff") format("woff"); + font-weight: 300; + font-style: italic; +} +@media (min-width: 1400px) { + .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { + float: left; + } + .col-xl-12 { + width: 100%; + } + .col-xl-11 { + width: 91.66666666666666%; + } + .col-xl-10 { + width: 83.33333333333334%; + } + .col-xl-9 { + width: 75%; + } + .col-xl-8 { + width: 66.66666666666666%; + } + .col-xl-7 { + width: 58.333333333333336%; + } + .col-xl-6 { + width: 50%; + } + .col-xl-5 { + width: 41.66666666666667%; + } + .col-xl-4 { + width: 33.33333333333333%; + } + .col-xl-3 { + width: 25%; + } + .col-xl-2 { + width: 16.666666666666664%; + } + .col-xl-1 { + width: 8.333333333333332%; + } + .col-xl-pull-12 { + right: 100%; + } + .col-xl-pull-11 { + right: 91.66666666666666%; + } + .col-xl-pull-10 { + right: 83.33333333333334%; + } + .col-xl-pull-9 { + right: 75%; + } + .col-xl-pull-8 { + right: 66.66666666666666%; + } + .col-xl-pull-7 { + right: 58.333333333333336%; + } + .col-xl-pull-6 { + right: 50%; + } + .col-xl-pull-5 { + right: 41.66666666666667%; + } + .col-xl-pull-4 { + right: 33.33333333333333%; + } + .col-xl-pull-3 { + right: 25%; + } + .col-xl-pull-2 { + right: 16.666666666666664%; + } + .col-xl-pull-1 { + right: 8.333333333333332%; + } + .col-xl-pull-0 { + right: 0%; + } + .col-xl-push-12 { + left: 100%; + } + .col-xl-push-11 { + left: 91.66666666666666%; + } + .col-xl-push-10 { + left: 83.33333333333334%; + } + .col-xl-push-9 { + left: 75%; + } + .col-xl-push-8 { + left: 66.66666666666666%; + } + .col-xl-push-7 { + left: 58.333333333333336%; + } + .col-xl-push-6 { + left: 50%; + } + .col-xl-push-5 { + left: 41.66666666666667%; + } + .col-xl-push-4 { + left: 33.33333333333333%; + } + .col-xl-push-3 { + left: 25%; + } + .col-xl-push-2 { + left: 16.666666666666664%; + } + .col-xl-push-1 { + left: 8.333333333333332%; + } + .col-xl-push-0 { + left: 0%; + } + .col-xl-offset-12 { + margin-left: 100%; + } + .col-xl-offset-11 { + margin-left: 91.66666666666666%; + } + .col-xl-offset-10 { + margin-left: 83.33333333333334%; + } + .col-xl-offset-9 { + margin-left: 75%; + } + .col-xl-offset-8 { + margin-left: 66.66666666666666%; + } + .col-xl-offset-7 { + margin-left: 58.333333333333336%; + } + .col-xl-offset-6 { + margin-left: 50%; + } + .col-xl-offset-5 { + margin-left: 41.66666666666667%; + } + .col-xl-offset-4 { + margin-left: 33.33333333333333%; + } + .col-xl-offset-3 { + margin-left: 25%; + } + .col-xl-offset-2 { + margin-left: 16.666666666666664%; + } + .col-xl-offset-1 { + margin-left: 8.333333333333332%; + } + .col-xl-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1400px) { + .container { + width: container-extra-large-desktop; + } +} +@media (min-width: 992px) { + .col-md-4 { + width: 33.3%; + } +} +@media (min-width: 1200px) { + .col-lg-4 { + width: 33.3%; + } +} +@media (min-width: 1400px) { + .col-xl-4 { + width: 33.3%; + } +} +.navbar { + min-height: 50px; + margin-bottom: 0; +} +@media (max-width: 1199px) { + .navbar { + margin-bottom: 0; + } +} +.navbar .navbar-header { + white-space: nowrap; +} +.navbar .nav-uppercase { + text-transform: uppercase; +} +.navbar .login-nav { + text-transform: none; +} +.navbar .divider-nav { + background-color: #303030; + width: 1px; + height: 30px; + margin-left: 20px; + display: inline-block; + vertical-align: middle; +} +.navbar .navbar-brand { + padding: 13px 10px; + margin: 0; +} +.navbar .navbar-brand .divider-nav { + margin-left: 30px; +} +.navbar .gw-download { + color: #76b900 !important; +} +.navbar .gw-sub-navbar > li > a { + padding: 17px 32px 9px 0; +} +@media (min-width: 992px) { + .navbar-nav > li > a { + padding-top: 17px; + padding-bottom: 9px; + } +} +.container > .navbar-header, +.container > .navbar-collapse { + margin-left: 0; + margin-right: 0; +} +@media (min-width: 991px) { + #search-top { + position: relative; + } + #search-top a { + padding-left: 0; + padding-right: 10px; + position: relative; + z-index: 3; + } + #search-top a:hover { + color: #77b820; + } + #search-top .search-form { + position: absolute; + top: 7px; + right: 0; + z-index: 2; + } + #search-top .search-form input { + display: none; + width: 300px; + height: 36px !important; + line-height: 38px; + border: 0; + outline: 0; + padding: 0 40px 0 12px; + border-radius: 3px; + background: #fff; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } +} +.nvidia-dropdown { + position: relative; +} +.nvidia-dropdown-menu { + left: auto; + float: right; + right: -59px; + background: #000000; + border: 1px solid #cccccc; + border: 1px solid #404040; +} +.nvidia-dropdown-menu.drop-gw { + right: -59px; +} +.nvidia-dropdown-menu.drop-sub-gw { + right: -43px; + background-color: #242424; +} +.nvidia-dropdown-menu.drop-sub-gw:after { + border-bottom: 9px solid #242424; + top: -7px; +} +.nvidia-dropdown-menu.pull-right { + right: 0; + left: auto; +} +.nvidia-dropdown-menu .divider { + height: 1px; + margin: 11px 0; + overflow: hidden; + background-color: transparent; +} +.nvidia-dropdown-menu > li { + font-size: 0.9em; +} +.nvidia-dropdown-menu > li > a { + display: block; + padding: 7px 20px; + clear: both; + font-weight: normal; + line-height: 1.5; + color: #cacaca; + white-space: nowrap; +} +@media (min-width: 991px) { + .nvidia-dropdown-menu:before, + .nvidia-dropdown-menu:after { + content: ''; + position: absolute; + left: 50%; + border-left: 9px solid transparent; + border-right: 9px solid transparent; + margin: 0 0 0 -7px; + } + .nvidia-dropdown-menu:before { + border-bottom: 9px solid #404040; + top: -9px; + } + .nvidia-dropdown-menu:after { + border-bottom: 9px solid #000000; + top: -7px; + } +} +@media (max-width: 991px) { + .nvidia-dropdown-menu:before, + .nvidia-dropdown-menu:after { + display: none; + } +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + text-decoration: none; + color: #ffffff; + background-color: transparent; +} +@media (max-width: 768px) { + .navbar .navbar-header { + text-align: left !important; + } + .navbar .navbar-header .logo-header { + display: block !important; + margin: 0 !important; + } + .navbar .navbar-brand { + float: none; + display: block; + } +} +.second-navbar { + background-color: #242424; + border-color: transparent; + margin-bottom: 0; +} +body { + background-color: #1a1a1a; +} +#wrapper { + background-color: #fcfcfc; +} +.container-fluid { + margin-left: 10px; + margin-right: 10px; +} +.masthead { + background-color: #373737; + background-size: cover; + background-position: center 0; + background-repeat: no-repeat; +} +.masthead .container { + padding: 0; +} +.masthead .masthead-content { + padding: 30px 10px 20px 10px; +} +.masthead .masthead-content h1 { + font-size: 24px; + color: #76b900; + padding: 0; + margin: 0; + text-transform: uppercase; + font-weight: normal; +} +.masthead .masthead-content p { + font-size: 1.2em; + color: #cacaca; + font-weight: normal; + padding-top: 10px; +} +.masthead-sub-page { + background-color: white; +} +.masthead-sub-page h1 { + margin-top: 12px; +} +.section-header { + padding-bottom: 5px; + margin: 24px 0 24px 0; + border-bottom: 1px solid #efefef; +} +.section-header h4 { + color: #004831; + text-transform: capitalize; + font-size: 19px; +} +.section-header a { + float: right; + padding-top: 4px; + font-size: 14px; + text-transform: capitalize; + color: #999999; +} +.section-header a:hover, +.section-header a:focus { + text-decoration: underline; +} +.newsletter-registration h5 { + margin-top: 0; +} +.newsletter-registration .input-group .input-group-addon { + background-color: white; + border-style: solid none solid solid; + border-width: 1px 0 1px 1px; + border-right: 0; +} +.newsletter-registration .input-group .form-control { + background-color: white; + border-style: solid none solid none; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-appearance: none; + border-width: 1px 0 1px 0; + height: 38px; + padding-left: 0; +} +.newsletter-registration .input-group .form-control:focus { + border-color: #ccc; +} +.node { + padding-bottom: 1em; +} +a.node-thumbnail { + position: relative; + display: block; + margin-bottom: 1em; +} +a.node-thumbnail img { + width: 100%; + height: auto; + border: 1px solid; + border-color: #999999; + display: inline; +} +a.node-thumbnail img.no-border { + border: none; +} +a.node-thumbnail .node-overlay { + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0); + -webkit-transition: background-color 0.5s ease-in-out; + transition: background-color 0.5s ease-in-out; +} +a.node-thumbnail .node-overlay .node-cta { + color: rgba(255, 255, 255, 0); + -webkit-transition: color 0.5s ease-in-out; + transition: color 0.5s ease-in-out; + text-align: center; + margin: auto; + position: absolute; + height: 24px; + top: 0; + left: 0; + bottom: 0; + right: 0; +} +a.node-thumbnail .node-overlay .node-cta i { + color: rgba(118, 185, 0, 0); + -webkit-transition: color 0.5s ease-in-out; + transition: color 0.5s ease-in-out; + font-size: 0.9em; +} +a.node-thumbnail:hover .node-overlay { + background-color: rgba(0, 0, 0, 0.65); + -webkit-transition: background-color 0.5s ease-in-out; + transition: background-color 0.5s ease-in-out; +} +a.node-thumbnail:hover .node-overlay .node-cta { + color: #ffffff; + -webkit-transition: color 0.5s ease-in-out; + transition: color 0.5s ease-in-out; +} +a.node-thumbnail:hover .node-overlay .node-cta i { + color: #76b900; + -webkit-transition: color 0.5s ease-in-out; + transition: color 0.5s ease-in-out; +} +.node-description .node-date { + color: #999999; + padding-bottom: 5px; + font-size: 0.8em; + font-weight: 600; +} +.node-description a.node-title { + display: block; + font-size: 1.1em; + font-weight: 600; + line-height: 1.25em; + color: #004831; + padding-bottom: 0.4em; +} +.node-description a.node-title:hover, +.node-description a.node-title:focus { + text-decoration: underline; +} +.node-description p { + font-size: 0.8em; + color: #999999; +} +.icon-description { + padding-bottom: 12px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.icon-description .icon { + color: white; + background-color: #76b900; + float: left; + width: 90px; + height: 90px; + text-align: center; + font-size: 3em; + line-height: 97px; +} +.icon-description .icon.icon-cogs { + line-height: 103px; +} +.icon-description .icon.icon-book { + line-height: 100px; +} +.icon-description .icon.icon-download { + line-height: 100px; +} +.icon-description .description { + margin-left: 100px; +} +.icon-description .description h2 { + font-size: 1.3em; + margin: 0; + padding-bottom: 5px; +} +.icon-description .description > h2 > a { + font-size: 1em; + margin: 0; + padding-bottom: 5px; + color: #004831; +} +.icon-description .description > h2 > a:hover, +.icon-description .description > h2 > a:focus { + text-decoration: underline; +} +.icon-description .description > p > a { + font-size: 1em; + color: #76b900; +} +.icon-description .description > p > a:hover, +.icon-description .description > p > a:focus { + text-decoration: underline; +} +.icon-description .description p { + font-size: 0.9em; + text-transform: none; + margin-bottom: 10px; +} +.product > h4 > a { + color: #004831; +} +.feature_items .feature_item { + padding-bottom: 1em; +} +.feature_items .feature_item .feature_image { + padding-bottom: 1em; +} +.feature_items .feature_item .feature_image img { + width: 100%; +} +.feature_items .feature_item .feature_image .feature_icon { + padding: 20px 0 20px 0; + background-color: #76b900; + text-align: center; + font-size: 4em; + line-height: 1em; +} +.feature_items .feature_item .feature_description h2 { + margin: 0; + font-size: 1.5em; +} +.twitter img { + float: right; +} +.twitter #twitter-feeds { + border: 1px solid #E1E3E4; + border-radius: 3px; + width: 100%; + padding: 8px 8px 0 8px; + margin-top: 10px; +} +.twitter #twitter-feeds.twt-cuda { + height: 340px; +} +.twitter #twitter-feeds.twt-gameworks { + height: 276px; +} +.twitter #twitter-feeds #overflow { + width: 100%; + overflow-y: auto; + height: 100%; +} +.twitter #twitter-feeds .twt_description { + padding: 10px 0 10px; + border-bottom: 1px solid #E1E3E4; +} +.twitter #twitter-feeds .twt_description .twt-thumbnails { + float: left; + width: 70px; + height: 70px; +} +.twitter #twitter-feeds .twt_description a { + font-size: 0.7em; + color: #999999; +} +.twitter #twitter-feeds .twt_description a:hover, +.twitter #twitter-feeds .twt_description a:focus { + text-decoration: underline; +} +.twitter #twitter-feeds .twt_description .tweet { + margin-left: 85px; +} +.twitter #twitter-feeds .twt_description .tweet h2 { + color: #333333; + font-size: 1em; + margin: 0; + padding: 0; +} +.twitter #twitter-feeds .twt_description .tweet h6 { + color: #999999; + font-size: 0.7em; + margin: 0; + padding: 0; +} +.twitter #twitter-feeds .twt_description .tweet p { + padding-top: 5px; + font-size: 0.8em; + text-transform: none; +} +.twitter #twitter-feeds .twt_description .tweet p > a { + font-size: 1em; + color: #76b900; +} +.twitter #twitter-feeds .twt_description .tweet p > a:hover, +.twitter #twitter-feeds .twt_description .tweet p > a:focus { + text-decoration: underline; +} +.homepage .home-masthead .masthead-content h1 { + color: #76b900; + text-transform: uppercase; + font-size: 32px; + line-height: 1.2em; +} +.homepage .home-masthead .masthead-content p { + color: #cacaca; + font-size: 18px; +} +.homepage .home-zones-container { + padding: 40px 15px 30px; + background-color: #efefef; +} +.homepage .dev-zone-box { + background-color: black; + position: relative; + background-repeat: no-repeat; + background-size: cover; + background-position: center center; + margin-bottom: 1em; +} +.homepage .dev-zone-box.even { + background-color: #333; +} +.homepage .dev-zone-box .box { + height: 250px; + width: 100%; +} +.homepage .dev-zone-box a { + display: block; + padding: 20px; + width: 100%; + height: 100%; + position: relative; + -webkit-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.homepage .dev-zone-box a .dev-zone-box-content { + position: absolute; + top: 20px; + margin-right: 20px; + -webkit-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} +.homepage .dev-zone-box a .dev-zone-box-content h2 { + margin: 0; + color: #76b900; + font-size: 24px; + text-transform: uppercase; + -webkit-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} +.homepage .dev-zone-box a .dev-zone-box-content p { + font-size: 16px; + color: #cacaca; + -webkit-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} +.homepage .dev-zone-box a:hover { + text-decoration: underline; + background-color: #76b900; + -webkit-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} +.homepage .dev-zone-box a:hover .dev-zone-box-content { + -webkit-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} +.homepage .dev-zone-box a:hover .dev-zone-box-content h2, +.homepage .dev-zone-box a:hover .dev-zone-box-content p { + color: white; +} +.content .page-header { + margin-top: 0; +} +.content .page-header h1, +.content .page-header h2, +.content .page-header h3 { + margin-top: 0; +} +.content-sidebar .panel-heading { + text-transform: uppercase; + font-weight: bold; +} +.btn-dark-icon > i.fa { + font-size: 1em; + color: #004831; +} +.seperator, +.separator { + height: 20px; +} +.seperator-sm, +.separator-sm { + height: 10px; +} +.padding-left { + padding-left: 0px; +} +.padding-md { + padding: 20px; +} +.padding-md-right { + padding-right: 20px; +} +.padding-md-left { + padding-left: 20px; +} +.padding-md-bottom { + padding-bottom: 20px; +} +.padding-md-top { + padding-top: 20px; +} +.padding-sm { + padding: 10px; +} +.padding-sm-right { + padding-right: 10px; +} +.padding-sm-left { + padding-left: 10px; +} +.padding-sm-bottom { + padding-bottom: 10px; +} +.padding-sm-top { + padding-top: 10px; +} +.padding-md-footer { + padding: 20px 20px 20px 0; +} +.padding-section-footer { + padding-right: 0px; +} +.padding-sub-footer { + padding: 20px 20px 20px 0px; +} +.gray-lighter-background { + background-color: #efefef; +} +.gray-darker-background { + background-color: #373737; +} +.white-background { + background-color: white; +} +.vertical-align-middle { + vertical-align: middle !important; +} +.text-white { + color: white; +} +.text-green { + color: #76b900; +} +@media (max-width: 991px) { + .navbar-toggle { + float: left; + } +} +.sidr { + display: none; + position: absolute; + position: fixed; + top: 0; + height: 100%; + z-index: 999999; + width: 260px; + overflow-x: none; + overflow-y: auto; + background-color: #3c3c3d; + color: white; +} +.sidr.right { + left: auto; + right: -260px; +} +.sidr.left { + left: -260px; + right: auto; +} +.sidr ul { + display: block; + margin: 0; + padding: 0; +} +.sidr ul li { + display: block; + margin: 0; + line-height: 40px; + padding: 0 15px; +} +.sidr ul li.menu-title { + color: white; + border-bottom: 1px solid #262626; + text-transform: uppercase; + padding-top: 7px; + padding-bottom: 3px; +} +.sidr ul li a { + display: block; + text-decoration: none; + color: #999999; + padding: 10px 0; +} +.sidr ul li a:hover, +.sidr ul li a:active, +.sidr ul li a:focus { + color: white; + background: none; +} +.sidr ul li a .caret { + display: inline-block; + font-family: FontAwesome; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: auto; + height: auto; + border: none; + margin-left: 5px; + vertical-align: baseline; +} +.sidr ul li a .caret:before { + content: "\f105"; +} +.sidr ul li.dropdown .dropdown-menu { + display: none; +} +.sidr ul li.open > a { + background: none; +} +.sidr ul li.open > a:hover, +.sidr ul li.open > a:active, +.sidr ul li.open > a:focus { + background: none; +} +.sidr ul li.open > a .caret:before { + content: "\f107"; +} +.sidr ul li.open.dropdown .dropdown-menu { + display: block; +} +.sidr ul li.open .dropdown-menu > li > a { + padding: 5px 15px 5px 0; +} +.sidr ul li .search-form { + padding-top: 10px; + padding-bottom: 10px; +} +.sidr ul li .search-form .container-inline div { + display: block; + margin-top: 0; + margin-bottom: 0; +} +.sidr ul li .search-form .input { + position: relative; +} +.sidr ul li .search-form .input .fa { + position: absolute; + top: 8px; + right: 12px; + font-size: 18px; + color: #3c3c3d; +} +.sidr ul li .search-form .input input { + width: 100%; + padding: 7px 14px 5px 14px; + line-height: 1.5em; + background-color: #f0f0f0; + border: 0; + color: #3c3c3d; + border-radius: 3px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2) inset; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +footer { + border-top: 3px solid #76b900; +} +footer .footer-links { + background-color: #222222; +} +@media (max-width: 768px) { + footer .footer-links .zone-select { + text-align: left; + } +} +@media (min-width: 1200px) { + footer .footer-links .zone-select { + text-align: right; + } +} +footer .footer-links a { + color: #6e6e6e; +} + +footer .footer-links a:hover h6, +footer .footer-links a:active h6, +footer .footer-links a:hover, +footer .footer-links a:active { + color: #FFFFFF; + text-decoration: none; +} +footer .footer-links h5 { + margin: 0 0 19px; + padding: 0 0 0.5em 0; + text-transform: uppercase; + color: #707070; +} +footer .footer-links h6 { + margin: 0; + padding: 0 0 0.5em 0; + font-weight: normal; + text-transform: uppercase; + color: #707070; +} +footer .footer-links ul { + margin: 0; + padding: 0; +} +footer .footer-links ul li { + font-weight: lighter; + font-size: 0.8em; + list-style: none; + margin: 0; + padding: 0 0 5px; +} +footer .footer-links .logo-footer { + height: 26px; + width: 195px; + background-image: url("../images/nvidia-logo-footer.png"); + padding-bottom: 10px; + background-repeat: no-repeat; + vertical-align: middle; + border: 0 none; +} +footer .footer-links .logo-footer ul { + margin: 0; + padding: 40px 0 0; +} +footer .footer-boilerplate { + background-color: #1a1a1a; +} +footer .footer-boilerplate.footer-home { + padding: 5px 0 5px; +} +footer .footer-boilerplate .boilerplate { + text-align: left; + font-size: 0.8em; + color: #666666; + padding: 10px 0; +} +footer .footer-boilerplate .boilerplate .footer-brand { + margin: -2px 40px 20px 0px; +} +footer .footer-boilerplate .boilerplate a { + font-size: 0.9em; + text-transform: none; + color: #666666; + text-decoration: none; +} +footer .footer-boilerplate .boilerplate a:hover, +footer .footer-boilerplate .boilerplate a:focus { + color: #FFFFFF; + text-decoration: none; +} +.label { + padding: .5em .6em .3em; +} +label { + font-weight: normal; +} +:focus { + outline-color: transparent; + outline-style: none; +} +.btn { + padding-top: 9.575999999999999px; + padding-bottom: 7.199999999999999px; + line-height: 1.2em; +} +.btn-lg { + padding-top: 12.768px; + padding-bottom: 9.6px; +} +.btn-sm { + padding-top: 7.98px; + padding-bottom: 6px; +} +.btn-xs { + padding-top: 6.384px; + padding-bottom: 4.8px; +} +.lead { + font-size: 18px; +} +@media (min-width: 768px) { + .lead { + font-size: 20px; + } +} +.breadcrumb { + background-color: transparent; + padding: 0; + font-size: 14px; +} +.block ul { + margin: 0; + padding: 0; +} +.panel-success { + border-color: #76b900; +} +.panel-success > .panel-heading { + color: #ffffff; + background-color: #76b900; + border-color: #76b900; +} +.panel-success > .panel-heading + .panel-collapse .panel-body { + border-top-color: #76b900; +} +.panel-success > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #76b900; +} +.panel-success .panel-heading a { + color: white; +} +/* + * Core Owl Carousel CSS File + * v1.3.2 + */ +/* clearfix */ +.owl-carousel .owl-wrapper:after { + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; +} +/* display none until init */ +.owl-carousel { + display: none; + position: relative; + width: 100%; + -ms-touch-action: pan-y; +} +.owl-carousel .owl-wrapper { + display: none; + position: relative; + -webkit-transform: translate3d(0px, 0px, 0px); +} +.owl-carousel .owl-wrapper-outer { + overflow: hidden; + position: relative; + width: 100%; +} +.owl-carousel .owl-wrapper-outer.autoHeight { + -webkit-transition: height 500ms ease-in-out; + -moz-transition: height 500ms ease-in-out; + -ms-transition: height 500ms ease-in-out; + -o-transition: height 500ms ease-in-out; + transition: height 500ms ease-in-out; +} +.owl-carousel .owl-item { + float: left; +} +.owl-controls .owl-page, +.owl-controls .owl-buttons div { + cursor: pointer; +} +.owl-controls { + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +/* mouse grab icon */ +.grabbing { + cursor: url(grabbing.png) 8 8, move; +} +/* fix */ +.owl-carousel .owl-wrapper, +.owl-carousel .owl-item { + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); +} +/* +* Owl Carousel Owl Demo Theme +* v1.3.2 +*/ +.owl-theme .owl-controls { + margin-top: 10px; + text-align: center; +} +/* Styling Next and Prev buttons */ +.owl-theme .owl-controls .owl-buttons div { + color: #FFF; + display: inline-block; + zoom: 1; + *display: inline; + /*IE7 life-saver */ + margin: 5px; + padding: 3px 10px; + font-size: 12px; + -webkit-border-radius: 30px; + -moz-border-radius: 30px; + border-radius: 30px; + background: #869791; + filter: alpha(opacity=50); + /*IE7 fix*/ + opacity: 0.5; +} +/* Clickable class fix problem with hover on touch devices */ +/* Use it for non-touch hover action */ +.owl-theme .owl-controls.clickable .owl-buttons div:hover { + filter: alpha(opacity=100); + /*IE7 fix*/ + opacity: 1; + text-decoration: none; +} +/* Styling Pagination*/ +.owl-theme .owl-controls .owl-page { + display: inline-block; + zoom: 1; + *display: inline; + /*IE7 life-saver */ +} +.owl-theme .owl-controls .owl-page span { + display: block; + width: 12px; + height: 12px; + margin: 5px 7px; + filter: alpha(opacity=50); + /*IE7 fix*/ + opacity: 0.5; + -webkit-border-radius: 20px; + -moz-border-radius: 20px; + border-radius: 20px; + background: #869791; +} +.owl-theme .owl-controls .owl-page.active span, +.owl-theme .owl-controls.clickable .owl-page:hover span { + filter: alpha(opacity=100); + /*IE7 fix*/ + opacity: 1; +} +/* If PaginationNumbers is true */ +.owl-theme .owl-controls .owl-page span.owl-numbers { + height: auto; + width: auto; + color: #FFF; + padding: 2px 10px; + font-size: 12px; + -webkit-border-radius: 30px; + -moz-border-radius: 30px; + border-radius: 30px; +} +/* preloading images */ +.owl-item.loading { + min-height: 150px; + background: url(AjaxLoader.gif) no-repeat center center; +} +.carousel-container { + color: #fff; +} +.carousel-container #masthead-text { + padding-bottom: 1em; +} +.carousel-container h1, +.carousel-container h2, +.carousel-container h3, +.carousel-container h4, +.carousel-container h5, +.carousel-container h6 { + padding-top: 0; + margin-top: 0; +} +.carousel-container h2 { + color: #80bd01; +} +.carousel-container h3 { + color: #76b900; + text-transform: uppercase; + font-size: 22px; +} +.carousel-container .fa { + vertical-align: top; + margin: 2px 0 0 4px; +} +.owl-carousel .item { + position: relative; + background-repeat: no-repeat; + background-position: right 0px center; + padding-left: 10px; + padding-right: 10px; + min-height: 200px; +} +.owl-carousel .item .row, +.owl-carousel .item .carousel-text { + padding-top: 1em; + padding-bottom: 1em; + position: relative; + z-index: 3; +} +.owl-carousel .item .item-background { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background-repeat: no-repeat; + background-position: right 0px top; + background-size: cover; +} +@media (max-width: 767px) { + .owl-carousel .item .item-background { + opacity: 0.1; + } +} +@media (max-width: 991px) { + .owl-carousel .item .item-background { + opacity: 0.3; + } +} +.owl-carousel .owl-controls { + margin: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + z-index: 2; +} +.owl-carousel .owl-controls .owl-buttons .owl-prev, +.owl-carousel .owl-controls .owl-buttons .owl-next { + height: 43px; + line-height: 43px; + font-size: 43px; + z-index: 3; + position: absolute; + padding: 0; + margin: 0; + background: transparent; + color: #CECECE; + border-radius: 0; +} +.owl-carousel .owl-controls .owl-buttons .owl-prev { + left: 0; +} +.owl-carousel .owl-controls .owl-buttons .owl-next { + right: 4px; +} +.owl-carousel .owl-controls .owl-buttons .fa { + vertical-align: top; +} +#colorbox, +#cboxOverlay, +#cboxWrapper { + position: absolute; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; +} +#cboxWrapper { + max-width: none; +} +#cboxOverlay { + position: fixed; + width: 100%; + height: 100%; +} +#cboxMiddleLeft, +#cboxBottomLeft { + clear: left; +} +#cboxContent { + position: relative; +} +#cboxLoadedContent { + overflow: auto; + -webkit-overflow-scrolling: touch; +} +#cboxTitle { + margin: 0; +} +#cboxLoadingOverlay, +#cboxLoadingGraphic { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#cboxPrevious, +#cboxNext, +#cboxClose, +#cboxSlideshow { + cursor: pointer; +} +.cboxPhoto { + float: left; + margin: auto; + border: 0; + display: block; + max-width: none; + -ms-interpolation-mode: bicubic; +} +.cboxIframe { + width: 100%; + height: 100%; + display: block; + border: 0; +} +#colorbox, +#cboxContent, +#cboxLoadedContent { + box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; +} +#cboxOverlay { + background: #000; +} +#colorbox { + outline: 0; +} +#cboxContent { + margin-top: 20px; + background: #000; +} +.cboxIframe { + background: #fff; +} +#cboxError { + padding: 50px; + border: 1px solid #ccc; +} +#cboxLoadedContent { + border: 5px solid #000; + background: #fff; +} +#cboxTitle { + position: absolute; + top: -20px; + left: 0; + color: #ccc; +} +#cboxCurrent { + position: absolute; + top: -20px; + right: 0px; + color: #ccc; +} +#cboxLoadingGraphic { + background: url(/images/colorbox/loading.gif) no-repeat center center; +} +/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */ +#cboxPrevious, +#cboxNext, +#cboxSlideshow, +#cboxClose { + border: 0; + padding: 0; + margin: 0; + overflow: visible; + width: auto; + background: none; +} +/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */ +#cboxPrevious:active, +#cboxNext:active, +#cboxSlideshow:active, +#cboxClose:active { + outline: 0; +} +#cboxSlideshow { + position: absolute; + top: -20px; + right: 90px; + color: #fff; +} +#cboxPrevious { + position: absolute; + top: 50%; + left: 5px; + margin-top: -32px; + background: url(/images/colorbox/controls.png) no-repeat top left; + width: 28px; + height: 65px; + text-indent: -9999px; +} +#cboxPrevious:hover { + background-position: bottom left; +} +#cboxNext { + position: absolute; + top: 50%; + right: 5px; + margin-top: -32px; + background: url(/images/colorbox/controls.png) no-repeat top right; + width: 28px; + height: 65px; + text-indent: -9999px; +} +#cboxNext:hover { + background-position: bottom right; +} +#cboxClose { + position: absolute; + top: 5px; + right: 5px; + display: block; + background: url(/images/colorbox/controls.png) no-repeat top center; + width: 38px; + height: 19px; + text-indent: -9999px; +} +#cboxClose:hover { + background-position: bottom center; +} +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +.pln { + color: #000; +} +/* plain text */ +@media screen { + .str { + color: #080; + } + /* string content */ + .kwd { + color: #008; + } + /* a keyword */ + .com { + color: #800; + } + /* a comment */ + .typ { + color: #606; + } + /* a type name */ + .lit { + color: #066; + } + /* a literal value */ + /* punctuation, lisp open bracket, lisp close bracket */ + .pun, + .opn, + .clo { + color: #660; + } + .tag { + color: #008; + } + /* a markup tag name */ + .atn { + color: #606; + } + /* a markup attribute name */ + .atv { + color: #080; + } + /* a markup attribute value */ + .dec, + .var { + color: #606; + } + /* a declaration; a variable name */ + .fun { + color: red; + } + /* a function name */ +} +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; + } + .kwd { + color: #006; + font-weight: bold; + } + .com { + color: #600; + font-style: italic; + } + .typ { + color: #404; + font-weight: bold; + } + .lit { + color: #044; + } + .pun, + .opn, + .clo { + color: #440; + } + .tag { + color: #006; + font-weight: bold; + } + .atn { + color: #404; + } + .atv { + color: #060; + } +} +/* Put a border around prettyprinted code snippets. */ +pre.prettyprint { + padding: 2px; + border: 1px solid #888; +} +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L5, +li.L6, +li.L7, +li.L8 { + list-style-type: none; +} +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + background: #eee; +} +pre.prettyprint { + padding: 10px; + font-size: 14px; +} +#right .more-link { + text-align: left; + border-top: 1px solid #dddddd; +} +#right .more-link a { + padding: 10px 15px 10px 15px; + display: block; + text-transform: capitalize; + color: #555555; +} +#right .more-link a:hover { + text-decoration: none; + background-color: #f5f5f5; +} diff --git a/doc/_static/bootstrap.css b/doc/_static/bootstrap.css new file mode 100644 index 0000000..5b7fe7e --- /dev/null +++ b/doc/_static/bootstrap.css @@ -0,0 +1,6167 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +audio:not([controls]) { + display: none; +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +a:hover, +a:active { + outline: 0; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +#map_canvas img, +.google-maps img { + max-width: none; +} + +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} + +button, +input { + *overflow: visible; + line-height: normal; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} + +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} + +a { + color: #0088cc; + text-decoration: none; +} + +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} + +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} + +.row { + margin-left: -20px; + *zoom: 1; +} + +.row:before, +.row:after { + display: table; + line-height: 0; + content: ""; +} + +.row:after { + clear: both; +} + +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} + +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.span12 { + width: 940px; +} + +.span11 { + width: 860px; +} + +.span10 { + width: 780px; +} + +.span9 { + width: 700px; +} + +.span8 { + width: 620px; +} + +.span7 { + width: 540px; +} + +.span6 { + width: 460px; +} + +.span5 { + width: 380px; +} + +.span4 { + width: 300px; +} + +.span3 { + width: 220px; +} + +.span2 { + width: 140px; +} + +.span1 { + width: 60px; +} + +.offset12 { + margin-left: 980px; +} + +.offset11 { + margin-left: 900px; +} + +.offset10 { + margin-left: 820px; +} + +.offset9 { + margin-left: 740px; +} + +.offset8 { + margin-left: 660px; +} + +.offset7 { + margin-left: 580px; +} + +.offset6 { + margin-left: 500px; +} + +.offset5 { + margin-left: 420px; +} + +.offset4 { + margin-left: 340px; +} + +.offset3 { + margin-left: 260px; +} + +.offset2 { + margin-left: 180px; +} + +.offset1 { + margin-left: 100px; +} + +.row-fluid { + width: 100%; + *zoom: 1; +} + +.row-fluid:before, +.row-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.row-fluid:after { + clear: both; +} + +.row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} + +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} + +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} + +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} + +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} + +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} + +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} + +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} + +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} + +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} + +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} + +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} + +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} + +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} + +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} + +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} + +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} + +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} + +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} + +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} + +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} + +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} + +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} + +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} + +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} + +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} + +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} + +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} + +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} + +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} + +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} + +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} + +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} + +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} + +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} + +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} + +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} + +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} + +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} + +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} + +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} + +.container:before, +.container:after { + display: table; + line-height: 0; + content: ""; +} + +.container:after { + clear: both; +} + +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} + +.container-fluid:before, +.container-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.container-fluid:after { + clear: both; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} + +small { + font-size: 85%; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +cite { + font-style: normal; +} + +.muted { + color: #999999; +} + +a.muted:hover, +a.muted:focus { + color: #808080; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover, +a.text-success:focus { + color: #356635; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + line-height: 40px; +} + +h1 { + font-size: 38.5px; +} + +h2 { + font-size: 31.5px; +} + +h3 { + font-size: 24.5px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +h2 small { + font-size: 17.5px; +} + +h3 small { + font-size: 14px; +} + +h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} + +li { + line-height: 20px; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} + +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + padding-right: 5px; + padding-left: 5px; + *zoom: 1; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 20px; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 10px; +} + +.dl-horizontal { + *zoom: 1; +} + +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + line-height: 0; + content: ""; +} + +.dl-horizontal:after { + clear: both; +} + +.dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dl-horizontal dd { + margin-left: 180px; +} + +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +code { + padding: 2px 4px; + color: #d14; + white-space: nowrap; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +form { + margin: 0 0 20px; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +legend small { + font-size: 15px; + color: #999999; +} + +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +label { + display: block; + margin-bottom: 5px; +} + +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input, +textarea, +.uneditable-input { + width: 206px; +} + +textarea { + height: auto; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} + +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; +} + +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} + +select, +input[type="file"] { + height: 30px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 30px; +} + +select { + width: 220px; + background-color: #ffffff; + border: 1px solid #cccccc; +} + +select[multiple], +select[size] { + height: auto; +} + +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.uneditable-input, +.uneditable-textarea { + color: #999999; + cursor: not-allowed; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} + +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} + +.uneditable-textarea { + width: auto; + height: auto; +} + +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} + +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} + +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} + +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} + +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} + +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} + +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +input, +textarea, +.uneditable-input { + margin-left: 0; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} + +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} + +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} + +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} + +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} + +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} + +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} + +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} + +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} + +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} + +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} + +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} + +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} + +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} + +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} + +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} + +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} + +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} + +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} + +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} + +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} + +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} + +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + +.control-group { + margin-bottom: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls:first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table th { + font-weight: bold; +} + +.table thead th { + vertical-align: bottom; +} + +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success > td { + background-color: #dff0d8; +} + +.table tbody tr.error > td { + background-color: #f2dede; +} + +.table tbody tr.warning > td { + background-color: #fcf8e3; +} + +.table tbody tr.info > td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} + +/* White icons with optional class, or on hover/focus/active states of certain elements */ + +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.icon-glass { + background-position: 0 0; +} + +.icon-music { + background-position: -24px 0; +} + +.icon-search { + background-position: -48px 0; +} + +.icon-envelope { + background-position: -72px 0; +} + +.icon-heart { + background-position: -96px 0; +} + +.icon-star { + background-position: -120px 0; +} + +.icon-star-empty { + background-position: -144px 0; +} + +.icon-user { + background-position: -168px 0; +} + +.icon-film { + background-position: -192px 0; +} + +.icon-th-large { + background-position: -216px 0; +} + +.icon-th { + background-position: -240px 0; +} + +.icon-th-list { + background-position: -264px 0; +} + +.icon-ok { + background-position: -288px 0; +} + +.icon-remove { + background-position: -312px 0; +} + +.icon-zoom-in { + background-position: -336px 0; +} + +.icon-zoom-out { + background-position: -360px 0; +} + +.icon-off { + background-position: -384px 0; +} + +.icon-signal { + background-position: -408px 0; +} + +.icon-cog { + background-position: -432px 0; +} + +.icon-trash { + background-position: -456px 0; +} + +.icon-home { + background-position: 0 -24px; +} + +.icon-file { + background-position: -24px -24px; +} + +.icon-time { + background-position: -48px -24px; +} + +.icon-road { + background-position: -72px -24px; +} + +.icon-download-alt { + background-position: -96px -24px; +} + +.icon-download { + background-position: -120px -24px; +} + +.icon-upload { + background-position: -144px -24px; +} + +.icon-inbox { + background-position: -168px -24px; +} + +.icon-play-circle { + background-position: -192px -24px; +} + +.icon-repeat { + background-position: -216px -24px; +} + +.icon-refresh { + background-position: -240px -24px; +} + +.icon-list-alt { + background-position: -264px -24px; +} + +.icon-lock { + background-position: -287px -24px; +} + +.icon-flag { + background-position: -312px -24px; +} + +.icon-headphones { + background-position: -336px -24px; +} + +.icon-volume-off { + background-position: -360px -24px; +} + +.icon-volume-down { + background-position: -384px -24px; +} + +.icon-volume-up { + background-position: -408px -24px; +} + +.icon-qrcode { + background-position: -432px -24px; +} + +.icon-barcode { + background-position: -456px -24px; +} + +.icon-tag { + background-position: 0 -48px; +} + +.icon-tags { + background-position: -25px -48px; +} + +.icon-book { + background-position: -48px -48px; +} + +.icon-bookmark { + background-position: -72px -48px; +} + +.icon-print { + background-position: -96px -48px; +} + +.icon-camera { + background-position: -120px -48px; +} + +.icon-font { + background-position: -144px -48px; +} + +.icon-bold { + background-position: -167px -48px; +} + +.icon-italic { + background-position: -192px -48px; +} + +.icon-text-height { + background-position: -216px -48px; +} + +.icon-text-width { + background-position: -240px -48px; +} + +.icon-align-left { + background-position: -264px -48px; +} + +.icon-align-center { + background-position: -288px -48px; +} + +.icon-align-right { + background-position: -312px -48px; +} + +.icon-align-justify { + background-position: -336px -48px; +} + +.icon-list { + background-position: -360px -48px; +} + +.icon-indent-left { + background-position: -384px -48px; +} + +.icon-indent-right { + background-position: -408px -48px; +} + +.icon-facetime-video { + background-position: -432px -48px; +} + +.icon-picture { + background-position: -456px -48px; +} + +.icon-pencil { + background-position: 0 -72px; +} + +.icon-map-marker { + background-position: -24px -72px; +} + +.icon-adjust { + background-position: -48px -72px; +} + +.icon-tint { + background-position: -72px -72px; +} + +.icon-edit { + background-position: -96px -72px; +} + +.icon-share { + background-position: -120px -72px; +} + +.icon-check { + background-position: -144px -72px; +} + +.icon-move { + background-position: -168px -72px; +} + +.icon-step-backward { + background-position: -192px -72px; +} + +.icon-fast-backward { + background-position: -216px -72px; +} + +.icon-backward { + background-position: -240px -72px; +} + +.icon-play { + background-position: -264px -72px; +} + +.icon-pause { + background-position: -288px -72px; +} + +.icon-stop { + background-position: -312px -72px; +} + +.icon-forward { + background-position: -336px -72px; +} + +.icon-fast-forward { + background-position: -360px -72px; +} + +.icon-step-forward { + background-position: -384px -72px; +} + +.icon-eject { + background-position: -408px -72px; +} + +.icon-chevron-left { + background-position: -432px -72px; +} + +.icon-chevron-right { + background-position: -456px -72px; +} + +.icon-plus-sign { + background-position: 0 -96px; +} + +.icon-minus-sign { + background-position: -24px -96px; +} + +.icon-remove-sign { + background-position: -48px -96px; +} + +.icon-ok-sign { + background-position: -72px -96px; +} + +.icon-question-sign { + background-position: -96px -96px; +} + +.icon-info-sign { + background-position: -120px -96px; +} + +.icon-screenshot { + background-position: -144px -96px; +} + +.icon-remove-circle { + background-position: -168px -96px; +} + +.icon-ok-circle { + background-position: -192px -96px; +} + +.icon-ban-circle { + background-position: -216px -96px; +} + +.icon-arrow-left { + background-position: -240px -96px; +} + +.icon-arrow-right { + background-position: -264px -96px; +} + +.icon-arrow-up { + background-position: -289px -96px; +} + +.icon-arrow-down { + background-position: -312px -96px; +} + +.icon-share-alt { + background-position: -336px -96px; +} + +.icon-resize-full { + background-position: -360px -96px; +} + +.icon-resize-small { + background-position: -384px -96px; +} + +.icon-plus { + background-position: -408px -96px; +} + +.icon-minus { + background-position: -433px -96px; +} + +.icon-asterisk { + background-position: -456px -96px; +} + +.icon-exclamation-sign { + background-position: 0 -120px; +} + +.icon-gift { + background-position: -24px -120px; +} + +.icon-leaf { + background-position: -48px -120px; +} + +.icon-fire { + background-position: -72px -120px; +} + +.icon-eye-open { + background-position: -96px -120px; +} + +.icon-eye-close { + background-position: -120px -120px; +} + +.icon-warning-sign { + background-position: -144px -120px; +} + +.icon-plane { + background-position: -168px -120px; +} + +.icon-calendar { + background-position: -192px -120px; +} + +.icon-random { + width: 16px; + background-position: -216px -120px; +} + +.icon-comment { + background-position: -240px -120px; +} + +.icon-magnet { + background-position: -264px -120px; +} + +.icon-chevron-up { + background-position: -288px -120px; +} + +.icon-chevron-down { + background-position: -313px -119px; +} + +.icon-retweet { + background-position: -336px -120px; +} + +.icon-shopping-cart { + background-position: -360px -120px; +} + +.icon-folder-close { + width: 16px; + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + background-position: -408px -120px; +} + +.icon-resize-vertical { + background-position: -432px -119px; +} + +.icon-resize-horizontal { + background-position: -456px -118px; +} + +.icon-hdd { + background-position: 0 -144px; +} + +.icon-bullhorn { + background-position: -24px -144px; +} + +.icon-bell { + background-position: -48px -144px; +} + +.icon-certificate { + background-position: -72px -144px; +} + +.icon-thumbs-up { + background-position: -96px -144px; +} + +.icon-thumbs-down { + background-position: -120px -144px; +} + +.icon-hand-right { + background-position: -144px -144px; +} + +.icon-hand-left { + background-position: -168px -144px; +} + +.icon-hand-up { + background-position: -192px -144px; +} + +.icon-hand-down { + background-position: -216px -144px; +} + +.icon-circle-arrow-right { + background-position: -240px -144px; +} + +.icon-circle-arrow-left { + background-position: -264px -144px; +} + +.icon-circle-arrow-up { + background-position: -288px -144px; +} + +.icon-circle-arrow-down { + background-position: -312px -144px; +} + +.icon-globe { + background-position: -336px -144px; +} + +.icon-wrench { + background-position: -360px -144px; +} + +.icon-tasks { + background-position: -384px -144px; +} + +.icon-filter { + background-position: -408px -144px; +} + +.icon-briefcase { + background-position: -432px -144px; +} + +.icon-fullscreen { + background-position: -456px -144px; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle { + *margin-bottom: -3px; +} + +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; +} + +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.collapse.in { + height: auto; +} + +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.btn { + display: inline-block; + *display: inline; + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + *background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #cccccc; + *border: 0; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group > .btn + .btn { + margin-left: -1px; +} + +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 10.5px; +} + +.btn-group > .btn-small { + font-size: 11.9px; +} + +.btn-group > .btn-large { + font-size: 17.5px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group > .btn + .dropdown-toggle { + *padding-top: 5px; + padding-right: 8px; + *padding-bottom: 5px; + padding-left: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group > .btn-mini + .dropdown-toggle { + *padding-top: 2px; + padding-right: 5px; + *padding-bottom: 2px; + padding-left: 5px; +} + +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} + +.btn-group > .btn-large + .dropdown-toggle { + *padding-top: 7px; + padding-right: 12px; + *padding-bottom: 7px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} + +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} + +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} + +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} + +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} + +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} + +.btn .caret { + margin-top: 8px; + margin-left: 0; +} + +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical > .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert, +.alert h4 { + color: #c09853; +} + +.alert h4 { + margin: 0; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success h4 { + color: #468847; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info h4 { + color: #3a87ad; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.nav { + margin-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav > li > a { + display: block; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li > a > img { + max-width: none; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} + +.nav li + .nav-header { + margin-top: 9px; +} + +.nav-list { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.nav-list > li > a { + padding: 3px 15px; +} + +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs, +.nav-pills { + *zoom: 1; +} + +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + line-height: 0; + content: ""; +} + +.nav-tabs:after, +.nav-pills:after { + clear: both; +} + +.nav-tabs > li, +.nav-pills > li { + float: left; +} + +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs > li { + margin-bottom: -1px; +} + +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li > a { + margin-right: 0; +} + +.nav-tabs.nav-stacked { + border-bottom: 0; +} + +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + z-index: 2; + border-color: #ddd; +} + +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} + +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} + +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.nav .dropdown-toggle .caret { + margin-top: 6px; + border-top-color: #0088cc; + border-bottom-color: #0088cc; +} + +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} + +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + content: ""; +} + +.tabbable:after { + clear: both; +} + +.tab-content { + overflow: auto; +} + +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} + +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} + +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} + +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} + +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; +} + +.navbar-inner { + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-form:after { + clear: both; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} + +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} + +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav > li { + float: left; +} + +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} + +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} + +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} + +.navbar .nav > li > .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav > li > .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} + +.navbar-inverse .brand { + color: #999999; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.pagination ul > li { + display: inline; +} + +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} + +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} + +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} + +.modal.fade { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-title:empty { + display: none; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; +} + +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} + +.thumbnails:before, +.thumbnails:after { + display: table; + line-height: 0; + content: ""; +} + +.thumbnails:after { + clear: both; +} + +.row-fluid .thumbnails { + margin-left: 0; +} + +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} + +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} + +.thumbnail > img { + display: block; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #555555; +} + +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + margin-left: 0; + list-style: none; +} + +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; +} + +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.badge { + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.label:empty, +.badge:empty { + display: none; +} + +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label-important, +.badge-important { + background-color: #b94a48; +} + +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} + +.label-warning, +.badge-warning { + background-color: #f89406; +} + +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} + +.label-success, +.badge-success { + background-color: #468847; +} + +.label-success[href], +.badge-success[href] { + background-color: #356635; +} + +.label-info, +.badge-info { + background-color: #3a87ad; +} + +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} + +.label-inverse, +.badge-inverse { + background-color: #333333; +} + +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} + +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} + +.btn-mini .label, +.btn-mini .badge { + top: 0; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress .bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); +} + +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} + +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} + +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} + +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} + +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} + +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.accordion { + margin-bottom: 20px; +} + +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.accordion-heading { + border-bottom: 0; +} + +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} + +.accordion-toggle { + cursor: pointer; +} + +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} + +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.right { + right: 15px; + left: auto; +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} + +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; +} + +.hero-unit li { + line-height: 30px; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/doc/_static/bootstrap.js b/doc/_static/bootstrap.js new file mode 100644 index 0000000..44109f6 --- /dev/null +++ b/doc/_static/bootstrap.js @@ -0,0 +1,2280 @@ +/* =================================================== + * bootstrap-transition.js v2.3.2 + * http://getbootstrap.com/2.3.2/javascript.html#transitions + * =================================================== + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-alert.js v2.3.2 + * http://getbootstrap.com/2.3.2/javascript.html#alerts + * ========================================================== + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT NO CONFLICT + * ================= */ + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.jQuery);/* ============================================================ + * bootstrap-button.js v2.3.2 + * http://getbootstrap.com/2.3.2/javascript.html#buttons + * ============================================================ + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON NO CONFLICT + * ================== */ + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-carousel.js v2.3.2 + * http://getbootstrap.com/2.3.2/javascript.html#carousel + * ========================================================== + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + if (this.interval) clearInterval(this.interval); + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , getActiveIndex: function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + return this.$items.index(this.$active) + } + + , to: function (pos) { + var activeIndex = this.getActiveIndex() + , that = this + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activeIndex == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + , direction: direction + }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + , slideIndex + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('carousel').pause().to(slideIndex).cycle() + } + + e.preventDefault() + }) + +}(window.jQuery);/* ============================================================= + * bootstrap-collapse.js v2.3.2 + * http://getbootstrap.com/2.3.2/javascript.html#collapse + * ============================================================= + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning || this.$element.hasClass('in')) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning || !this.$element.hasClass('in')) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSE PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSE NO CONFLICT + * ==================== */ + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + /* COLLAPSE DATA-API + * ================= */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.jQuery);/* ============================================================ + * bootstrap-dropdown.js v2.3.2 + * http://getbootstrap.com/2.3.2/javascript.html#dropdowns + * ============================================================ + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement) { + // if mobile we we use a backdrop because click events don't delegate + $('