From 0b7fd816a256229829c5114d60bf1c85e817d08a Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 21 May 2016 00:40:03 +0200 Subject: [PATCH 1/2] Add a project for Vulkan port. --- amd_lib/shared/common/inc/AMD_Types.h | 4 + .../shared/d3d11/build/AMD_LIB_2010.vcxproj | 1 - .../d3d11/build/AMD_LIB_2010.vcxproj.filters | 25 +- .../shared/d3d11/build/AMD_LIB_2012.vcxproj | 1 - .../d3d11/build/AMD_LIB_2012.vcxproj.filters | 25 +- .../shared/d3d11/build/AMD_LIB_2013.vcxproj | 1 - .../d3d11/build/AMD_LIB_2013.vcxproj.filters | 25 +- .../shared/d3d11/build/AMD_LIB_2015.vcxproj | 1 - .../d3d11/build/AMD_LIB_2015.vcxproj.filters | 25 +- amd_tressfx/inc/AMD_TressFX.h | 77 +- .../build/TressFX_Viewer_2012.sln | 6 + .../build/TressFX_Viewer_2013.sln | 6 + .../build/TressFX_Viewer_2015.sln | 6 + amd_tressfx_viewer/premake/premake5.lua | 10 + .../build/AMD_TressFX_Vulkan_2012.sln | 66 + .../build/AMD_TressFX_Vulkan_2012.vcxproj | 567 + .../AMD_TressFX_Vulkan_2012.vcxproj.filters | 167 + .../build/AMD_TressFX_Vulkan_2013.sln | 66 + .../build/AMD_TressFX_Vulkan_2013.vcxproj | 568 + .../AMD_TressFX_Vulkan_2013.vcxproj.filters | 167 + .../build/AMD_TressFX_Vulkan_2015.sln | 66 + .../build/AMD_TressFX_Vulkan_2015.vcxproj | 559 + .../AMD_TressFX_Vulkan_2015.vcxproj.filters | 167 + amd_tressfx_vulkan/premake/premake5.lua | 94 + .../shader_builder/shader_builder.py | 67 + .../shader_builder/shader_builder.pyproj | 41 + .../src/Shaders/ComputeCoverage.glsl | 33 + .../src/Shaders/ComputeHairShading.glsl | 83 + .../src/Shaders/ComputeShadow.glsl | 93 + .../src/Shaders/ComputeTangents.comp | 44 + .../src/Shaders/FS_Depth_Hair_Data.frag | 78 + .../src/Shaders/FS_FillColors_Hair_Data.frag | 134 + .../Shaders/FS_ResolveColor_Hair_Data.frag | 119 + .../Shaders/FS_ResolveDepth_Hair_Data.frag | 31 + .../src/Shaders/GlobalConstraints.comp | 143 + .../src/Shaders/HairShadowMap.frag | 7 + .../src/Shaders/HairShadowMap.vert | 17 + .../src/Shaders/IndicesComputations.glsl | 45 + .../src/Shaders/LengthWindCollision.comp | 199 + .../src/Shaders/LocalConstraints.comp | 173 + .../src/Shaders/PackUnpack.glsl | 31 + .../src/Shaders/PrepareFollowHair.comp | 29 + .../src/Shaders/RenderConfig.glsl | 92 + .../src/Shaders/RenderHair.vert | 59 + .../src/Shaders/RenderHairAA.vert | 65 + .../src/Shaders/RenderHairAAStrandCopies.vert | 85 + .../src/Shaders/RenderHairStrandCopies.vert | 77 + .../src/Shaders/SimulationConfig.glsl | 92 + .../src/Shaders/TressFXRender_pass2.frag | 147 + .../src/Shaders/TressFXRender_pass2.vert | 20 + .../src/Shaders/TressFxRender.frag | 67 + .../src/Shaders/UpdateFollowHair.comp | 37 + amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp | 1147 + amd_tressfx_vulkan/src/TressFXMeshVulkan.h | 171 + .../src/TressFXOpaqueVulkan.cpp | 228 + amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h | 75 + .../src/TressFXPrecompiledShadersVulkan.h | 49053 ++++++++++++++++ .../src/TressFXRendererVulkan.cpp | 1569 + .../src/TressFXRendererVulkan.h | 174 + .../src/TressFXShortCutVulkan.cpp | 865 + .../src/TressFXShortCutVulkan.h | 142 + .../src/TressFXSimulationVulkan.cpp | 1180 + .../src/TressFXSimulationVulkan.h | 133 + amd_tressfx_vulkan/src/TressFXVulkan.cpp | 319 + amd_tressfx_vulkan/src/UtilVulkan.cpp | 375 + amd_tressfx_vulkan/src/UtilVulkan.h | 114 + 66 files changed, 60267 insertions(+), 86 deletions(-) create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.sln create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj.filters create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.sln create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj.filters create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.sln create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj create mode 100644 amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj.filters create mode 100644 amd_tressfx_vulkan/premake/premake5.lua create mode 100644 amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py create mode 100644 amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.pyproj create mode 100644 amd_tressfx_vulkan/src/Shaders/ComputeCoverage.glsl create mode 100644 amd_tressfx_vulkan/src/Shaders/ComputeHairShading.glsl create mode 100644 amd_tressfx_vulkan/src/Shaders/ComputeShadow.glsl create mode 100644 amd_tressfx_vulkan/src/Shaders/ComputeTangents.comp create mode 100644 amd_tressfx_vulkan/src/Shaders/FS_Depth_Hair_Data.frag create mode 100644 amd_tressfx_vulkan/src/Shaders/FS_FillColors_Hair_Data.frag create mode 100644 amd_tressfx_vulkan/src/Shaders/FS_ResolveColor_Hair_Data.frag create mode 100644 amd_tressfx_vulkan/src/Shaders/FS_ResolveDepth_Hair_Data.frag create mode 100644 amd_tressfx_vulkan/src/Shaders/GlobalConstraints.comp create mode 100644 amd_tressfx_vulkan/src/Shaders/HairShadowMap.frag create mode 100644 amd_tressfx_vulkan/src/Shaders/HairShadowMap.vert create mode 100644 amd_tressfx_vulkan/src/Shaders/IndicesComputations.glsl create mode 100644 amd_tressfx_vulkan/src/Shaders/LengthWindCollision.comp create mode 100644 amd_tressfx_vulkan/src/Shaders/LocalConstraints.comp create mode 100644 amd_tressfx_vulkan/src/Shaders/PackUnpack.glsl create mode 100644 amd_tressfx_vulkan/src/Shaders/PrepareFollowHair.comp create mode 100644 amd_tressfx_vulkan/src/Shaders/RenderConfig.glsl create mode 100644 amd_tressfx_vulkan/src/Shaders/RenderHair.vert create mode 100644 amd_tressfx_vulkan/src/Shaders/RenderHairAA.vert create mode 100644 amd_tressfx_vulkan/src/Shaders/RenderHairAAStrandCopies.vert create mode 100644 amd_tressfx_vulkan/src/Shaders/RenderHairStrandCopies.vert create mode 100644 amd_tressfx_vulkan/src/Shaders/SimulationConfig.glsl create mode 100644 amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.frag create mode 100644 amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert create mode 100644 amd_tressfx_vulkan/src/Shaders/TressFxRender.frag create mode 100644 amd_tressfx_vulkan/src/Shaders/UpdateFollowHair.comp create mode 100644 amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp create mode 100644 amd_tressfx_vulkan/src/TressFXMeshVulkan.h create mode 100644 amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp create mode 100644 amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h create mode 100644 amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h create mode 100644 amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp create mode 100644 amd_tressfx_vulkan/src/TressFXRendererVulkan.h create mode 100644 amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp create mode 100644 amd_tressfx_vulkan/src/TressFXShortCutVulkan.h create mode 100644 amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp create mode 100644 amd_tressfx_vulkan/src/TressFXSimulationVulkan.h create mode 100644 amd_tressfx_vulkan/src/TressFXVulkan.cpp create mode 100644 amd_tressfx_vulkan/src/UtilVulkan.cpp create mode 100644 amd_tressfx_vulkan/src/UtilVulkan.h diff --git a/amd_lib/shared/common/inc/AMD_Types.h b/amd_lib/shared/common/inc/AMD_Types.h index 3bb5b42..18643a9 100644 --- a/amd_lib/shared/common/inc/AMD_Types.h +++ b/amd_lib/shared/common/inc/AMD_Types.h @@ -156,7 +156,11 @@ namespace AMD #define AMD_SAFE_DELETE_ARRAY(p) { delete [] (p); (p) = nullptr; } #endif #ifndef AMD_SAFE_RELEASE +#ifndef VULKAN #define AMD_SAFE_RELEASE(p) { if (p) { (p)->Release(); } (p) = nullptr; } +#else +#define AMD_SAFE_RELEASE(object, releaseFunction, device) if (object != nullptr) releaseFunction(device, object, nullptr); +#endif #endif #define AMD_FUNCTION_WIDEN2(x) L ## x diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj b/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj index 46478b0..81c0d27 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj @@ -288,7 +288,6 @@ - diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj.filters b/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj.filters index ed6f070..42f78d0 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj.filters +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2010.vcxproj.filters @@ -1,23 +1,11 @@ - - {61705900-4DFC-870B-B6AA-880BA255880B} + + {AEFEE3F6-9AA0-0ECD-835B-22216F9C951D} - - {CC6E590B-3883-81BC-0105-251C6DD87DED} - - - {4CE19223-B8A1-0E5A-81DC-57D7ED5B5336} - - - {553A9689-C150-941F-0AC8-1F41761D65A7} - - - {993A4365-05A5-F7DB-4EE3-A881BA8CD530} - - - {22723C73-8E32-B8A9-576D-0127C3ECFC85} + + {B7381BB1-A3F0-5CFE-0CF8-355AF8CEF7EE} {1F80880B-8B89-887C-1405-9F7C800D947C} @@ -59,11 +47,8 @@ - - ..\..\ags_lib\inc - - ..\common\inc + common\inc inc diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj b/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj index c21f221..8bb6f31 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj @@ -288,7 +288,6 @@ - diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj.filters b/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj.filters index ed6f070..42f78d0 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj.filters +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2012.vcxproj.filters @@ -1,23 +1,11 @@ - - {61705900-4DFC-870B-B6AA-880BA255880B} + + {AEFEE3F6-9AA0-0ECD-835B-22216F9C951D} - - {CC6E590B-3883-81BC-0105-251C6DD87DED} - - - {4CE19223-B8A1-0E5A-81DC-57D7ED5B5336} - - - {553A9689-C150-941F-0AC8-1F41761D65A7} - - - {993A4365-05A5-F7DB-4EE3-A881BA8CD530} - - - {22723C73-8E32-B8A9-576D-0127C3ECFC85} + + {B7381BB1-A3F0-5CFE-0CF8-355AF8CEF7EE} {1F80880B-8B89-887C-1405-9F7C800D947C} @@ -59,11 +47,8 @@ - - ..\..\ags_lib\inc - - ..\common\inc + common\inc inc diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj b/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj index fef26f1..f7f9d39 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj @@ -289,7 +289,6 @@ - diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj.filters b/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj.filters index ed6f070..42f78d0 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj.filters +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2013.vcxproj.filters @@ -1,23 +1,11 @@ - - {61705900-4DFC-870B-B6AA-880BA255880B} + + {AEFEE3F6-9AA0-0ECD-835B-22216F9C951D} - - {CC6E590B-3883-81BC-0105-251C6DD87DED} - - - {4CE19223-B8A1-0E5A-81DC-57D7ED5B5336} - - - {553A9689-C150-941F-0AC8-1F41761D65A7} - - - {993A4365-05A5-F7DB-4EE3-A881BA8CD530} - - - {22723C73-8E32-B8A9-576D-0127C3ECFC85} + + {B7381BB1-A3F0-5CFE-0CF8-355AF8CEF7EE} {1F80880B-8B89-887C-1405-9F7C800D947C} @@ -59,11 +47,8 @@ - - ..\..\ags_lib\inc - - ..\common\inc + common\inc inc diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj b/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj index af775b4..4722368 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj @@ -284,7 +284,6 @@ - diff --git a/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj.filters b/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj.filters index ed6f070..42f78d0 100644 --- a/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj.filters +++ b/amd_lib/shared/d3d11/build/AMD_LIB_2015.vcxproj.filters @@ -1,23 +1,11 @@ - - {61705900-4DFC-870B-B6AA-880BA255880B} + + {AEFEE3F6-9AA0-0ECD-835B-22216F9C951D} - - {CC6E590B-3883-81BC-0105-251C6DD87DED} - - - {4CE19223-B8A1-0E5A-81DC-57D7ED5B5336} - - - {553A9689-C150-941F-0AC8-1F41761D65A7} - - - {993A4365-05A5-F7DB-4EE3-A881BA8CD530} - - - {22723C73-8E32-B8A9-576D-0127C3ECFC85} + + {B7381BB1-A3F0-5CFE-0CF8-355AF8CEF7EE} {1F80880B-8B89-887C-1405-9F7C800D947C} @@ -59,11 +47,8 @@ - - ..\..\ags_lib\inc - - ..\common\inc + common\inc inc diff --git a/amd_tressfx/inc/AMD_TressFX.h b/amd_tressfx/inc/AMD_TressFX.h index aa4fd4f..3de38ff 100644 --- a/amd_tressfx/inc/AMD_TressFX.h +++ b/amd_tressfx/inc/AMD_TressFX.h @@ -24,6 +24,10 @@ #define AMD_TRESSFX_H #include +#ifdef VULKAN +#include +#endif + #include #define AMD_TRESSFX_VERSION_MAJOR 3 @@ -75,6 +79,19 @@ #define IDSRV_HAIR_FRAGMENT_COLORS 14 #define IDSRV_HAIR_ACCUM_INV_ALPHA 15 +#define IDSRV_CONSTANTS_BUFFER 16 +#define IDSRV_ATOMIC_COUNTER_BUFFER 17 +#define IDSRV_NOISE_SAMPLER 18 +#define IDSRV_SHADOW_SAMPLER 19 + +#define IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS 20 +#define IDSRV_HAIR_VERTEX_INITIAL_POSITIONS 21 +#define IDSRV_HAIR_STRAND_TYPE 22 +#define IDSRV_HAIR_GLOBAL_ROTATION 23 +#define IDSRV_HAIR_LOCAL_REF_VEC 24 +#define IDSRV_HAIR_ROOT_OFFSET 25 +#define IDSRV_HAIR_LENGTH 26 +#define IDSRV_HEAD_TRANSFORM 27 #if defined(DEBUG) || defined(_DEBUG) #define AMD_TRESSFX_DEBUG 1 @@ -167,10 +184,18 @@ struct TressFX_HairBlob struct TressFX_SceneMesh { +#ifndef VULKAN ID3D11ShaderResourceView* pMeshVertices; // untransformed vertices +#else + VkBufferView pMeshVertices; // untransformed vertices +#endif unsigned numMeshes; // number of meshes unsigned* meshOffsets; // offset to the start of each mesh +#ifndef VULKAN ID3D11ShaderResourceView* pTransformedVerts; // transformed vertices +#else + VkBufferView pTransformedVerts; // untransformed vertices +#endif }; struct TressFX_HairTransform @@ -227,32 +252,80 @@ struct TressFX_Desc // Buffer of transformations (one transform per strand) for hair skinning // This UAV is used as a structured buffer where each element is a TressFX_HairTransform. // The number of elements in the buffer is numTotalHairStrands. +#ifndef VULKAN ID3D11UnorderedAccessView* pSkinningTransformationsUAV; +#else + VkBufferView pSkinningTransformationsUAV; +#endif // hair shadow map +#ifndef VULKAN ID3D11ShaderResourceView* pHairShadowMapSRV; +#else + VkImageView pHairShadowMapSRV; +#endif +#ifndef VULKAN ID3D11Device* pd3dDevice; ID3D11DeviceContext* pd3dDeviceContext; ID3D11ShaderResourceView* pd3dDepthSRV; ID3D11RenderTargetView* pd3dOutputRTV; +#else + VkDevice pvkDevice; + uint32_t memoryIndexDeviceLocal; + uint32_t memoryIndexHostVisible; + VkImageView pvkDepthSRV; + uint32_t maxConstantBuffers; + VkFormat depthStencilFormat; + VkFormat colorFormat; +#endif // !VULKAN }; extern "C" { AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_GetVersion(uint* major, uint* minor, uint* patch); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Initialize(TressFX_Desc & desc); +#ifdef VULKAN + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Initialize( + TressFX_Desc &desc, VkImageView depthTexture, VkImageView colorTexture, + VkCommandBuffer commandBuffer, VkDeviceMemory scratchMemory, + VkBuffer scratchBuffer, size_t &offsetInScratchBuffer); +#else + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Initialize(TressFX_Desc &desc); +#endif AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadRawAsset(TressFX_Desc & desc, const TressFX_GuideFollowParams& guideFollowParams, TressFX_HairBlob *pRawHairBlob); +#ifndef VULKAN AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadProcessedAsset(TressFX_Desc & desc, TressFX_HairBlob *pHairBlob, TressFX_SceneMesh *sceneMesh, ID3D11ShaderResourceView *pTextureSRV); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_CreateProcessedAsset(TressFX_Desc & desc, TressFX_HairBlob **ppHairBlob, TressFX_SceneMesh *sceneMesh, ID3D11ShaderResourceView *pTextureSRV); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Begin(TressFX_Desc & desc); +#else + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadProcessedAsset( + TressFX_Desc &desc, TressFX_HairBlob *pHairBlob, + TressFX_SceneMesh *sceneMesh, VkImageView pTextureSRV, + VkCommandBuffer uploadCmdBuffer, + VkBuffer scratchBuffer, VkDeviceMemory scratchMemory); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_CreateProcessedAsset( + TressFX_Desc &desc, TressFX_HairBlob **ppHairBlob, + TressFX_SceneMesh *sceneMesh, VkImageView pTextureSRV, + VkCommandBuffer uploadCmdBuffer, + VkBuffer scratchBuffer, VkDeviceMemory scratchMemory); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Begin(TressFX_Desc & desc, uint32_t uniformBufferIndex); +#endif AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_End(TressFX_Desc & desc); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_GenerateTransforms(TressFX_Desc & desc, TressFX_SceneMesh &sceneMesh); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_ApplyRigidTransforms(TressFX_Desc & desc); +#ifndef VULKAN AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Simulate(TressFX_Desc & desc, float elapsedTime); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_RenderShadowMap(TressFX_Desc & desc); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Render(TressFX_Desc & desc); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Resize(TressFX_Desc & desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Resize(TressFX_Desc &desc); +#else + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Simulate(TressFX_Desc & desc, VkCommandBuffer commandBuffer, float elapsedTime, uint32_t uniformBufferIndex); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_RenderShadowMap(TressFX_Desc & desc, VkCommandBuffer commandBuffer, uint32_t uniformBufferIndex); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE + TressFX_Render(TressFX_Desc &desc, VkCommandBuffer commandBuffer, uint32_t uniformBufferIndex); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE + TressFX_Resize(TressFX_Desc &desc, uint32_t texture_memory_index); +#endif AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Release(TressFX_Desc & desc); } diff --git a/amd_tressfx_viewer/build/TressFX_Viewer_2012.sln b/amd_tressfx_viewer/build/TressFX_Viewer_2012.sln index d8add24..6dfac25 100644 --- a/amd_tressfx_viewer/build/TressFX_Viewer_2012.sln +++ b/amd_tressfx_viewer/build/TressFX_Viewer_2012.sln @@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_SDK_Minimal", "..\..\fr EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX", "..\..\AMD_TressFX\build\AMD_TressFX_2012.vcxproj", "{252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX_Vulkan", "..\..\AMD_TressFX_Vulkan\build\AMD_TressFX_Vulkan_2012.vcxproj", "{9B729252-7D58-4B28-882F-DFB4EF44A485}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXUT", "..\..\framework\d3d11\dxut\Core\DXUT_2012.vcxproj", "{85344B7F-5AA0-4E12-A065-D1333D11F6CA}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXUTOpt", "..\..\framework\d3d11\dxut\Optional\DXUTOpt_2012.vcxproj", "{61B333C2-C4F7-4CC1-A9BF-83F6D95588EB}" @@ -35,6 +37,10 @@ Global {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Debug|x64.Build.0 = DLL_Debug|x64 {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Release|x64.ActiveCfg = DLL_Release|x64 {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Release|x64.Build.0 = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Debug|x64.ActiveCfg = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Debug|x64.Build.0 = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Release|x64.ActiveCfg = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Release|x64.Build.0 = DLL_Release|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Debug|x64.ActiveCfg = Debug|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Debug|x64.Build.0 = Debug|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Release|x64.ActiveCfg = Release|x64 diff --git a/amd_tressfx_viewer/build/TressFX_Viewer_2013.sln b/amd_tressfx_viewer/build/TressFX_Viewer_2013.sln index 741b627..1e91dac 100644 --- a/amd_tressfx_viewer/build/TressFX_Viewer_2013.sln +++ b/amd_tressfx_viewer/build/TressFX_Viewer_2013.sln @@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_SDK_Minimal", "..\..\fr EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX", "..\..\AMD_TressFX\build\AMD_TressFX_2013.vcxproj", "{252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX_Vulkan", "..\..\AMD_TressFX_Vulkan\build\AMD_TressFX_Vulkan_2013.vcxproj", "{9B729252-7D58-4B28-882F-DFB4EF44A485}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXUT", "..\..\framework\d3d11\dxut\Core\DXUT_2013.vcxproj", "{85344B7F-5AA0-4E12-A065-D1333D11F6CA}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXUTOpt", "..\..\framework\d3d11\dxut\Optional\DXUTOpt_2013.vcxproj", "{61B333C2-C4F7-4CC1-A9BF-83F6D95588EB}" @@ -35,6 +37,10 @@ Global {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Debug|x64.Build.0 = DLL_Debug|x64 {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Release|x64.ActiveCfg = DLL_Release|x64 {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Release|x64.Build.0 = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Debug|x64.ActiveCfg = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Debug|x64.Build.0 = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Release|x64.ActiveCfg = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Release|x64.Build.0 = DLL_Release|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Debug|x64.ActiveCfg = Debug|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Debug|x64.Build.0 = Debug|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Release|x64.ActiveCfg = Release|x64 diff --git a/amd_tressfx_viewer/build/TressFX_Viewer_2015.sln b/amd_tressfx_viewer/build/TressFX_Viewer_2015.sln index ad6a952..7caf805 100644 --- a/amd_tressfx_viewer/build/TressFX_Viewer_2015.sln +++ b/amd_tressfx_viewer/build/TressFX_Viewer_2015.sln @@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_SDK_Minimal", "..\..\fr EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX", "..\..\AMD_TressFX\build\AMD_TressFX_2015.vcxproj", "{252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX_Vulkan", "..\..\AMD_TressFX_Vulkan\build\AMD_TressFX_Vulkan_2015.vcxproj", "{9B729252-7D58-4B28-882F-DFB4EF44A485}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXUT", "..\..\framework\d3d11\dxut\Core\DXUT_2015.vcxproj", "{85344B7F-5AA0-4E12-A065-D1333D11F6CA}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXUTOpt", "..\..\framework\d3d11\dxut\Optional\DXUTOpt_2015.vcxproj", "{61B333C2-C4F7-4CC1-A9BF-83F6D95588EB}" @@ -35,6 +37,10 @@ Global {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Debug|x64.Build.0 = DLL_Debug|x64 {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Release|x64.ActiveCfg = DLL_Release|x64 {252C0AF0-91E1-82E5-1AD6-7CBC868A79E9}.Release|x64.Build.0 = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Debug|x64.ActiveCfg = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Debug|x64.Build.0 = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Release|x64.ActiveCfg = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Release|x64.Build.0 = DLL_Release|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Debug|x64.ActiveCfg = Debug|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Debug|x64.Build.0 = Debug|x64 {85344B7F-5AA0-4E12-A065-D1333D11F6CA}.Release|x64.ActiveCfg = Release|x64 diff --git a/amd_tressfx_viewer/premake/premake5.lua b/amd_tressfx_viewer/premake/premake5.lua index 3ebfad4..b0fafad 100644 --- a/amd_tressfx_viewer/premake/premake5.lua +++ b/amd_tressfx_viewer/premake/premake5.lua @@ -25,6 +25,16 @@ externalproject ("AMD_" .. _AMD_LIBRARY_NAME) ["Debug"] = "DLL_Debug", ["Release"] = "DLL_Release" } +externalproject ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan") + kind "SharedLib" + language "C++" + location "../../AMD_%{_AMD_LIBRARY_NAME}_Vulkan/build" + filename ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan" .. _AMD_VS_SUFFIX) + uuid "9B729252-7D58-4B28-882F-DFB4EF44A485" + configmap { + ["Debug"] = "DLL_Debug", + ["Release"] = "DLL_Release" } + externalproject "AMD_LIB_Minimal" kind "StaticLib" language "C++" diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.sln b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.sln new file mode 100644 index 0000000..168ff52 --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.sln @@ -0,0 +1,66 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX_Vulkan", "AMD_TressFX_Vulkan_2012.vcxproj", "{9B729252-7D58-4B28-882F-DFB4EF44A485}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_LIB_Minimal", "..\..\amd_lib\shared\d3d11\build\AMD_LIB_Minimal_2012.vcxproj", "{0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DLL_Debug|Win32 = DLL_Debug|Win32 + DLL_Debug|x64 = DLL_Debug|x64 + DLL_Release_MT|Win32 = DLL_Release_MT|Win32 + DLL_Release_MT|x64 = DLL_Release_MT|x64 + DLL_Release|Win32 = DLL_Release|Win32 + DLL_Release|x64 = DLL_Release|x64 + Lib_Debug|Win32 = Lib_Debug|Win32 + Lib_Debug|x64 = Lib_Debug|x64 + Lib_Release|Win32 = Lib_Release|Win32 + Lib_Release|x64 = Lib_Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|Win32.ActiveCfg = DLL_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|Win32.Build.0 = DLL_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|x64.ActiveCfg = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|x64.Build.0 = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|Win32.ActiveCfg = DLL_Release_MT|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|Win32.Build.0 = DLL_Release_MT|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|x64.ActiveCfg = DLL_Release_MT|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|x64.Build.0 = DLL_Release_MT|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|Win32.ActiveCfg = DLL_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|Win32.Build.0 = DLL_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|x64.ActiveCfg = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|x64.Build.0 = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|Win32.ActiveCfg = Lib_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|Win32.Build.0 = Lib_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|x64.ActiveCfg = Lib_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|x64.Build.0 = Lib_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|Win32.ActiveCfg = Lib_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|Win32.Build.0 = Lib_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|x64.ActiveCfg = Lib_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|x64.Build.0 = Lib_Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|Win32.ActiveCfg = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|Win32.Build.0 = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|x64.ActiveCfg = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|x64.Build.0 = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|Win32.ActiveCfg = Release_MT|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|Win32.Build.0 = Release_MT|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|x64.ActiveCfg = Release_MT|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|x64.Build.0 = Release_MT|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|Win32.ActiveCfg = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|Win32.Build.0 = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|x64.ActiveCfg = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|x64.Build.0 = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|Win32.ActiveCfg = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|Win32.Build.0 = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|x64.ActiveCfg = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|x64.Build.0 = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|Win32.ActiveCfg = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|Win32.Build.0 = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|x64.ActiveCfg = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj new file mode 100644 index 0000000..4e7fe13 --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj @@ -0,0 +1,567 @@ + + + + + DLL_Debug + Win32 + + + DLL_Debug + x64 + + + DLL_Release + Win32 + + + DLL_Release + x64 + + + Lib_Debug + Win32 + + + Lib_Debug + x64 + + + Lib_Release + Win32 + + + Lib_Release + x64 + + + DLL_Release_MT + Win32 + + + DLL_Release_MT + x64 + + + + {9B729252-7D58-4B28-882F-DFB4EF44A485} + Win32Proj + AMD_TressFX_Vulkan + AMD_TressFX_Vulkan + + + + DynamicLibrary + true + Unicode + v110 + + + DynamicLibrary + true + Unicode + v110 + + + DynamicLibrary + false + Unicode + v110 + + + DynamicLibrary + false + Unicode + v110 + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + false + Unicode + v110 + + + StaticLibrary + false + Unicode + v110 + + + DynamicLibrary + false + Unicode + v110 + + + DynamicLibrary + false + Unicode + v110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ..\lib\VS2012\Win32\DLL_Debug\ + VS2012\Win32\DLL_Debug\ + GPUOpen_TressFX_x86d + .dll + + + true + ..\lib\VS2012\x64\DLL_Debug\ + VS2012\x64\DLL_Debug\ + GPUOpen_TressFX_x64d + .dll + + + false + ..\lib\VS2012\Win32\DLL_Release\ + VS2012\Win32\DLL_Release\ + GPUOpen_TressFX_x86 + .dll + + + false + ..\lib\VS2012\x64\DLL_Release\ + VS2012\x64\DLL_Release\ + GPUOpen_TressFX_x64 + .dll + + + ..\lib\VS2012\Win32\Lib_Debug\ + VS2012\Win32\Lib_Debug\ + GPUOpen_TressFX_x86d + .lib + + + ..\lib\VS2012\x64\Lib_Debug\ + VS2012\x64\Lib_Debug\ + GPUOpen_TressFX_x64d + .lib + + + ..\lib\VS2012\Win32\Lib_Release\ + VS2012\Win32\Lib_Release\ + GPUOpen_TressFX_x86 + .lib + + + ..\lib\VS2012\x64\Lib_Release\ + VS2012\x64\Lib_Release\ + GPUOpen_TressFX_x64 + .lib + + + false + ..\lib\VS2012\Win32\DLL_Release_MT\ + VS2012\Win32\DLL_Release_MT\ + GPUOpen_TressFX_x86 + .dll + + + false + ..\lib\VS2012\x64\DLL_Release_MT\ + VS2012\x64\DLL_Release_MT\ + GPUOpen_TressFX_x64 + .dll + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2012\Win32\DLL_Debug\GPUOpen_TressFX_x86d.lib + true + + + copy /b "..\lib\VS2012\Win32\DLL_Debug\$(TargetName).lib" +,, "..\lib\VS2012\Win32\DLL_Debug\" > nul +xcopy "..\lib\VS2012\Win32\DLL_Debug\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2012\Win32\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + ProgramDatabase + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2012\x64\DLL_Debug\GPUOpen_TressFX_x64d.lib + true + + + copy /b "..\lib\VS2012\x64\DLL_Debug\$(TargetName).lib" +,, "..\lib\VS2012\x64\DLL_Debug\" > nul +xcopy "..\lib\VS2012\x64\DLL_Debug\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2012\x64\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2012\Win32\DLL_Release\GPUOpen_TressFX_x86.lib + true + + + copy /b "..\lib\VS2012\Win32\DLL_Release\$(TargetName).lib" +,, "..\lib\VS2012\Win32\DLL_Release\" > nul +xcopy "..\lib\VS2012\Win32\DLL_Release\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2012\Win32\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2012\x64\DLL_Release\GPUOpen_TressFX_x64.lib + true + + + copy /b "..\lib\VS2012\x64\DLL_Release\$(TargetName).lib" +,, "..\lib\VS2012\x64\DLL_Release\" > nul +xcopy "..\lib\VS2012\x64\DLL_Release\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2012\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + ProgramDatabase + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + MultiThreaded + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2012\Win32\DLL_Release_MT\GPUOpen_TressFX_x86.lib + true + + + copy /b "..\lib\VS2012\Win32\DLL_Release_MT\$(TargetName).lib" +,, "..\lib\VS2012\Win32\DLL_Release_MT\" > nul +xcopy "..\lib\VS2012\Win32\DLL_Release_MT\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2012\Win32\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + MultiThreaded + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2012\x64\DLL_Release_MT\GPUOpen_TressFX_x64.lib + true + + + copy /b "..\lib\VS2012\x64\DLL_Release_MT\$(TargetName).lib" +,, "..\lib\VS2012\x64\DLL_Release_MT\" > nul +xcopy "..\lib\VS2012\x64\DLL_Release_MT\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2012\x64\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44} + + + + + + \ No newline at end of file diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj.filters b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj.filters new file mode 100644 index 0000000..9682ca1 --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj.filters @@ -0,0 +1,167 @@ + + + + + {E5B4C84B-516A-4141-DA5E-3B1846133845} + + + {7C5D4EB9-E8E8-BB7D-F1F9-3E725D04187E} + + + {D58F8ECE-C11E-1898-6A3D-2C9356AB283E} + + + {2DAB880B-99B4-887C-2230-9F7C8E38947C} + + + {06ADC7FB-7262-40F1-FB56-3AC8670B37F5} + + + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src + + + amd_tressfx\src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + \ No newline at end of file diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.sln b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.sln new file mode 100644 index 0000000..d0c6490 --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.sln @@ -0,0 +1,66 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX_Vulkan", "AMD_TressFX_Vulkan_2013.vcxproj", "{9B729252-7D58-4B28-882F-DFB4EF44A485}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_LIB_Minimal", "..\..\amd_lib\shared\d3d11\build\AMD_LIB_Minimal_2013.vcxproj", "{0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DLL_Debug|Win32 = DLL_Debug|Win32 + DLL_Debug|x64 = DLL_Debug|x64 + DLL_Release_MT|Win32 = DLL_Release_MT|Win32 + DLL_Release_MT|x64 = DLL_Release_MT|x64 + DLL_Release|Win32 = DLL_Release|Win32 + DLL_Release|x64 = DLL_Release|x64 + Lib_Debug|Win32 = Lib_Debug|Win32 + Lib_Debug|x64 = Lib_Debug|x64 + Lib_Release|Win32 = Lib_Release|Win32 + Lib_Release|x64 = Lib_Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|Win32.ActiveCfg = DLL_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|Win32.Build.0 = DLL_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|x64.ActiveCfg = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|x64.Build.0 = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|Win32.ActiveCfg = DLL_Release_MT|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|Win32.Build.0 = DLL_Release_MT|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|x64.ActiveCfg = DLL_Release_MT|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|x64.Build.0 = DLL_Release_MT|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|Win32.ActiveCfg = DLL_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|Win32.Build.0 = DLL_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|x64.ActiveCfg = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|x64.Build.0 = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|Win32.ActiveCfg = Lib_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|Win32.Build.0 = Lib_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|x64.ActiveCfg = Lib_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|x64.Build.0 = Lib_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|Win32.ActiveCfg = Lib_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|Win32.Build.0 = Lib_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|x64.ActiveCfg = Lib_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|x64.Build.0 = Lib_Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|Win32.ActiveCfg = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|Win32.Build.0 = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|x64.ActiveCfg = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|x64.Build.0 = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|Win32.ActiveCfg = Release_MT|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|Win32.Build.0 = Release_MT|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|x64.ActiveCfg = Release_MT|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|x64.Build.0 = Release_MT|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|Win32.ActiveCfg = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|Win32.Build.0 = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|x64.ActiveCfg = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|x64.Build.0 = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|Win32.ActiveCfg = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|Win32.Build.0 = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|x64.ActiveCfg = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|x64.Build.0 = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|Win32.ActiveCfg = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|Win32.Build.0 = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|x64.ActiveCfg = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj new file mode 100644 index 0000000..85cfdab --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj @@ -0,0 +1,568 @@ + + + + + DLL_Debug + Win32 + + + DLL_Debug + x64 + + + DLL_Release + Win32 + + + DLL_Release + x64 + + + Lib_Debug + Win32 + + + Lib_Debug + x64 + + + Lib_Release + Win32 + + + Lib_Release + x64 + + + DLL_Release_MT + Win32 + + + DLL_Release_MT + x64 + + + + {9B729252-7D58-4B28-882F-DFB4EF44A485} + true + Win32Proj + AMD_TressFX_Vulkan + AMD_TressFX_Vulkan + + + + DynamicLibrary + true + Unicode + v120 + + + DynamicLibrary + true + Unicode + v120 + + + DynamicLibrary + false + Unicode + v120 + + + DynamicLibrary + false + Unicode + v120 + + + StaticLibrary + true + Unicode + v120 + + + StaticLibrary + true + Unicode + v120 + + + StaticLibrary + false + Unicode + v120 + + + StaticLibrary + false + Unicode + v120 + + + DynamicLibrary + false + Unicode + v120 + + + DynamicLibrary + false + Unicode + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ..\lib\VS2013\Win32\DLL_Debug\ + VS2013\Win32\DLL_Debug\ + GPUOpen_TressFX_x86d + .dll + + + true + ..\lib\VS2013\x64\DLL_Debug\ + VS2013\x64\DLL_Debug\ + GPUOpen_TressFX_x64d + .dll + + + false + ..\lib\VS2013\Win32\DLL_Release\ + VS2013\Win32\DLL_Release\ + GPUOpen_TressFX_x86 + .dll + + + false + ..\lib\VS2013\x64\DLL_Release\ + VS2013\x64\DLL_Release\ + GPUOpen_TressFX_x64 + .dll + + + ..\lib\VS2013\Win32\Lib_Debug\ + VS2013\Win32\Lib_Debug\ + GPUOpen_TressFX_x86d + .lib + + + ..\lib\VS2013\x64\Lib_Debug\ + VS2013\x64\Lib_Debug\ + GPUOpen_TressFX_x64d + .lib + + + ..\lib\VS2013\Win32\Lib_Release\ + VS2013\Win32\Lib_Release\ + GPUOpen_TressFX_x86 + .lib + + + ..\lib\VS2013\x64\Lib_Release\ + VS2013\x64\Lib_Release\ + GPUOpen_TressFX_x64 + .lib + + + false + ..\lib\VS2013\Win32\DLL_Release_MT\ + VS2013\Win32\DLL_Release_MT\ + GPUOpen_TressFX_x86 + .dll + + + false + ..\lib\VS2013\x64\DLL_Release_MT\ + VS2013\x64\DLL_Release_MT\ + GPUOpen_TressFX_x64 + .dll + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2013\Win32\DLL_Debug\GPUOpen_TressFX_x86d.lib + true + + + copy /b "..\lib\VS2013\Win32\DLL_Debug\$(TargetName).lib" +,, "..\lib\VS2013\Win32\DLL_Debug\" > nul +xcopy "..\lib\VS2013\Win32\DLL_Debug\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2013\Win32\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + ProgramDatabase + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2013\x64\DLL_Debug\GPUOpen_TressFX_x64d.lib + true + + + copy /b "..\lib\VS2013\x64\DLL_Debug\$(TargetName).lib" +,, "..\lib\VS2013\x64\DLL_Debug\" > nul +xcopy "..\lib\VS2013\x64\DLL_Debug\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2013\x64\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2013\Win32\DLL_Release\GPUOpen_TressFX_x86.lib + true + + + copy /b "..\lib\VS2013\Win32\DLL_Release\$(TargetName).lib" +,, "..\lib\VS2013\Win32\DLL_Release\" > nul +xcopy "..\lib\VS2013\Win32\DLL_Release\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2013\Win32\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2013\x64\DLL_Release\GPUOpen_TressFX_x64.lib + true + + + copy /b "..\lib\VS2013\x64\DLL_Release\$(TargetName).lib" +,, "..\lib\VS2013\x64\DLL_Release\" > nul +xcopy "..\lib\VS2013\x64\DLL_Release\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2013\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + ProgramDatabase + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + MultiThreaded + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2013\Win32\DLL_Release_MT\GPUOpen_TressFX_x86.lib + true + + + copy /b "..\lib\VS2013\Win32\DLL_Release_MT\$(TargetName).lib" +,, "..\lib\VS2013\Win32\DLL_Release_MT\" > nul +xcopy "..\lib\VS2013\Win32\DLL_Release_MT\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2013\Win32\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + MultiThreaded + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2013\x64\DLL_Release_MT\GPUOpen_TressFX_x64.lib + true + + + copy /b "..\lib\VS2013\x64\DLL_Release_MT\$(TargetName).lib" +,, "..\lib\VS2013\x64\DLL_Release_MT\" > nul +xcopy "..\lib\VS2013\x64\DLL_Release_MT\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2013\x64\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44} + + + + + + \ No newline at end of file diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj.filters b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj.filters new file mode 100644 index 0000000..9682ca1 --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj.filters @@ -0,0 +1,167 @@ + + + + + {E5B4C84B-516A-4141-DA5E-3B1846133845} + + + {7C5D4EB9-E8E8-BB7D-F1F9-3E725D04187E} + + + {D58F8ECE-C11E-1898-6A3D-2C9356AB283E} + + + {2DAB880B-99B4-887C-2230-9F7C8E38947C} + + + {06ADC7FB-7262-40F1-FB56-3AC8670B37F5} + + + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src + + + amd_tressfx\src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + \ No newline at end of file diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.sln b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.sln new file mode 100644 index 0000000..7db7b73 --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.sln @@ -0,0 +1,66 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_TressFX_Vulkan", "AMD_TressFX_Vulkan_2015.vcxproj", "{9B729252-7D58-4B28-882F-DFB4EF44A485}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_LIB_Minimal", "..\..\amd_lib\shared\d3d11\build\AMD_LIB_Minimal_2015.vcxproj", "{0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DLL_Debug|Win32 = DLL_Debug|Win32 + DLL_Debug|x64 = DLL_Debug|x64 + DLL_Release_MT|Win32 = DLL_Release_MT|Win32 + DLL_Release_MT|x64 = DLL_Release_MT|x64 + DLL_Release|Win32 = DLL_Release|Win32 + DLL_Release|x64 = DLL_Release|x64 + Lib_Debug|Win32 = Lib_Debug|Win32 + Lib_Debug|x64 = Lib_Debug|x64 + Lib_Release|Win32 = Lib_Release|Win32 + Lib_Release|x64 = Lib_Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|Win32.ActiveCfg = DLL_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|Win32.Build.0 = DLL_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|x64.ActiveCfg = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Debug|x64.Build.0 = DLL_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|Win32.ActiveCfg = DLL_Release_MT|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|Win32.Build.0 = DLL_Release_MT|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|x64.ActiveCfg = DLL_Release_MT|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release_MT|x64.Build.0 = DLL_Release_MT|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|Win32.ActiveCfg = DLL_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|Win32.Build.0 = DLL_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|x64.ActiveCfg = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.DLL_Release|x64.Build.0 = DLL_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|Win32.ActiveCfg = Lib_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|Win32.Build.0 = Lib_Debug|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|x64.ActiveCfg = Lib_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Debug|x64.Build.0 = Lib_Debug|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|Win32.ActiveCfg = Lib_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|Win32.Build.0 = Lib_Release|Win32 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|x64.ActiveCfg = Lib_Release|x64 + {9B729252-7D58-4B28-882F-DFB4EF44A485}.Lib_Release|x64.Build.0 = Lib_Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|Win32.ActiveCfg = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|Win32.Build.0 = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|x64.ActiveCfg = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Debug|x64.Build.0 = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|Win32.ActiveCfg = Release_MT|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|Win32.Build.0 = Release_MT|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|x64.ActiveCfg = Release_MT|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release_MT|x64.Build.0 = Release_MT|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|Win32.ActiveCfg = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|Win32.Build.0 = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|x64.ActiveCfg = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.DLL_Release|x64.Build.0 = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|Win32.ActiveCfg = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|Win32.Build.0 = Debug|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|x64.ActiveCfg = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Debug|x64.Build.0 = Debug|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|Win32.ActiveCfg = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|Win32.Build.0 = Release|Win32 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|x64.ActiveCfg = Release|x64 + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44}.Lib_Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj new file mode 100644 index 0000000..60a35dc --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj @@ -0,0 +1,559 @@ + + + + + DLL_Debug + Win32 + + + DLL_Debug + x64 + + + DLL_Release + Win32 + + + DLL_Release + x64 + + + Lib_Debug + Win32 + + + Lib_Debug + x64 + + + Lib_Release + Win32 + + + Lib_Release + x64 + + + DLL_Release_MT + Win32 + + + DLL_Release_MT + x64 + + + + {9B729252-7D58-4B28-882F-DFB4EF44A485} + true + Win32Proj + AMD_TressFX_Vulkan + AMD_TressFX_Vulkan + 8.1 + + + + DynamicLibrary + true + Unicode + v140 + + + DynamicLibrary + true + Unicode + v140 + + + DynamicLibrary + false + Unicode + v140 + + + DynamicLibrary + false + Unicode + v140 + + + StaticLibrary + true + Unicode + v140 + + + StaticLibrary + true + Unicode + v140 + + + StaticLibrary + false + Unicode + v140 + + + StaticLibrary + false + Unicode + v140 + + + DynamicLibrary + false + Unicode + v140 + + + DynamicLibrary + false + Unicode + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + ..\lib\VS2015\Win32\DLL_Debug\ + VS2015\Win32\DLL_Debug\ + GPUOpen_TressFX_x86d + .dll + + + true + ..\lib\VS2015\x64\DLL_Debug\ + VS2015\x64\DLL_Debug\ + GPUOpen_TressFX_x64d + .dll + + + false + ..\lib\VS2015\Win32\DLL_Release\ + VS2015\Win32\DLL_Release\ + GPUOpen_TressFX_x86 + .dll + + + false + ..\lib\VS2015\x64\DLL_Release\ + VS2015\x64\DLL_Release\ + GPUOpen_TressFX_x64 + .dll + + + ..\lib\VS2015\Win32\Lib_Debug\ + VS2015\Win32\Lib_Debug\ + GPUOpen_TressFX_x86d + .lib + + + ..\lib\VS2015\x64\Lib_Debug\ + VS2015\x64\Lib_Debug\ + GPUOpen_TressFX_x64d + .lib + + + ..\lib\VS2015\Win32\Lib_Release\ + VS2015\Win32\Lib_Release\ + GPUOpen_TressFX_x86 + .lib + + + ..\lib\VS2015\x64\Lib_Release\ + VS2015\x64\Lib_Release\ + GPUOpen_TressFX_x64 + .lib + + + false + ..\lib\VS2015\Win32\DLL_Release_MT\ + VS2015\Win32\DLL_Release_MT\ + GPUOpen_TressFX_x86 + .dll + + + false + ..\lib\VS2015\x64\DLL_Release_MT\ + VS2015\x64\DLL_Release_MT\ + GPUOpen_TressFX_x64 + .dll + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2015\Win32\DLL_Debug\GPUOpen_TressFX_x86d.lib + true + + + copy /b "..\lib\VS2015\Win32\DLL_Debug\$(TargetName).lib" +,, "..\lib\VS2015\Win32\DLL_Debug\" > nul +xcopy "..\lib\VS2015\Win32\DLL_Debug\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2015\Win32\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + ProgramDatabase + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2015\x64\DLL_Debug\GPUOpen_TressFX_x64d.lib + true + + + copy /b "..\lib\VS2015\x64\DLL_Debug\$(TargetName).lib" +,, "..\lib\VS2015\x64\DLL_Debug\" > nul +xcopy "..\lib\VS2015\x64\DLL_Debug\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2015\x64\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2015\Win32\DLL_Release\GPUOpen_TressFX_x86.lib + true + + + copy /b "..\lib\VS2015\Win32\DLL_Release\$(TargetName).lib" +,, "..\lib\VS2015\Win32\DLL_Release\" > nul +xcopy "..\lib\VS2015\Win32\DLL_Release\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2015\Win32\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2015\x64\DLL_Release\GPUOpen_TressFX_x64.lib + true + + + copy /b "..\lib\VS2015\x64\DLL_Release\$(TargetName).lib" +,, "..\lib\VS2015\x64\DLL_Release\" > nul +xcopy "..\lib\VS2015\x64\DLL_Release\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2015\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + EditAndContinue + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + ProgramDatabase + Disabled + false + false + /EHsc %(AdditionalOptions) + + + Windows + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + + + true + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + MultiThreaded + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2015\Win32\DLL_Release_MT\GPUOpen_TressFX_x86.lib + true + + + copy /b "..\lib\VS2015\Win32\DLL_Release_MT\$(TargetName).lib" +,, "..\lib\VS2015\Win32\DLL_Release_MT\" > nul +xcopy "..\lib\VS2015\Win32\DLL_Release_MT\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2015\Win32\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + NotUsing + Level4 + true + VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) + Full + true + true + false + true + MultiThreaded + false + false + /EHsc %(AdditionalOptions) + + + Windows + false + true + true + vulkan-1.lib;%(AdditionalDependencies) + $(VULKAN_SDK)\Bin;%(AdditionalLibraryDirectories) + ..\lib\VS2015\x64\DLL_Release_MT\GPUOpen_TressFX_x64.lib + true + + + copy /b "..\lib\VS2015\x64\DLL_Release_MT\$(TargetName).lib" +,, "..\lib\VS2015\x64\DLL_Release_MT\" > nul +xcopy "..\lib\VS2015\x64\DLL_Release_MT\$(TargetName).dll" "..\lib" /H /R /Y > nul +xcopy "..\lib\VS2015\x64\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y > nul + Copying build output to lib directory... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {0D2AEA47-7909-69E3-8221-F4B9EE7FCF44} + + + + + + \ No newline at end of file diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj.filters b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj.filters new file mode 100644 index 0000000..9682ca1 --- /dev/null +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj.filters @@ -0,0 +1,167 @@ + + + + + {E5B4C84B-516A-4141-DA5E-3B1846133845} + + + {7C5D4EB9-E8E8-BB7D-F1F9-3E725D04187E} + + + {D58F8ECE-C11E-1898-6A3D-2C9356AB283E} + + + {2DAB880B-99B4-887C-2230-9F7C8E38947C} + + + {06ADC7FB-7262-40F1-FB56-3AC8670B37F5} + + + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + src\Shaders + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src\Math + + + amd_tressfx\src + + + amd_tressfx\src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + \ No newline at end of file diff --git a/amd_tressfx_vulkan/premake/premake5.lua b/amd_tressfx_vulkan/premake/premake5.lua new file mode 100644 index 0000000..3797848 --- /dev/null +++ b/amd_tressfx_vulkan/premake/premake5.lua @@ -0,0 +1,94 @@ +_AMD_LIBRARY_NAME = "TressFX" +_AMD_LIBRARY_NAME_ALL_CAPS = string.upper(_AMD_LIBRARY_NAME) + +-- Set _AMD_LIBRARY_NAME before including amd_premake_util.lua +dofile ("../../premake/amd_premake_util.lua") + +workspace ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan") + configurations { "DLL_Debug", "DLL_Release", "Lib_Debug", "Lib_Release", "DLL_Release_MT" } + platforms { "Win32", "x64" } + location "../build" + filename ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan" .. _AMD_VS_SUFFIX) + startproject ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan") + + filter "platforms:Win32" + system "Windows" + architecture "x86" + + filter "platforms:x64" + system "Windows" + architecture "x64" + +externalproject "AMD_LIB_Minimal" + kind "StaticLib" + language "C++" + location "../../amd_lib/shared/d3d11/build" + filename ("AMD_LIB_Minimal" .. _AMD_VS_SUFFIX) + uuid "0D2AEA47-7909-69E3-8221-F4B9EE7FCF44" + configmap { + ["DLL_Debug"] = "Debug", + ["DLL_Release"] = "Release", + ["Lib_Debug"] = "Debug", + ["Lib_Release"] = "Release", + ["DLL_Release_MT"] = "Release_MT" } + +project ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan") + language "C++" + location "../build" + filename ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan".. _AMD_VS_SUFFIX) + uuid "9B729252-7D58-4B28-882F-DFB4EF44A485" + targetdir "../lib/%{_AMD_LIBRARY_DIR_LAYOUT}" + objdir "../build/%{_AMD_LIBRARY_DIR_LAYOUT}" + warnings "Extra" + exceptionhandling "Off" + rtti "Off" + + -- Specify WindowsTargetPlatformVersion here for VS2015 + windowstarget (_AMD_WIN_SDK_VERSION) + defines { "VULKAN"} + files { "../inc/**.h", "../src/**.h", "../src/**.cpp", "../src/Shaders/**.glsl", "../src/Shaders/**.comp", "../src/Shaders/**.vert", "../src/Shaders/**.frag", "../../amd_tressfx/src/TressFXAsset.cpp", "../../amd_tressfx/src/Util.cpp", "../../amd_tressfx/src/Math/**.cpp" } + includedirs { "../inc", "../../amd_lib/shared/common/inc", "../../amd_tressfx/inc", "../../amd_tressfx/src", "$(VULKAN_SDK)/Include" } + libdirs { "$(VULKAN_SDK)/Bin"} + links { "AMD_LIB_Minimal", "vulkan-1" } + + filter "configurations:DLL_*" + kind "SharedLib" + defines { "_USRDLL", "AMD_%{_AMD_LIBRARY_NAME_ALL_CAPS}_COMPILE_DYNAMIC_LIB=1" } + -- Copy DLL and import library to the lib directory + postbuildcommands { amdLibPostbuildCommands() } + postbuildmessage "Copying build output to lib directory..." + + filter "configurations:Lib_*" + kind "StaticLib" + defines { "_LIB", "AMD_%{_AMD_LIBRARY_NAME_ALL_CAPS}_COMPILE_DYNAMIC_LIB=0" } + + filter "configurations:*_Debug" + defines { "WIN32", "_DEBUG", "_WINDOWS", "_WIN32_WINNT=0x0601", "_SCL_SECURE_NO_WARNINGS" } + flags { "Symbols", "FatalWarnings", "Unicode" } + -- add "d" to the end of the library name for debug builds + targetsuffix "d" + + filter "configurations:*_Release" + defines { "WIN32", "NDEBUG", "_WINDOWS", "_WIN32_WINNT=0x0601", "_SCL_SECURE_NO_WARNINGS" } + flags { "FatalWarnings", "Unicode" } + optimize "On" + + filter "configurations:DLL_Release_MT" + defines { "WIN32", "NDEBUG", "_WINDOWS", "_WIN32_WINNT=0x0601", "_SCL_SECURE_NO_WARNINGS" } + flags { "FatalWarnings", "Unicode" } + -- link against the static runtime to avoid introducing a dependency + -- on the particular version of Visual Studio used to build the DLLs + flags { "StaticRuntime" } + optimize "On" + + filter "action:vs*" + -- specify exception handling model for Visual Studio to avoid + -- "'noexcept' used with no exception handling mode specified" + -- warning in vs2015 + buildoptions { "/EHsc" } + + filter "platforms:Win32" + targetname "%{_AMD_LIBRARY_PREFIX}%{_AMD_LIBRARY_NAME}_x86" + + filter "platforms:x64" + targetname "%{_AMD_LIBRARY_PREFIX}%{_AMD_LIBRARY_NAME}_x64" diff --git a/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py b/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py new file mode 100644 index 0000000..1f70c86 --- /dev/null +++ b/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py @@ -0,0 +1,67 @@ +import os; +import array; +import re; + +def get_file_content(filename): + src_file = open("..\..\src\Shaders\\" + filename, 'r') + return src_file.read() + +def load_array(name, filename): + src_file = open("..\..\src\Shaders\\" + filename) + if filename.endswith('.vert'): + temporary_file = open('temp.vert', 'w') + elif filename.endswith('.frag'): + temporary_file = open('temp.frag', 'w') + else: + temporary_file = open('temp.comp', 'w') + line = src_file.readline() + while line != '': + m = re.search(r'^#include "(.*)"', line) + if m: + temporary_file.write(get_file_content(m.group(1))) + else: + temporary_file.write(line) + line = src_file.readline() + temporary_file.close() + if filename.endswith('.vert'): + os.system("glslangValidator.exe -V temp.vert") + f = open("vert.spv", 'rb') + filesize = os.path.getsize("vert.spv") + elif filename.endswith('.frag'): + os.system("glslangValidator.exe -V temp.frag") + f = open("frag.spv", 'rb') + filesize = os.path.getsize("frag.spv") + else: + os.system("glslangValidator.exe -V temp.comp") + f = open("comp.spv", 'rb') + filesize = os.path.getsize("comp.spv") + a = array.array('L') + a.fromfile(f, filesize // 4) + f.close() + code = "const std::vector " + name +" = {" + for i in a: + code += str(i) + ",\n" + code += "};\n" + return code + +output = open("..\..\src\TressFXPrecompiledShadersVulkan.h", 'w') +output.write("#include \n") +output.write(load_array("hair_shadow_vertex", "HairShadowMap.vert")) +output.write(load_array("hair_shadow_fragment", "HairShadowMap.frag")) +output.write(load_array("render_hair_vertex", "RenderHair.vert")) +output.write(load_array("render_hair_aa_vertex", "RenderHairAA.vert")) +output.write(load_array("render_hair_strand_copies_vertex", "RenderHairStrandCopies.vert")) +output.write(load_array("render_hair_aa_strand_copies_vertex", "RenderHairAAStrandCopies.vert")) +output.write(load_array("pass1_fragment", "TressFXRender.frag")) +output.write(load_array("pass2_vertex", "TressFXRender_pass2.vert")) +output.write(load_array("pass2_fragment", "TressFXRender_pass2.frag")) +output.write(load_array("global_constraints", "GlobalConstraints.comp")) +output.write(load_array("local_constraints", "LocalConstraints.comp")) +output.write(load_array("length_wind_tangent_compute", "LengthWindTangentComputation.comp")) +output.write(load_array("prepare_follow_hair", "PrepareFollowHair.comp")) +output.write(load_array("update_follow_hair", "UpdateFollowHair.comp")) +output.write(load_array("depth_hair_data", "FS_Depth_Hair_Data.frag")) +output.write(load_array("resolve_depth", "FS_ResolveDepth_Hair_Data.frag")) +output.write(load_array("fillcolors_hair_data", "FS_FillColors_Hair_Data.frag")) +output.write(load_array("resolvecolors", "FS_ResolveColor_Hair_Data.frag")) +output.close() diff --git a/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.pyproj b/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.pyproj new file mode 100644 index 0000000..2888265 --- /dev/null +++ b/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.pyproj @@ -0,0 +1,41 @@ + + + + Debug + 2.0 + 5cb29e1d-e89d-42ae-9c2d-dbc0a988c843 + . + shader_builder.py + + + . + . + shader_builder + shader_builder + + + true + false + + + true + false + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets + + + + + + + + + + \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/ComputeCoverage.glsl b/amd_tressfx_vulkan/src/Shaders/ComputeCoverage.glsl new file mode 100644 index 0000000..175fa61 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/ComputeCoverage.glsl @@ -0,0 +1,33 @@ +//-------------------------------------------------------------------------------------- +// ComputeCoverage +// +// Calculate the pixel coverage of a hair strand by computing the hair width +//-------------------------------------------------------------------------------------- +float ComputeCoverage(vec2 p0, vec2 p1, vec2 pixelLoc) +{ + // p0, p1, pixelLoc are in d3d clip space (-1 to 1)x(-1 to 1) + + // Scale positions so 1.f = half pixel width + p0 *= g_WinSize.xy; + p1 *= g_WinSize.xy; + pixelLoc.y *= -1; + pixelLoc *= g_WinSize.xy; + + float p0dist = length(p0 - pixelLoc); + float p1dist = length(p1 - pixelLoc); + float hairWidth = length(p0 - p1); + + // will be 1.f if pixel outside hair, 0.f if pixel inside hair + bool outside = any(bvec2(step(hairWidth, p0dist) > 0., step(hairWidth, p1dist) > 0.)); + + // if outside, set sign to -1, else set sign to 1 + float sign = outside ? -1.f : 1.f; + + // signed distance (positive if inside hair, negative if outside hair) + float relDist = sign * clamp(min(p0dist, p1dist), 0., 1.); + + // returns coverage based on the relative distance + // 0, if completely outside hair edge + // 1, if completely inside hair edge + return (relDist + 1.f) * 0.5f; +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/ComputeHairShading.glsl b/amd_tressfx_vulkan/src/Shaders/ComputeHairShading.glsl new file mode 100644 index 0000000..5ab3121 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/ComputeHairShading.glsl @@ -0,0 +1,83 @@ + +vec3 ComputeHairShading(vec3 iPos, vec3 iTangent, vec4 iTex, float amountLight, vec3 color) +{ + vec3 baseColor = g_MatBaseColor.xyz; + float rand_value = 1; + + // if(abs(iTex.x) + abs(iTex.y) >1e-5) // if texcoord is available, use texture map + // rand_value = g_txNoise.SampleLevel(g_samLinearWrap, iTex.xy, 0).x; + + // define baseColor and Ka Kd Ks coefficient for hair + float Ka = g_MatKValue.x, Kd = g_MatKValue.y, + Ks1 = g_MatKValue.z, Ex1 = g_MatKValue.w, + Ks2 = g_fHairKs2, Ex2 = g_fHairEx2; + + vec3 lightPos = g_PointLightPos.xyz; + vec3 vLightDir = normalize(lightPos - iPos.xyz); + vec3 vEyeDir = normalize(g_vEye.xyz - iPos.xyz); + vec3 tangent = normalize(iTangent); + + // in Kajiya's model: diffuse component: sin(t, l) + float cosTL = (dot(tangent, vLightDir)); + float sinTL = sqrt(1 - cosTL*cosTL); + float diffuse = sinTL; // here sinTL is apparently larger than 0 + + float alpha = (rand_value * 10) * PI / 180; // tiled angle (5-10 dgree) + + // in Kajiya's model: specular component: cos(t, rl) * cos(t, e) + sin(t, rl)sin(t, e) + float cosTRL = -cosTL; + float sinTRL = sinTL; + float cosTE = (dot(tangent, vEyeDir)); + float sinTE = sqrt(1 - cosTE*cosTE); + + // primary highlight: reflected direction shift towards root (2 * Alpha) + float cosTRL_root = cosTRL * cos(2 * alpha) - sinTRL * sin(2 * alpha); + float sinTRL_root = sqrt(1 - cosTRL_root * cosTRL_root); + float specular_root = max(0., cosTRL_root * cosTE + sinTRL_root * sinTE); + + // secondary highlight: reflected direction shifted toward tip (3*Alpha) + float cosTRL_tip = cosTRL*cos(-3 * alpha) - sinTRL*sin(-3 * alpha); + float sinTRL_tip = sqrt(1 - cosTRL_tip * cosTRL_tip); + float specular_tip = max(0., cosTRL_tip * cosTE + sinTRL_tip * sinTE); + + vec3 vColor = Ka * g_AmbientLightColor.xyz * baseColor + // ambient + amountLight * g_PointLightColor.xyz * ( + Kd * diffuse * baseColor + // diffuse + Ks1 * pow(specular_root, Ex1) + // primary hightlight r + Ks2 * pow(specular_tip, Ex2) * baseColor); // secondary highlight rtr + + return vColor * amountLight; +} + +#define SUPERSIMPLESHADING + +vec3 SimpleHairShading(vec3 iPos, vec3 iTangent, vec4 iTex, float amountLight) +{ + vec3 baseColor = g_MatBaseColor.xyz; + float Kd = g_MatKValue.y; + +#ifdef SUPERSIMPLESHADING + vec3 vColor = amountLight * Kd * baseColor; +#else + // define baseColor and Ka Kd Ks coefficient for hair + float Ka = g_MatKValue.x; + float Ks1 = g_MatKValue.z; + float Ex1 = g_MatKValue.w; + float Ks2 = g_fHairKs2; + float Ex2 = g_fHairEx2; + + vec3 lightPos = g_PointLightPos.xyz; + vec3 vLightDir = normalize(lightPos - iPos.xyz); + vec3 tangent = normalize(iTangent); + + // in Kajiya's model: diffuse component: sin(t, l) + float cosTL = (dot(tangent, vLightDir)); + float sinTL = sqrt(1 - cosTL*cosTL); + float diffuse = sinTL; // here sinTL is apparently larger than 0 + + vec3 vColor = Ka * g_AmbientLightColor.xyz * baseColor + // ambient + amountLight * g_PointLightColor.xyz * (Kd * diffuse * baseColor); // diffuse +#endif + return vColor * amountLight; +} + diff --git a/amd_tressfx_vulkan/src/Shaders/ComputeShadow.glsl b/amd_tressfx_vulkan/src/Shaders/ComputeShadow.glsl new file mode 100644 index 0000000..9597f91 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/ComputeShadow.glsl @@ -0,0 +1,93 @@ +layout(set = 0, binding = IDSRV_HAIRSM) uniform texture2D HairShadowMap; +layout(set = 0, binding = IDSRV_SHADOW_SAMPLER) uniform sampler g_samPointClamp; + +//-------------------------------------------------------------------------------------- +// ComputeShadow +// +// Computes the shadow using a simplified deep shadow map technique for the hair and +// PCF for scene objects. It uses multiple taps to filter over a (KERNEL_SIZE x KERNEL_SIZE) +// kernel for high quality results. +//-------------------------------------------------------------------------------------- +float ComputeShadow(vec3 worldPos, float alpha) +{ + vec4 projPosLight = g_mViewProjLight * vec4(worldPos, 1); + projPosLight.xy /= projPosLight.w; + vec2 texSM = .5 * projPosLight.xy + .5; + texSM.y = 1. - texSM.y; + float depth = projPosLight.z / projPosLight.w; + float epsilon = depth * SM_EPSILON; + float depth_fragment = projPosLight.w; + + // for shadow casted by scene objs, use PCF shadow + float total_weight = 0; + float amountLight_hair = 0; + + total_weight = 0; + for (int dx = (1 - KERNEL_SIZE) / 2; dx <= KERNEL_SIZE / 2; dx++) + { + for (int dy = (1 - KERNEL_SIZE) / 2; dy <= KERNEL_SIZE / 2; dy++) + { + float size = 2.4; + float sigma = (KERNEL_SIZE / 2.0) / size; // standard deviation, when kernel/2 > 3*sigma, it's close to zero, here we use 1.5 instead + float exp = -1 * (dx * dx + dy * dy) / (2 * sigma * sigma); + float weight = 1 / (2 * PI * sigma * sigma) * pow(2.7, exp); + + // shadow casted by hair: simplified deep shadow map + float depthSMHair = 2. * texture(sampler2D(HairShadowMap, g_samPointClamp), texSM + vec2(dx, dy) / 640.).x - 1.; //z/w + + float depth_smPoint = g_fNearLight / (1 - depthSMHair * (g_fFarLight - g_fNearLight) / g_fFarLight); + + float depth_range = max(0., depth_fragment - depth_smPoint); + float numFibers = depth_range / (g_FiberSpacing * g_FiberRadius); + + // if occluded by hair, there is at least one fiber + numFibers += (depth_range > .00001) ? 1. : 0.; + amountLight_hair += pow(abs(1 - alpha), numFibers) * weight; + + total_weight += weight; + } + } + amountLight_hair /= total_weight; + + float amountLight_scene = 1.;//g_txSMScene.SampleCmpLevelZero(g_samShadow, texSM, depth-epsilon); + + return (amountLight_hair * amountLight_scene); +} + + +//-------------------------------------------------------------------------------------- +// ComputeSimpleShadow +// +// Computes the shadow using a simplified deep shadow map technique for the hair and +// PCF for scene objects. This function only uses one sample, so it is faster but +// not as good quality as ComputeShadow +//-------------------------------------------------------------------------------------- +float ComputeSimpleShadow(vec3 worldPos, float alpha) +{ + vec4 projPosLight = g_mViewProjLight * vec4(worldPos, 1); + projPosLight.xy /= projPosLight.w; + + vec2 texSM = .5 * projPosLight.xy + .5; + texSM.y = 1. - texSM.y; + float depth = projPosLight.z / projPosLight.w; + float epsilon = depth * SM_EPSILON; + float depth_fragment = projPosLight.w; + + // shadow casted by scene + float amountLight_scene = 1.;//g_txSMScene.SampleCmpLevelZero(g_samShadow, texSM, depth-epsilon); // TODO + + // shadow casted by hair: simplified deep shadow map + float depthSMHair = 2. * texture(sampler2D(HairShadowMap, g_samPointClamp), texSM).x - 1.; //z/w + + float depth_smPoint = g_fNearLight / (1. - depthSMHair * (g_fFarLight - g_fNearLight) / g_fFarLight); + + float depth_range = max(0., depth_fragment - depth_smPoint); + + float numFibers = depth_range / (g_FiberSpacing * g_FiberRadius); + + // if occluded by hair, there is at least one fiber + numFibers += (depth_range > .00001) ? 1. : 0.; + float amountLight_hair = pow(abs(1 - alpha), numFibers); + + return amountLight_hair; +} diff --git a/amd_tressfx_vulkan/src/Shaders/ComputeTangents.comp b/amd_tressfx_vulkan/src/Shaders/ComputeTangents.comp new file mode 100644 index 0000000..1e6c697 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/ComputeTangents.comp @@ -0,0 +1,44 @@ +#version 450 + +#include "SimulationConfig.glsl" + +layout(local_size_x = THREAD_GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; +layout(set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) uniform usamplerBuffer g_HairVertexPositions; +layout(std430, set = 1, binding = IDSRV_HAIR_TANGENTS) buffer writeablePositions +{ + vec4 g_HairVertexTangents[]; +}; + +#include "IndicesComputations.glsl" + +shared vec4 sharedPos[THREAD_GROUP_SIZE]; + +void main() +{ + uint globalStrandIndex, localStrandIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType; + int globalVertexIndex; + CalcIndicesInVertexLevelTotal(gl_LocalInvocationID.x, gl_WorkGroupID.x, globalStrandIndex, localStrandIndex, globalVertexIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType); + + sharedPos[indexForSharedMem] = texelFetch(g_HairVertexPositions, globalVertexIndex); + barrier(); + + uint numOfStrandsPerThreadGroup = g_NumOfStrandsPerThreadGroup; + + if (localVertexIndex == 0) // vertex 0 + { + vec3 tangent = sharedPos[indexForSharedMem + numOfStrandsPerThreadGroup].xyz - sharedPos[indexForSharedMem].xyz; + g_HairVertexTangents[globalVertexIndex].xyz = normalize(tangent); + } + else // vertex 1 through n-1 + { + vec3 vert_i_minus_1 = sharedPos[indexForSharedMem - numOfStrandsPerThreadGroup].xyz; + vec3 vert_i = sharedPos[indexForSharedMem].xyz; + g_HairVertexTangents[globalVertexIndex].xyz = normalize(vert_i - vert_i_minus_1); + } + +/* if ( localVertexIndex < numVerticesInTheStrand - 1 ) + { + vec3 tangent = sharedPos[indexForSharedMem + numOfStrandsPerThreadGroup].xyz - sharedPos[indexForSharedMem].xyz; + g_HairVertexTangents[globalVertexIndex].xyz = normalize(tangent); + }*/ +} diff --git a/amd_tressfx_vulkan/src/Shaders/FS_Depth_Hair_Data.frag b/amd_tressfx_vulkan/src/Shaders/FS_Depth_Hair_Data.frag new file mode 100644 index 0000000..918c9c0 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/FS_Depth_Hair_Data.frag @@ -0,0 +1,78 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" +#include "PackUnpack.glsl" +#include "ComputeCoverage.glsl" + +layout(set = 0, binding = IDSRV_HAIR_FRAGMENT_DEPTHS, r32ui) uniform uimage2DArray RWFragmentDepthsTexture; + +layout(early_fragment_tests) in; + +layout(location = 0) in float depth; +layout(location = 1) in vec4 p0p1; +layout(location = 2) in vec4 tangent; + +layout(location = 0) out float FragColor; + +//-------------------------------------------------------------------------------------- +// PS_Depth_Hair +// +//-------------------------------------------------------------------------------------- +void main() +{ + // Render AA Line, calculate pixel coverage + vec4 proj_pos = vec4(2 * gl_FragCoord.x * g_WinSize.z - 1.0, // g_WinSize.z = 1.0/g_WinSize.x + 1 - 2 * gl_FragCoord.y * g_WinSize.w, // g_WinSize.w = 1.0/g_WinSize.y + gl_FragCoord.z, + 1); + + float curve_scale = 1; + if (g_bThinTip > 0) + curve_scale = tangent.w; + + float fiber_radius = curve_scale * g_FiberRadius; + + float coverage = 1.f; + if (g_bUseCoverage != 0) + { + coverage = ComputeCoverage(p0p1.xy, p0p1.zw, proj_pos.xy); + } + + float alpha = coverage * g_FiberAlpha; + + if (alpha < g_alphaThreshold) + { + FragColor = 1.0; + return; + } + + uvec2 vScreenAddress = uvec2(gl_FragCoord.xy); + + uint uDepth = floatBitsToUint(gl_FragCoord.z); + uint uDepth0Prev, uDepth1Prev; + + // Min of depth 0 and input depth + // Original value is uDepth0Prev + uDepth0Prev = imageAtomicMin(RWFragmentDepthsTexture, ivec3(vScreenAddress, 0), uDepth); + + // Min of depth 1 and greater of the last compare + // If fragment opaque, always use input depth (don't need greater depths) + uDepth = (alpha > 0.98) ? uDepth : max(uDepth, uDepth0Prev); + + uDepth1Prev = imageAtomicMin(RWFragmentDepthsTexture, ivec3(vScreenAddress, 1), uDepth); + +#if SHORTCUT_NUM_DEPTHS == 3 + uint uDepth2Prev; + + // Min of depth 2 and greater of the last compare + // If fragment opaque, always use input depth (don't need greater depths) + uDepth = (alpha > 0.98) ? uDepth : max(uDepth, uDepth1Prev); + + uDepth2Prev = imageAtomicMin(RWFragmentDepthsTexture, ivec3(vScreenAddress, 2), uDepth); +#endif + + FragColor = 1.0 - alpha; +} diff --git a/amd_tressfx_vulkan/src/Shaders/FS_FillColors_Hair_Data.frag b/amd_tressfx_vulkan/src/Shaders/FS_FillColors_Hair_Data.frag new file mode 100644 index 0000000..a8c29df --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/FS_FillColors_Hair_Data.frag @@ -0,0 +1,134 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" +#include "PackUnpack.glsl" +#include "ComputeCoverage.glsl" +#include "ComputeShadow.glsl" +#include "ComputeHairShading.glsl" + +layout(set = 0, binding = IDSRV_HAIR_FRAGMENT_DEPTHS, r32ui) uniform uimage2DArray FragmentDepthsTexture; +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE +#else +layout(set = 0, binding = IDSRV_HAIR_FRAGMENT_COLORS, r32ui) uniform uimageBuffer RWFragmentColors; +#endif + +layout(early_fragment_tests) in; + +// Convert 2D address to 1D address +int GetAddress(ivec2 vAddress) +{ + int nAddress = vAddress.y * int(g_WinSize.x) + vAddress.x; + return nAddress; +} + +layout(location = 0) in float depth; +layout(location = 1) in vec4 p0p1; +layout(location = 2) in vec4 tangent; +layout(location = 3) in vec4 strandColor; + +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE +layout(location = 0) out vec4 FragColor; +#endif + +void main() +{ + // Render AA Line, calculate pixel coverage + vec4 proj_pos = vec4(2 * gl_FragCoord.x * g_WinSize.z - 1.0, // g_WinSize.z = 1.0/g_WinSize.x + 1 - 2 * gl_FragCoord.y * g_WinSize.w, // g_WinSize.w = 1.0/g_WinSize.y + gl_FragCoord.z, + 1); + + vec4 world_pos = g_mInvViewProj * proj_pos; + world_pos.xyz = world_pos.xyz / world_pos.w; + world_pos.w = 1.0; + + float curve_scale = 1; + if (g_bThinTip > 0) + curve_scale = tangent.w; + + float fiber_radius = curve_scale * g_FiberRadius; + + float coverage = 1.f; + if (g_bUseCoverage != 0) + { + coverage = ComputeCoverage(p0p1.xy, p0p1.zw, proj_pos.xy); + } + + float alpha = coverage * g_FiberAlpha; + + if (alpha < g_alphaThreshold) + { +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + FragColor = vec4(0, 0, 0, 0); +#endif + return; + } + + ivec2 vScreenAddress = ivec2(gl_FragCoord.xy); + int fragmentIndex = GetAddress(vScreenAddress); + + uint uDepth = floatBitsToUint(gl_FragCoord.z); + + uint uDepth0 = imageLoad(FragmentDepthsTexture, ivec3(vScreenAddress, 0)).x; + uint uDepth1 = imageLoad(FragmentDepthsTexture, ivec3(vScreenAddress, 1)).x; +#if SHORTCUT_NUM_DEPTHS == 3 + uint uDepth2 = imageLoad(FragmentDepthsTexture, ivec3(vScreenAddress, 2)).x; +#endif + + // Shade regardless of depth, since ResolveDepth pass writes one of the near depths + + float amountLight = ComputeShadow(world_pos.xyz, g_HairShadowAlpha); + vec3 color = ComputeHairShading(world_pos.xyz, tangent.xyz, vec4(0, 0, 0, 0), amountLight, strandColor.xyz); + uint uColor = PackFloat4IntoUint(vec4(color, alpha)); + + +#if SHORTCUT_DETERMINISTIC // deterministic result when fragments match in depth, with added cost + +#if SHORTCUT_WEIGHTED_AVERAGE + FragColor = vec4(color * alpha, alpha); + return; +#else + // For fragments of equal depth, keep colors with greatest uint value + if (uDepth == uDepth0) + { + uint uColorPrev = imageAtomicMax(RWFragmentColors, fragmentIndex, uColor); + uColor = min(uColor, uColorPrev); + } + if (uDepth == uDepth1) + { + uint uColorPrev = imageAtomicMax(RWFragmentColors, fragmentIndex + 1, uColor); + uColor = min(uColor, uColorPrev); + } +#if SHORTCUT_NUM_DEPTHS == 3 + if (uDepth == uDepth2) + { + uint uColorPrev = imageAtomicMax(RWFragmentColors, fragmentIndex + 2, uColor); + uColor = min(uColor, uColorPrev); + } +#endif +#endif + +#else // !SHORTCUT_DETERMINISTIC + + if (uDepth == uDepth0) + { + imageStore(RWFragmentColors, fragmentIndex, uvec4(uColor)); + uColor = 0; + } + if (uDepth == uDepth1) + { + imageStore(RWFragmentColors, fragmentIndex + 1, uvec4(uColor)); + uColor = 0; + } +#if SHORTCUT_NUM_DEPTHS == 3 + if (uDepth == uDepth2) + { + imageStore(RWFragmentColors, fragmentIndex + 2, uvec4(uColor)); + } +#endif + +#endif +} diff --git a/amd_tressfx_vulkan/src/Shaders/FS_ResolveColor_Hair_Data.frag b/amd_tressfx_vulkan/src/Shaders/FS_ResolveColor_Hair_Data.frag new file mode 100644 index 0000000..fe403cf --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/FS_ResolveColor_Hair_Data.frag @@ -0,0 +1,119 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" +#include "PackUnpack.glsl" + +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE +layout(input_attachment_index = 2, set = 0, binding = IDSRV_HAIR_FRAGMENT_COLORS) uniform subpassInput FragmentColors; +#else +layout(set = 0, binding = IDSRV_HAIR_FRAGMENT_DEPTHS, r32ui) uniform uimage2DArray FragmentDepthsTexture; +layout(set = 0, binding = IDSRV_HAIR_FRAGMENT_COLORS, r32ui) uniform uimageBuffer FragmentColors; +#endif + +layout(set = 0, binding = IDSRV_HAIRSM) uniform texture2D HairShadowMap; +layout(set = 0, binding = IDSRV_SHADOW_SAMPLER) uniform sampler g_samPointClamp; + +layout(input_attachment_index = 1, set = 0, binding = IDSRV_HAIR_ACCUM_INV_ALPHA) uniform subpassInput tAccumInvAlpha; + +layout(early_fragment_tests) in; + +layout(location = 0) out vec4 FragColor; + +// Convert 2D address to 1D address +int GetAddress(ivec2 vAddress) +{ + int nAddress = vAddress.y * int(g_WinSize.x) + vAddress.x; + return nAddress; +} + + +//-------------------------------------------------------------------------------------- +// PS_ResolveColor_Hair +// +//-------------------------------------------------------------------------------------- +void main() +{ + ivec2 vScreenAddress = ivec2(gl_FragCoord.xy); + int fragmentIndex = GetAddress(vScreenAddress); + + float fInvAlpha = subpassLoad(tAccumInvAlpha).x; + float fAlpha = 1.0 - fInvAlpha; + + if (fAlpha < SHORTCUT_MIN_ALPHA) + { + FragColor = vec4(0, 0, 0, 1); + return; + } + +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + vec4 fcolor = subpassLoad(FragmentColors); + float colorSumX = fcolor.x; + float colorSumY = fcolor.y; + float colorSumZ = fcolor.z; + float colorSumW = fcolor.w; + fcolor.x = colorSumX / colorSumW; + fcolor.y = colorSumY / colorSumW; + fcolor.z = colorSumZ / colorSumW; + fcolor.xyz *= fAlpha; +#else + uint uDepth0 = imageLoad(FragmentDepthsTexture, ivec3(vScreenAddress, 0)).x; + uint uDepth1 = imageLoad(FragmentDepthsTexture, ivec3(vScreenAddress, 1)).x; + uint uColor0 = imageLoad(FragmentColors, fragmentIndex).x; + uint uColor1 = imageLoad(FragmentColors, fragmentIndex).y; + + vec4 color0 = UnpackUintIntoFloat4(uColor0); + float alpha0 = color0.w; + float invAlpha0 = 1.0 - alpha0; + + vec4 color1 = (uDepth1 == SHORTCUT_INITIAL_DEPTH) ? vec4(0, 0, 0, 0) : UnpackUintIntoFloat4(uColor1); + float alpha1 = color1.w; + float invAlpha1 = 1.0 - alpha1; + +#if SHORTCUT_NUM_DEPTHS == 3 + uint uDepth2 = FragmentDepthsTexture[uint3(vScreenAddress, 2)]; + uint uColor2 = FragmentColors[fragmentIndex].z; + + vec4 color2 = (uDepth2 == SHORTCUT_INITIAL_DEPTH) ? vec4(0, 0, 0, 0) : UnpackUintIntoFloat4(uColor2); + float alpha2 = color2.w; +#endif + + vec4 fcolor; + +#if SHORTCUT_WEIGHTED_AVERAGE +#if SHORTCUT_NUM_DEPTHS == 3 + fcolor.xyz = fAlpha * (color0.xyz * alpha0 + color1.xyz * alpha1 + color2.xyz * alpha2) / (alpha0 + alpha1 + alpha2); +#else + fcolor.xyz = fAlpha * (color0.xyz * alpha0 + color1.xyz * alpha1) / (alpha0 + alpha1); +#endif +#else +#if SHORTCUT_NUM_DEPTHS == 3 + float invAlpha01 = invAlpha0 * invAlpha1; + + // Get cumulative alpha for all fragments after front two; apply to back fragment + float fInvAlphaBack = invAlpha01 < 0.0001 ? fInvAlpha : fInvAlpha / invAlpha01; + float fAlphaBack = 1.0 - fInvAlphaBack; + + vec3 backColor = (uColor2 == 0) ? ((uColor1 == 0) ? color0.xyz : color1.xyz) : color2.xyz; + + // Blend is: + // alpha0 * color0 + (1 - alpha0) * (alpha1 * color1 + (1 - alpha1) * (fAlphaBack * backColor + fInvAlphaBack * dstcolor)) + fcolor.xyz = color0.xyz * alpha0 + color1.xyz * (1 - alpha0) * alpha1 + backColor.xyz * (1 - alpha0) * (1 - alpha1) * fAlphaBack; +#else + // Get cumulative alpha for all fragments after front; apply to back fragment + float fInvAlphaBack = invAlpha0 < 0.0001 ? fInvAlpha : fInvAlpha / invAlpha0; + float fAlphaBack = 1.0 - fInvAlphaBack; + + vec3 backColor = (uColor1 == 0) ? color0.xyz : color1.xyz; + + // Blend is: + // alpha0 * color0 + (1 - alpha0) * (fAlphaBack * backColor + fInvAlphaBack * dstcolor)) + fcolor.xyz = color0.xyz * alpha0 + backColor * (1 - alpha0) * fAlphaBack; +#endif +#endif +#endif + fcolor.w = fInvAlpha; + FragColor = fcolor; +} diff --git a/amd_tressfx_vulkan/src/Shaders/FS_ResolveDepth_Hair_Data.frag b/amd_tressfx_vulkan/src/Shaders/FS_ResolveDepth_Hair_Data.frag new file mode 100644 index 0000000..9635c0b --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/FS_ResolveDepth_Hair_Data.frag @@ -0,0 +1,31 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" + +layout(set = 0, binding = IDSRV_HAIR_FRAGMENT_DEPTHS, r32ui) uniform uimage2DArray FragmentDepthsTexture; + +//-------------------------------------------------------------------------------------- +// PS_ResolveDepth_Hair +// +//-------------------------------------------------------------------------------------- +void main() +{ + ivec2 vScreenAddress = ivec2(gl_FragCoord.xy); + + uint uDepth = 0; + +// NOTE: A bug in FXC in the Win 8.x SDKs prevents +// this shader from compiling if depth is read from a +// structured buffer. A texture array is used instead. + +#if SHORTCUT_NUM_DEPTHS == 3 + uDepth = imageLoad(FragmentDepthsTexture, ivec3(vScreenAddress, 2)).x; +#else + uDepth = imageLoad(FragmentDepthsTexture, ivec3(vScreenAddress, 1)).x; +#endif + + gl_FragDepth = uintBitsToFloat(uDepth); +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/GlobalConstraints.comp b/amd_tressfx_vulkan/src/Shaders/GlobalConstraints.comp new file mode 100644 index 0000000..4416476 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/GlobalConstraints.comp @@ -0,0 +1,143 @@ +#version 450 + +#include "SimulationConfig.glsl" + + +layout (local_size_x = THREAD_GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; + +layout(std430, set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) buffer writeablePositions +{ + vec4 g_HairVertexPositions[]; +}; +layout(std430, set = 1, binding = IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS) buffer writeablePrevPositions +{ + vec4 g_HairVertexPositionsPrev[]; +}; +layout(set = 1, binding = IDSRV_HAIR_VERTEX_INITIAL_POSITIONS) uniform samplerBuffer g_InitialHairPositions; + +#include "IndicesComputations.glsl" + +//-------------------------------------------------------------------------------------- +// +// Integrate +// +// Uses Verlet integration to calculate the new position for the current time step +// +//-------------------------------------------------------------------------------------- +vec4 Integrate(vec4 curPosition, vec4 oldPosition, vec4 initialPos, vec4 force, uint globalVertexIndex, uint localVertexIndex, uint numVerticesInTheStrand, float dampingCoeff) +{ + vec4 outputPos = curPosition; + + force.xyz += g_GravityMagnitude * vec3(0, -1.0f, 0); + outputPos.xyz = curPosition.xyz + (1.0 - dampingCoeff)*(curPosition.xyz - oldPosition.xyz) + force.xyz*g_TimeStep*g_TimeStep; + + return outputPos; +} + +//-------------------------------------------------------------------------------------- +// +// UpdateFinalVertexPositions +// +// Updates the hair vertex positions based on the physics simulation +// +//-------------------------------------------------------------------------------------- +void UpdateFinalVertexPositions(vec4 oldPosition, vec4 newPosition, uint globalVertexIndex, uint localVertexIndex, uint numVerticesInTheStrand) +{ + g_HairVertexPositionsPrev[int(globalVertexIndex)] = oldPosition; + g_HairVertexPositions[int(globalVertexIndex)] = newPosition; +} + +//-------------------------------------------------------------------------------------- +// +// IntegrationAndGlobalShapeConstraints +// +// Compute shader to simulate the gravitational force with integration and to maintain the +// global shape constraints. +// +// One thread computes one vertex. +// +//-------------------------------------------------------------------------------------- +void main() +{ + uint globalStrandIndex, localStrandIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType; + int globalVertexIndex; + CalcIndicesInVertexLevelMaster(gl_LocalInvocationID.x, gl_WorkGroupID.x, globalStrandIndex, localStrandIndex, globalVertexIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType); + + vec4 currentPos = vec4(0, 0, 0, 0); // position when this step starts. In other words, a position from the last step. + vec4 initialPos = vec4(0, 0, 0, 0); // rest position + + vec4 tmpPos; + + // Copy data into shared memory + initialPos = texelFetch(g_InitialHairPositions, globalVertexIndex); + initialPos.xyz = (g_ModelTransformForHead * vec4(initialPos.xyz, 1)).xyz; + if (g_bWarp != 0) + currentPos = initialPos; + else + currentPos = tmpPos = g_HairVertexPositions[globalVertexIndex]; + + // Integrate + float dampingCoeff = 0.03f; + + if ( strandType == 0 ) + dampingCoeff = g_Damping0; + else if ( strandType == 1 ) + dampingCoeff = g_Damping1; + else if ( strandType == 2 ) + dampingCoeff = g_Damping2; + else if ( strandType == 3 ) + dampingCoeff = g_Damping3; + + vec4 oldPos; + if (g_bWarp != 0) + oldPos = currentPos; + else + oldPos = g_HairVertexPositionsPrev[globalVertexIndex]; + vec4 force = vec4(0, 0, 0, 0); + + if ( IsMovable(currentPos) ) + tmpPos = Integrate(currentPos, oldPos, initialPos, force, globalVertexIndex, localVertexIndex, numVerticesInTheStrand, dampingCoeff); + else + tmpPos = initialPos; + + // Global Shape Constraints + float stiffnessForGlobalShapeMatching = 0; + float globalShapeMatchingEffectiveRange = 0; + + if ( strandType == 0 ) + { + stiffnessForGlobalShapeMatching = g_StiffnessForGlobalShapeMatching0; + globalShapeMatchingEffectiveRange = g_GlobalShapeMatchingEffectiveRange0; + } + else if ( strandType == 1 ) + { + stiffnessForGlobalShapeMatching = g_StiffnessForGlobalShapeMatching1; + globalShapeMatchingEffectiveRange = g_GlobalShapeMatchingEffectiveRange1; + } + else if ( strandType == 2 ) + { + stiffnessForGlobalShapeMatching = g_StiffnessForGlobalShapeMatching2; + globalShapeMatchingEffectiveRange = g_GlobalShapeMatchingEffectiveRange2; + } + else if ( strandType == 3 ) + { + stiffnessForGlobalShapeMatching = g_StiffnessForGlobalShapeMatching3; + globalShapeMatchingEffectiveRange = g_GlobalShapeMatchingEffectiveRange3; + } + + if ( stiffnessForGlobalShapeMatching > 0 && globalShapeMatchingEffectiveRange != 0.) + { + if (IsMovable(tmpPos)) + { + if (float(localVertexIndex) < globalShapeMatchingEffectiveRange * float(numVerticesInTheStrand)) + { + float factor = stiffnessForGlobalShapeMatching; + vec3 del = factor * (initialPos - tmpPos).xyz; + tmpPos.xyz += del; + } + } + } + + // update global position buffers + UpdateFinalVertexPositions(currentPos, tmpPos, globalVertexIndex, localVertexIndex, numVerticesInTheStrand); +} diff --git a/amd_tressfx_vulkan/src/Shaders/HairShadowMap.frag b/amd_tressfx_vulkan/src/Shaders/HairShadowMap.frag new file mode 100644 index 0000000..a9eff44 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/HairShadowMap.frag @@ -0,0 +1,7 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +void main() +{ +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/HairShadowMap.vert b/amd_tressfx_vulkan/src/Shaders/HairShadowMap.vert new file mode 100644 index 0000000..2966967 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/HairShadowMap.vert @@ -0,0 +1,17 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" + +layout(set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) uniform samplerBuffer g_HairVertexPositions; + +out gl_PerVertex{ + vec4 gl_Position; +}; + +void main() +{ + gl_Position = g_mViewProjLight * vec4(texelFetch(g_HairVertexPositions, gl_VertexIndex).xyz, 1.); +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/IndicesComputations.glsl b/amd_tressfx_vulkan/src/Shaders/IndicesComputations.glsl new file mode 100644 index 0000000..807e97b --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/IndicesComputations.glsl @@ -0,0 +1,45 @@ +layout(set = 1, binding = IDSRV_HAIR_STRAND_TYPE) uniform usamplerBuffer g_HairStrandType; + +void CalcIndicesInVertexLevelMaster(uint local_id, uint group_id, inout uint globalStrandIndex, inout uint localStrandIndex, inout int globalVertexIndex, inout uint localVertexIndex, inout uint numVerticesInTheStrand, inout uint indexForSharedMem, inout uint strandType) +{ + indexForSharedMem = local_id; + numVerticesInTheStrand = (THREAD_GROUP_SIZE / g_NumOfStrandsPerThreadGroup); + + localStrandIndex = local_id % g_NumOfStrandsPerThreadGroup; + globalStrandIndex = group_id * g_NumOfStrandsPerThreadGroup + localStrandIndex; + globalStrandIndex *= (g_NumFollowHairsPerGuideHair + 1); + localVertexIndex = (local_id - localStrandIndex) / g_NumOfStrandsPerThreadGroup; + + strandType = texelFetch(g_HairStrandType, int(globalStrandIndex)).x; + globalVertexIndex = int(globalStrandIndex * numVerticesInTheStrand + localVertexIndex); +} + +void CalcIndicesInVertexLevelTotal(uint local_id, uint group_id, inout uint globalStrandIndex, inout uint localStrandIndex, inout int globalVertexIndex, inout uint localVertexIndex, inout uint numVerticesInTheStrand, inout uint indexForSharedMem, inout uint strandType) +{ + indexForSharedMem = local_id; + numVerticesInTheStrand = (THREAD_GROUP_SIZE / g_NumOfStrandsPerThreadGroup); + + localStrandIndex = local_id % g_NumOfStrandsPerThreadGroup; + globalStrandIndex = group_id * g_NumOfStrandsPerThreadGroup + localStrandIndex; + localVertexIndex = (local_id - localStrandIndex) / g_NumOfStrandsPerThreadGroup; + + strandType = texelFetch(g_HairStrandType, int(globalStrandIndex)).x; + globalVertexIndex = int(globalStrandIndex * numVerticesInTheStrand + localVertexIndex); +} + +void CalcIndicesInStrandLevelTotal(uint local_id, uint group_id, inout uint globalStrandIndex, inout uint numVerticesInTheStrand, inout uint globalRootVertexIndex, inout uint strandType) +{ + globalStrandIndex = THREAD_GROUP_SIZE*group_id + local_id; + numVerticesInTheStrand = (THREAD_GROUP_SIZE / g_NumOfStrandsPerThreadGroup); + strandType = texelFetch(g_HairStrandType, int(globalStrandIndex)).x; + globalRootVertexIndex = globalStrandIndex * numVerticesInTheStrand; +} + +void CalcIndicesInStrandLevelMaster(int local_id, int group_id, inout int globalStrandIndex, inout uint numVerticesInTheStrand, inout int globalRootVertexIndex, inout uint strandType) +{ + globalStrandIndex = THREAD_GROUP_SIZE * group_id + local_id; + globalStrandIndex *= int(g_NumFollowHairsPerGuideHair + 1); + numVerticesInTheStrand = (THREAD_GROUP_SIZE / g_NumOfStrandsPerThreadGroup); + strandType = texelFetch(g_HairStrandType, globalStrandIndex).x; + globalRootVertexIndex = globalStrandIndex * int(numVerticesInTheStrand); +} diff --git a/amd_tressfx_vulkan/src/Shaders/LengthWindCollision.comp b/amd_tressfx_vulkan/src/Shaders/LengthWindCollision.comp new file mode 100644 index 0000000..19cae7b --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/LengthWindCollision.comp @@ -0,0 +1,199 @@ +#version 450 + +#include "SimulationConfig.glsl" + +layout (local_size_x = THREAD_GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; + +layout(std430, set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) buffer writeablePositions +{ + vec4 g_HairVertexPositions[]; +}; +layout(set = 1, binding = IDSRV_HAIR_LENGTH) uniform samplerBuffer g_HairRestLengthSRV; + +#include "IndicesComputations.glsl" + +shared vec4 sharedPos[THREAD_GROUP_SIZE]; +shared float sharedLength[THREAD_GROUP_SIZE]; + +vec2 ConstraintMultiplier(vec4 particle0, vec4 particle1) +{ + if (IsMovable(particle0)) + { + if (IsMovable(particle1)) + return vec2(0.5, 0.5); + else + return vec2(1, 0); + } + else + { + if (IsMovable(particle1)) + return vec2(0, 1); + else + return vec2(0, 0); + } +} + +void ApplyDistanceConstraint(inout vec4 pos0, inout vec4 pos1, float targetDistance, float stiffness) +{ + vec3 delta = pos1.xyz - pos0.xyz; + float distance = max(length(delta), 1e-7); + float stretching = 1 - targetDistance / distance; + delta = stretching * delta; + vec2 multiplier = ConstraintMultiplier(pos0, pos1); + + pos0.xyz += multiplier[0] * delta * stiffness; + pos1.xyz -= multiplier[1] * delta * stiffness; +} + + +//-------------------------------------------------------------------------------------- +// +// LengthConstriantsWindAndCollision +// +// Compute shader to move the vertex position based on wind, maintain the lenght constraints +// and handles collisions. +// +// One thread computes one vertex. +// +//-------------------------------------------------------------------------------------- + +void main() +{ + uint globalStrandIndex, localStrandIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType; + int globalVertexIndex; + CalcIndicesInVertexLevelMaster(gl_LocalInvocationID.x, gl_WorkGroupID.x, globalStrandIndex, localStrandIndex, globalVertexIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType); + + uint numOfStrandsPerThreadGroup = g_NumOfStrandsPerThreadGroup; + + //------------------------------ + // Copy data into shared memory + //------------------------------ + sharedPos[indexForSharedMem] = g_HairVertexPositions[globalVertexIndex]; + sharedLength[indexForSharedMem] = texelFetch(g_HairRestLengthSRV, globalVertexIndex).x; + barrier(); + + + //------------ + // Wind + //------------ + if (g_Wind.x != 0 || g_Wind.y != 0 || g_Wind.z != 0) + { + vec4 force = vec4(0.); + + float frame = g_Wind.w; + + if (localVertexIndex >= 2 && localVertexIndex < numVerticesInTheStrand - 1) + { + // combining four winds. + float a = float(globalStrandIndex % 20) / 20.0; + vec3 w = a * g_Wind.xyz + (1.0 - a) * g_Wind1.xyz + a * g_Wind2.xyz + (1. - a) * g_Wind3.xyz; + + int sharedIndex = int(localVertexIndex) * int(numOfStrandsPerThreadGroup) + int(localStrandIndex); + + vec3 v = sharedPos[sharedIndex].xyz - sharedPos[sharedIndex + numOfStrandsPerThreadGroup].xyz; + vec3 force = -cross(cross(v, w), v); + sharedPos[sharedIndex].xyz += force*g_TimeStep*g_TimeStep; + } + } + + barrier(); + + //---------------------------- + // Enforce length constraints + //---------------------------- + int a = int(floor(numVerticesInTheStrand / 2.)); + int b = int(floor((numVerticesInTheStrand - 1.) / 2.)); + + for (int iterationE = 0; iterationE < g_NumLengthConstraintIterations; iterationE++) + { + int sharedIndex = 2 * int(localVertexIndex) * int(numOfStrandsPerThreadGroup) + int(localStrandIndex); + + if( localVertexIndex < a) + ApplyDistanceConstraint(sharedPos[sharedIndex], sharedPos[sharedIndex+numOfStrandsPerThreadGroup], sharedLength[sharedIndex].x, 1.); + + barrier(); + + if( localVertexIndex < b) + ApplyDistanceConstraint(sharedPos[sharedIndex + numOfStrandsPerThreadGroup], sharedPos[sharedIndex + numOfStrandsPerThreadGroup * 2], sharedLength[sharedIndex + numOfStrandsPerThreadGroup].x, 1.); + + barrier(); + } + + + //------------------------------------------------- + // Collision handling hard-code collision shapes + //------------------------------------------------- + bool bColDetected = false; + + /* + float4 oldPos = g_HairVertexPositionsPrev[globalVertexIndex]; + + if ( g_bCollision > 0 ) + { + float3 newPos; + + { + float3 centerSphere = g_cc0_center; + centerSphere = mul(float4( centerSphere.xyz, 1), g_ModelTransformForHead).xyz; + float radius = g_cc0_radius; + + CollisionCapsule cc; + cc.p1.xyz = centerSphere; + cc.p1.w = radius; + cc.p2.xyz = centerSphere + float3(0.0,1.0,0.0); + cc.p2.w = g_cc0_radius2; + + bColDetected = CapsuleCollision(sharedPos[indexForSharedMem], oldPos, newPos, cc, true); + + if ( bColDetected ) + sharedPos[indexForSharedMem].xyz = newPos; + } + + { + float3 centerSphere = g_cc1_center; + centerSphere = mul(float4( centerSphere.xyz, 1), g_ModelTransformForHead).xyz; + float radius = g_cc1_radius; + + CollisionCapsule cc; + cc.p1.xyz = centerSphere; + cc.p1.w = radius; + cc.p2.xyz = centerSphere + float3(0.0,1.0,0.0); + cc.p2.w = g_cc1_radius2; + + bColDetected = CapsuleCollision(sharedPos[indexForSharedMem], oldPos, newPos, cc, true); + + if ( bColDetected ) + sharedPos[indexForSharedMem].xyz = newPos; + } + + { + float3 centerSphere = g_cc2_center; + centerSphere = mul(float4( centerSphere.xyz, 1), g_ModelTransformForHead).xyz; + float radius = g_cc2_radius; + + CollisionCapsule cc; + cc.p1.xyz = centerSphere; + cc.p1.w = radius; + cc.p2.xyz = centerSphere + float3(0.0,1.0,0.0); + cc.p2.w = g_cc2_radius2; + + bColDetected = CapsuleCollision(sharedPos[indexForSharedMem], oldPos, newPos, cc, true); + + if ( bColDetected ) + sharedPos[indexForSharedMem].xyz = newPos; + } + } + + GroupMemoryBarrierWithGroupSync(); +*/ + + //--------------------------------------- + // update global position buffers + //--------------------------------------- + g_HairVertexPositions[globalVertexIndex] = sharedPos[indexForSharedMem]; + +// if ( bColDetected ) +// g_HairVertexPositionsPrev[globalVertexIndex] = sharedPos[indexForSharedMem]; + + return; +} diff --git a/amd_tressfx_vulkan/src/Shaders/LocalConstraints.comp b/amd_tressfx_vulkan/src/Shaders/LocalConstraints.comp new file mode 100644 index 0000000..e7c9dc0 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/LocalConstraints.comp @@ -0,0 +1,173 @@ +#version 450 + +#include "SimulationConfig.glsl" + +layout (local_size_x = THREAD_GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; + +layout(std430, set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) buffer writeablePositions +{ + vec4 g_HairVertexPositions[]; +}; +layout(set = 1, binding = IDSRV_HAIR_GLOBAL_ROTATION) uniform samplerBuffer g_GlobalRotations; +layout(set = 1, binding = IDSRV_HAIR_LOCAL_REF_VEC) uniform samplerBuffer g_HairRefVecsInLocalFrame; + +#include "IndicesComputations.glsl" + +vec4 MultQuaternionAndQuaternion(vec4 qA, vec4 qB) +{ + vec4 q; + + q.w = qA.w * qB.w - qA.x * qB.x - qA.y * qB.y - qA.z * qB.z; + q.x = qA.w * qB.x + qA.x * qB.w + qA.y * qB.z - qA.z * qB.y; + q.y = qA.w * qB.y + qA.y * qB.w + qA.z * qB.x - qA.x * qB.z; + q.z = qA.w * qB.z + qA.z * qB.w + qA.x * qB.y - qA.y * qB.x; + + return q; +} + +vec3 MultQuaternionAndVector(vec4 q, vec3 v) +{ + vec3 uv, uuv; + vec3 qvec = vec3(q.x, q.y, q.z); + uv = cross(qvec, v); + uuv = cross(qvec, uv); + uv *= (2.0f * q.w); + uuv *= 2.0f; + + return v + uv + uuv; +} + +vec4 MakeQuaternion(float angle_radian, vec3 axis) +{ + // create quaternion using angle and rotation axis + vec4 quaternion; + float halfAngle = 0.5f * angle_radian; + float sinHalf = sin(halfAngle); + + quaternion.w = cos(halfAngle); + quaternion.xyz = sinHalf * axis.xyz; + + return quaternion; +} + +vec4 InverseQuaternion(vec4 q) +{ + float lengthSqr = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w; + + if ( lengthSqr < 0.001 ) + return vec4(0, 0, 0, 1.0f); + + q.x = -q.x / lengthSqr; + q.y = -q.y / lengthSqr; + q.z = -q.z / lengthSqr; + q.w = q.w / lengthSqr; + + return q; +} + + +//-------------------------------------------------------------------------------------- +// +// LocalShapeConstraintsWithIteration +// +// Compute shader to maintain the local shape constraints. This is the same as +// the LocalShapeConstraints shader, except the iterations are done on the GPU +// instead of multiple dispatch calls on the CPU, for better performance +// +//-------------------------------------------------------------------------------------- + +void main() +{ + int globalStrandIndex, globalRootVertexIndex; + uint numVerticesInTheStrand, strandType; + CalcIndicesInStrandLevelMaster(int(gl_LocalInvocationID.x), int(gl_WorkGroupID.x), globalStrandIndex, numVerticesInTheStrand, globalRootVertexIndex, strandType); + + // stiffness for local shape constraints + float stiffnessForLocalShapeMatching = 0.4; + + if ( strandType == 2) + stiffnessForLocalShapeMatching = g_StiffnessForLocalShapeMatching2; + else if ( strandType == 3 ) + stiffnessForLocalShapeMatching = g_StiffnessForLocalShapeMatching3; + else if ( strandType == 1 ) + stiffnessForLocalShapeMatching = g_StiffnessForLocalShapeMatching1; + else if ( strandType == 0 ) + stiffnessForLocalShapeMatching = g_StiffnessForLocalShapeMatching0; + + //1.0 for stiffness makes things unstable sometimes. + stiffnessForLocalShapeMatching = 0.5 * min(stiffnessForLocalShapeMatching, 0.95); + + //------------------------------ + // Copy strand data into registers, for faster iteration + //------------------------------ + int globalVertexIndex = 0; + vec4 sharedStrandPos[MAX_VERTS_PER_STRAND]; + for (int localVertexIndex = 0; localVertexIndex < numVerticesInTheStrand; localVertexIndex++) + { + globalVertexIndex = globalRootVertexIndex + localVertexIndex; + sharedStrandPos[localVertexIndex] = g_HairVertexPositions[globalVertexIndex]; + } + + //-------------------------------------------- + // Local shape constraint for bending/twisting + //-------------------------------------------- + for (int iterations = 0; iterations < g_NumLocalShapeMatchingIterations; iterations++) + { + vec4 pos = sharedStrandPos[1]; + vec4 rotGlobal = texelFetch(g_GlobalRotations, globalRootVertexIndex); + + for (int localVertexIndex = 1; localVertexIndex < numVerticesInTheStrand - 1; localVertexIndex++) + { + globalVertexIndex = globalRootVertexIndex + localVertexIndex; + vec4 pos_plus_one = sharedStrandPos[localVertexIndex+1]; + + //-------------------------------- + // Update position i and i_plus_1 + //-------------------------------- + vec4 rotGlobalWorld = MultQuaternionAndQuaternion(g_ModelRotateForHead, rotGlobal); + + vec3 orgPos_i_plus_1_InLocalFrame_i = texelFetch(g_HairRefVecsInLocalFrame, globalVertexIndex + 1).xyz; + vec3 orgPos_i_plus_1_InGlobalFrame = MultQuaternionAndVector(rotGlobalWorld, orgPos_i_plus_1_InLocalFrame_i) + pos.xyz; + + vec3 del = stiffnessForLocalShapeMatching * (orgPos_i_plus_1_InGlobalFrame - pos_plus_one.xyz).xyz; + + if (IsMovable(pos)) + pos.xyz -= del.xyz; + + if (IsMovable(pos_plus_one)) + pos_plus_one.xyz += del.xyz; + + //--------------------------- + // Update local/global frames + //--------------------------- + vec4 invRotGlobalWorld = InverseQuaternion(rotGlobalWorld); + vec3 vec = normalize(pos_plus_one.xyz - pos.xyz); + + vec3 x_i_plus_1_frame_i = normalize(MultQuaternionAndVector(invRotGlobalWorld, vec)); + vec3 e = vec3(1., 0, 0); + vec3 rotAxis = cross(e, x_i_plus_1_frame_i); + + if ( length(rotAxis) > 0.001 ) + { + float angle_radian = acos(dot(e, x_i_plus_1_frame_i)); + rotAxis = normalize(rotAxis); + + vec4 localRot = MakeQuaternion(angle_radian, rotAxis); + rotGlobal = MultQuaternionAndQuaternion(rotGlobal, localRot); + } + + sharedStrandPos[localVertexIndex].xyz = pos.xyz; + sharedStrandPos[localVertexIndex+1].xyz = pos_plus_one.xyz; + + pos = pos_plus_one; + } + } + + for (int localVertexIndex = 0; localVertexIndex < numVerticesInTheStrand; localVertexIndex++) + { + globalVertexIndex = globalRootVertexIndex + localVertexIndex; + g_HairVertexPositions[globalVertexIndex] = sharedStrandPos[localVertexIndex]; + } + + return; +} diff --git a/amd_tressfx_vulkan/src/Shaders/PackUnpack.glsl b/amd_tressfx_vulkan/src/Shaders/PackUnpack.glsl new file mode 100644 index 0000000..0b8f1a5 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/PackUnpack.glsl @@ -0,0 +1,31 @@ +//-------------------------------------------------------------------------------------- +// Helper functions for packing and unpacking the stored tangent and coverage +//-------------------------------------------------------------------------------------- +uint PackFloat4IntoUint(vec4 vValue) +{ + uint byte3 = uint(vValue.x * 255.) & 0xFF; + uint byte2 = uint(vValue.y * 255.) & 0xFF; + uint byte1 = uint(vValue.z * 255) & 0xFF; + uint byte0 = uint(vValue.w * 255) & 0xFF; + return (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0; +} + +vec4 UnpackUintIntoFloat4(uint uValue) +{ + return vec4(((uValue & 0xFF000000) >> 24) / 255.0, ((uValue & 0x00FF0000) >> 16) / 255.0, ((uValue & 0x0000FF00) >> 8) / 255.0, ((uValue & 0x000000FF)) / 255.0); +} + +uint PackTangentAndCoverage(vec3 tangent, float coverage) +{ + return PackFloat4IntoUint(vec4(tangent.xyz*0.5 + 0.5, coverage)); +} + +vec3 GetTangent(uint packedTangent) +{ + return 2.0 * UnpackUintIntoFloat4(packedTangent).xyz - 1.0; +} + +float GetCoverage(uint packedCoverage) +{ + return UnpackUintIntoFloat4(packedCoverage).w; +} diff --git a/amd_tressfx_vulkan/src/Shaders/PrepareFollowHair.comp b/amd_tressfx_vulkan/src/Shaders/PrepareFollowHair.comp new file mode 100644 index 0000000..c394fbe --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/PrepareFollowHair.comp @@ -0,0 +1,29 @@ +#version 450 + +#include "SimulationConfig.glsl" + +layout (local_size_x = THREAD_GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; +layout(std430, set = 1, binding = IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS) buffer writeablePositionPrev +{ + vec4 g_HairVertexPositionsPrev[]; +}; +layout(set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) uniform samplerBuffer g_HairVertexPositions; + +#include "IndicesComputations.glsl" + +// One thread computes one vertex. +void main() +{ + uint globalStrandIndex, localStrandIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType; + int globalVertexIndex; + CalcIndicesInVertexLevelMaster(gl_LocalInvocationID.x, gl_WorkGroupID.x, globalStrandIndex, localStrandIndex, globalVertexIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType); + + for (int i = 0; i < g_NumFollowHairsPerGuideHair; i++) + { + int globalFollowVertexIndex = globalVertexIndex + int(numVerticesInTheStrand) * (i + 1); + vec4 hairPos = texelFetch(g_HairVertexPositions, globalFollowVertexIndex).xyzw; + g_HairVertexPositionsPrev[globalFollowVertexIndex] = hairPos; + } + + return; +} diff --git a/amd_tressfx_vulkan/src/Shaders/RenderConfig.glsl b/amd_tressfx_vulkan/src/Shaders/RenderConfig.glsl new file mode 100644 index 0000000..377bf47 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/RenderConfig.glsl @@ -0,0 +1,92 @@ +#pragma once + +// shader resource view slots +#define IDSRV_PPLL 0 +#define IDSRV_HEAD_PPLL 1 +#define IDSRV_SCENESM 2 +#define IDSRV_HAIRSM 3 +#define IDSRV_HAIR_COLOR_TEXTURE 4 +#define IDSRV_NOISEMAP 5 +#define IDSRV_HAIR_THICKNESSES 6 +#define IDSRV_HAIR_VERTEX_POSITIONS 7 +#define IDSRV_HAIR_TANGENTS 8 +#define IDSRV_HAIR_TRANSFORMS 9 +#define IDSRV_HAIR_STRAND_TEX_COORDS 10 +#define IDSRV_HAIR_VERTEX_TEX_COORDS 11 +#define IDSRV_HAIR_VERTEX_COLORS 12 + +// Shortcut resources. +#define IDSRV_HAIR_FRAGMENT_DEPTHS 13 +#define IDSRV_HAIR_FRAGMENT_COLORS 14 +#define IDSRV_HAIR_ACCUM_INV_ALPHA 15 + +#define IDSRV_CONSTANTS_BUFFER 16 +#define IDSRV_ATOMIC_COUNTER_BUFFER 17 +#define IDSRV_NOISE_SAMPLER 18 +#define IDSRV_SHADOW_SAMPLER 19 + +#define IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS 20 +#define IDSRV_HAIR_VERTEX_INITIAL_POSITIONS 21 +#define IDSRV_HAIR_STRAND_TYPE 22 +#define IDSRV_HAIR_GLOBAL_ROTATION 23 +#define IDSRV_HAIR_LOCAL_REF_VEC 24 +#define IDSRV_HAIR_ROOT_OFFSET 25 +#define IDSRV_HAIR_LENGTH 26 +#define IDSRV_HEAD_TRANSFORM 27 + +#define SM_EPSILON 0.01 +#define KERNEL_SIZE 5 +#define PI 3.14 +#define FLOAT_EPSILON 1e-7 + +#define SHORTCUT_MIN_ALPHA 0.02 + +// Number of depth layers to use. 2 or 3 supported. +#define SHORTCUT_NUM_DEPTHS 3 + +// Compute source color as weighted average of front fragments, vs blending in order. +#define SHORTCUT_WEIGHTED_AVERAGE 1 + +// Output color deterministically when fragments have the same depth. Requires additional clear of colors resource. +#define SHORTCUT_DETERMINISTIC 1 + +layout(std140, set = 0, binding = IDSRV_CONSTANTS_BUFFER) uniform Constants +{ +mat4 g_mWorld; +mat4 g_mViewProj; +mat4 g_mInvViewProj; +mat4 g_mViewProjLight; + +vec3 g_vEye; +float g_fvFov; + +vec4 g_AmbientLightColor; +vec4 g_PointLightColor; +vec4 g_PointLightPos; +vec4 g_MatBaseColor; +vec4 g_MatKValue; // Ka, Kd, Ks, Ex + +float g_FiberAlpha; +float g_HairShadowAlpha; +float g_bExpandPixels; +float g_FiberRadius; + +vec4 g_WinSize; // screen size + +float g_FiberSpacing; // average spacing between fibers +float g_bThinTip; +float g_fNearLight; +float g_fFarLight; + +int g_iTechSM; +int g_bUseCoverage; +int g_iStrandCopies; // strand copies that the transparency shader will produce +int g_iMaxFragments; + +float g_alphaThreshold; +float g_fHairKs2; // for second highlight +float g_fHairEx2; // for second highlight + +mat4 g_mInvViewProjViewport; +}; + diff --git a/amd_tressfx_vulkan/src/Shaders/RenderHair.vert b/amd_tressfx_vulkan/src/Shaders/RenderHair.vert new file mode 100644 index 0000000..1f8e21a --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/RenderHair.vert @@ -0,0 +1,59 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" + +layout(set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) uniform samplerBuffer g_HairVertexPositions; +layout(set = 1, binding = IDSRV_HAIR_TANGENTS) uniform samplerBuffer g_HairVertexTangents; +layout(set = 1, binding = IDSRV_HAIR_THICKNESSES) uniform samplerBuffer g_HairThicknessCoeffs; + +out gl_PerVertex{ + vec4 gl_Position; +}; + +vec2 Safe_normalize(vec2 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec2(0, 0); +} + +vec3 Safe_normalize(vec3 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec3(0, 0, 0); +} + +// Need Depth, gl_FragCoord.z returns meaningless values... +layout(location = 0) out float depth; +layout(location = 1) out vec4 p0p1; +layout(location = 2) out vec4 tangent; +layout(location = 3) out vec4 strandColor; + +//-------------------------------------------------------------------------------------- +// VS_RenderHair +// +// Vertex shader for rendering the hair strands without AA +//-------------------------------------------------------------------------------------- +void main() +{ + vec3 v = texelFetch(g_HairVertexPositions, gl_VertexIndex / 2).xyz; + vec3 Tangent = texelFetch(g_HairVertexTangents, gl_VertexIndex / 2).xyz; + float ratio = (g_bThinTip > 0) ? texelFetch(g_HairThicknessCoeffs, gl_VertexIndex / 2).x : 1.; + + // Calculate right and projected right vectors + vec3 right = Safe_normalize(cross(Tangent, normalize(v - g_vEye))); + vec2 proj_right = Safe_normalize((g_mViewProj * vec4(right, 0)).xy); + + float expandPixels = (g_bExpandPixels < 0) ? 0.0 : 0.71; + float fDirIndex = (gl_VertexIndex % 2 == 1) ? -1.0 : 1.0; + + vec3 temp = v + fDirIndex * right * ratio * g_FiberRadius; + gl_Position = g_mViewProj * vec4(temp, 1.f); + gl_Position = gl_Position + fDirIndex * vec4(proj_right * expandPixels / g_WinSize.y, 0.f, 0.f) * gl_Position.w; + depth = gl_Position.z / gl_Position.w; + tangent = vec4(Tangent, ratio); + p0p1 = vec4(v.xy, texelFetch(g_HairVertexPositions, gl_VertexIndex / 2 + 1).xy); + // TODO: Strand color +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/RenderHairAA.vert b/amd_tressfx_vulkan/src/Shaders/RenderHairAA.vert new file mode 100644 index 0000000..3c671f3 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/RenderHairAA.vert @@ -0,0 +1,65 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" + +layout(set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) uniform samplerBuffer g_HairVertexPositions; +layout(set = 1, binding = IDSRV_HAIR_TANGENTS) uniform samplerBuffer g_HairVertexTangents; +layout(set = 1, binding = IDSRV_HAIR_THICKNESSES) uniform samplerBuffer g_HairThicknessCoeffs; + +out gl_PerVertex { + vec4 gl_Position; +}; + +vec2 Safe_normalize(vec2 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec2(0,0); +} + +vec3 Safe_normalize(vec3 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec3(0,0,0); +} + +// Need Depth, gl_FragCoord.z returns meaningless values... +layout(location = 0) out float depth; +layout(location = 1) out vec4 p0p1; +layout(location = 2) out vec4 tangent; +layout(location = 3) out vec4 strandColor; + +//-------------------------------------------------------------------------------------- +// VS_RenderHair_AA +// +// Vertex shader for rendering the hair strands with randomized copies and AA +//-------------------------------------------------------------------------------------- +void main(void) { + vec3 v = texelFetch(g_HairVertexPositions, gl_VertexIndex / 2).xyz; + vec3 Tangent = texelFetch(g_HairVertexTangents, gl_VertexIndex / 2).xyz; + float ratio = (g_bThinTip > 0) ? texelFetch(g_HairThicknessCoeffs, gl_VertexIndex / 2).x : 1.; + + // Calculate right and projected right vectors + vec3 right = Safe_normalize( cross( Tangent, normalize(v - g_vEye))); + vec2 proj_right = Safe_normalize( (g_mViewProj * vec4(right, 0)).xy ); + + vec4 hairEdgePositions0, hairEdgePositions1; // 0 is negative, 1 is positive + hairEdgePositions0 = vec4(v - 1.0 * right * ratio * g_FiberRadius, 1.0); + hairEdgePositions1 = vec4(v + 1.0 * right * ratio * g_FiberRadius, 1.0); + hairEdgePositions0 = g_mViewProj * hairEdgePositions0; + hairEdgePositions1 = g_mViewProj * hairEdgePositions1; + hairEdgePositions0 = hairEdgePositions0 / hairEdgePositions0.w; + hairEdgePositions1 = hairEdgePositions1 / hairEdgePositions1.w; + + float expandPixels = (g_bExpandPixels < 0) ? 0.0 : 0.71; + + float fDirIndex = (gl_VertexIndex % 2 == 1) ? -1.0 : 1.0; + + gl_Position = (fDirIndex==-1.0 ? hairEdgePositions0 : hairEdgePositions1) + fDirIndex * vec4(proj_right * expandPixels / g_WinSize.y, 0.0, 0.0); + depth = gl_Position.z; + tangent = vec4(Tangent, ratio); + p0p1 = vec4( hairEdgePositions0.xy, hairEdgePositions1.xy ); + // TODO: Strand color +} diff --git a/amd_tressfx_vulkan/src/Shaders/RenderHairAAStrandCopies.vert b/amd_tressfx_vulkan/src/Shaders/RenderHairAAStrandCopies.vert new file mode 100644 index 0000000..4f3fe20 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/RenderHairAAStrandCopies.vert @@ -0,0 +1,85 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" + +layout(set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) uniform samplerBuffer g_HairVertexPositions; +layout(set = 1, binding = IDSRV_HAIR_TANGENTS) uniform samplerBuffer g_HairVertexTangents; +layout(set = 1, binding = IDSRV_HAIR_THICKNESSES) uniform samplerBuffer g_HairThicknessCoeffs; +layout(set = 0, binding = IDSRV_NOISEMAP) uniform texture2D g_txNoise; +layout(set = 0, binding = IDSRV_NOISE_SAMPLER) uniform sampler g_samLinearWrap; + +out gl_PerVertex{ + vec4 gl_Position; +}; + +vec2 Safe_normalize(vec2 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec2(0, 0); +} + +vec3 Safe_normalize(vec3 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec3(0, 0, 0); +} + +// Need Depth, gl_FragCoord.z returns meaningless values... +layout(location = 0) out float depth; +layout(location = 1) out vec4 p0p1; +layout(location = 2) out vec4 tangent; +layout(location = 3) out vec4 strandColor; + +//-------------------------------------------------------------------------------------- +// VS_RenderHair_AA_StrandCopies +// +// Vertex shader for rendering the hair strands with randomized copies and AA +//-------------------------------------------------------------------------------------- +void main() +{ + // Access the current line segment + int index = gl_VertexIndex / 2; // vertexId is actually the indexed vertex id when indexed triangles are used + + // Identifies which copy of the strand this is (0 is the original, 1 is the first copy, etc.) + int randOffsetIndex = gl_InstanceIndex; + + // Getting a random offset value + uint seedRand = ((index / 64 + 1) * (randOffsetIndex + 1)) % 512; + vec2 seedTexcorrd = vec2(float(seedRand % 512), float(seedRand / 512)) * (1.f / 512.f); + vec3 randOffset = float(randOffsetIndex) * textureLod(sampler2D(g_txNoise, g_samLinearWrap), seedTexcorrd, 0).xyz; + randOffset = 2.0f * randOffset - 1.0f; // so we have random offsets between -1 and 1 + + + // Get updated positions and tangents from simulation result + vec3 Tangent = texelFetch(g_HairVertexTangents, gl_VertexIndex / 2).xyz; + vec3 v = randOffset.xyz + texelFetch(g_HairVertexPositions, gl_VertexIndex / 2).xyz; // We apply a random offset to each vertex when multiple strands are requested + + // Get hair strand thickness + float ratio = (g_bThinTip > 0) ? texelFetch(g_HairThicknessCoeffs, gl_VertexIndex / 2).x : 1.; + + // Calculate right and projected right vectors + vec3 right = Safe_normalize(cross(Tangent, normalize(v - g_vEye))); + vec2 proj_right = Safe_normalize((g_mViewProj * vec4(right, 0)).xy); + + // g_bExpandPixels should be set to 0 at minimum from the CPU side; this would avoid the below test + float expandPixels = (g_bExpandPixels < 0) ? 0.0 : 0.71; + + // Calculate the negative and positive offset screenspace positions + vec4 hairEdgePositions0, hairEdgePositions1; // 0 is negative, 1 is positive + hairEdgePositions0 = vec4(v - 1.0 * right * ratio * g_FiberRadius, 1.0); + hairEdgePositions1 = vec4(v + 1.0 * right * ratio * g_FiberRadius, 1.0); + hairEdgePositions0 = g_mViewProj * hairEdgePositions0; + hairEdgePositions1 = g_mViewProj * hairEdgePositions1; + + // Write output data + + float fDirIndex = (gl_VertexIndex % 2 == 1) ? -1.0 : 1.0; + gl_Position = ((fDirIndex == -1.0) ? hairEdgePositions0 : hairEdgePositions1) + fDirIndex * vec4(proj_right * expandPixels / g_WinSize.y, 0.0f, 0.0f) * ((fDirIndex == -1.0) ? hairEdgePositions0.w : hairEdgePositions1.w); + depth = gl_Position.z / gl_Position.w; + tangent = vec4(Tangent, ratio); + p0p1 = vec4(hairEdgePositions0.xy / max(hairEdgePositions0.w, FLOAT_EPSILON), hairEdgePositions1.xy / max(hairEdgePositions1.w, FLOAT_EPSILON)); + // TODO: Strand color +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/RenderHairStrandCopies.vert b/amd_tressfx_vulkan/src/Shaders/RenderHairStrandCopies.vert new file mode 100644 index 0000000..e9efc80 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/RenderHairStrandCopies.vert @@ -0,0 +1,77 @@ +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" + +layout(set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) uniform samplerBuffer g_HairVertexPositions; +layout(set = 1, binding = IDSRV_HAIR_TANGENTS) uniform samplerBuffer g_HairVertexTangents; +layout(set = 1, binding = IDSRV_HAIR_THICKNESSES) uniform samplerBuffer g_HairThicknessCoeffs; +layout(set = 0, binding = IDSRV_NOISEMAP) uniform texture2D g_txNoise; +layout(set = 0, binding = IDSRV_NOISE_SAMPLER) uniform sampler g_samLinearWrap; + +out gl_PerVertex{ + vec4 gl_Position; +}; + +vec2 Safe_normalize(vec2 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec2(0, 0); +} + +vec3 Safe_normalize(vec3 vec) +{ + float len = length(vec); + return len >= FLOAT_EPSILON ? (vec / len) : vec3(0, 0, 0); +} + +// Need Depth, gl_FragCoord.z returns meaningless values... +layout(location = 0) out float depth; +layout(location = 1) out vec4 p0p1; +layout(location = 2) out vec4 tangent; +layout(location = 3) out vec4 strandColor; + +//-------------------------------------------------------------------------------------- +// VS_RenderHair_StrandCopies +// +// Vertex shader for rendering the hair strands with randomized copies and without AA +//-------------------------------------------------------------------------------------- +void main() +{ + // Access the current line segment + int index = gl_VertexIndex / 2; // vertexId is actually the indexed vertex id when indexed triangles are used + + // Identifies which copy of the strand this is (0 is the original, 1 is the first copy, etc.) + int randOffsetIndex = gl_InstanceIndex; + + // Getting a random offset value + uint seedRand = ((index / 64 + 1) * (randOffsetIndex + 1)) % 512; + vec2 seedTexcorrd = vec2(float(seedRand % 512), float(seedRand / 512)) * (1.f / 512.f); + vec3 randOffset = float(randOffsetIndex) * textureLod(sampler2D(g_txNoise, g_samLinearWrap), seedTexcorrd, 0).xyz; + randOffset = 2.0f * randOffset - 1.0f; // so we have random offsets between -1 and 1 + + // Get updated positions and tangents from simulation result + vec3 Tangent = texelFetch(g_HairVertexTangents, gl_VertexIndex / 2).xyz; + vec3 v = randOffset.xyz + texelFetch(g_HairVertexPositions, gl_VertexIndex / 2).xyz; // We apply a random offset to each vertex when multiple strands are requested + + // Get hair strand thickness + float ratio = (g_bThinTip > 0) ? texelFetch(g_HairThicknessCoeffs, gl_VertexIndex / 2).x : 1.; + + // Calculate right and projected right vectors + vec3 right = Safe_normalize(cross(Tangent, normalize(v - g_vEye))); + vec2 proj_right = Safe_normalize((g_mViewProj * vec4(right, 0)).xy); + + // g_bExpandPixels should be set to 0 at minimum from the CPU side; this would avoid the below test + float expandPixels = (g_bExpandPixels < 0) ? 0.0 : 0.71; + + float fDirIndex = (gl_VertexIndex % 2 == 1) ? -1.0 : 1.0; + vec3 temp = v + fDirIndex * right * ratio * g_FiberRadius; + gl_Position = g_mViewProj * vec4(temp, 1.f); + gl_Position = gl_Position + fDirIndex * vec4(proj_right * expandPixels / g_WinSize.y, 0.f, 0.f) * gl_Position.w; + depth = gl_Position.z / gl_Position.w; + tangent = vec4(Tangent, ratio); + p0p1 = vec4(v.xy, randOffset.xy + texelFetch(g_HairVertexPositions, gl_VertexIndex / 2 + 1).xy); + // TODO: Strand color +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/SimulationConfig.glsl b/amd_tressfx_vulkan/src/Shaders/SimulationConfig.glsl new file mode 100644 index 0000000..3582fde --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/SimulationConfig.glsl @@ -0,0 +1,92 @@ +// If you change the value below, you must change it in TressFXAsset.h as well. +#define THREAD_GROUP_SIZE 64 + +// shader resource view slots +#define IDSRV_PPLL 0 +#define IDSRV_HEAD_PPLL 1 +#define IDSRV_SCENESM 2 +#define IDSRV_HAIRSM 3 +#define IDSRV_HAIR_COLOR_TEXTURE 4 +#define IDSRV_NOISEMAP 5 +#define IDSRV_HAIR_THICKNESSES 6 +#define IDSRV_HAIR_VERTEX_POSITIONS 7 +#define IDSRV_HAIR_TANGENTS 8 +#define IDSRV_HAIR_TRANSFORMS 9 +#define IDSRV_HAIR_STRAND_TEX_COORDS 10 +#define IDSRV_HAIR_VERTEX_TEX_COORDS 11 +#define IDSRV_HAIR_VERTEX_COLORS 12 + +// Shortcut resources. +#define IDSRV_HAIR_FRAGMENT_DEPTHS 13 +#define IDSRV_HAIR_FRAGMENT_COLORS 14 +#define IDSRV_HAIR_ACCUM_INV_ALPHA 15 + +#define IDSRV_CONSTANTS_BUFFER 16 +#define IDSRV_ATOMIC_COUNTER_BUFFER 17 +#define IDSRV_NOISE_SAMPLER 18 +#define IDSRV_SHADOW_SAMPLER 19 + +#define IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS 20 +#define IDSRV_HAIR_VERTEX_INITIAL_POSITIONS 21 +#define IDSRV_HAIR_STRAND_TYPE 22 +#define IDSRV_HAIR_GLOBAL_ROTATION 23 +#define IDSRV_HAIR_LOCAL_REF_VEC 24 +#define IDSRV_HAIR_ROOT_OFFSET 25 +#define IDSRV_HAIR_LENGTH 26 +#define IDSRV_HEAD_TRANSFORM 27 + +#define MAX_VERTS_PER_STRAND 16 + +layout(std140, set = 0, binding = IDSRV_CONSTANTS_BUFFER) buffer Constants +{ + vec4 g_Wind; + vec4 g_Wind1; + vec4 g_Wind2; + vec4 g_Wind3; + + int g_NumLengthConstraintIterations; + int g_bCollision; + + float g_GravityMagnitude; + float g_TimeStep; + + float g_Damping0; + float g_StiffnessForLocalShapeMatching0; + float g_StiffnessForGlobalShapeMatching0; + float g_GlobalShapeMatchingEffectiveRange0; + + float g_Damping1; + float g_StiffnessForLocalShapeMatching1; + float g_StiffnessForGlobalShapeMatching1; + float g_GlobalShapeMatchingEffectiveRange1; + + float g_Damping2; + float g_StiffnessForLocalShapeMatching2; + float g_StiffnessForGlobalShapeMatching2; + float g_GlobalShapeMatchingEffectiveRange2; + + float g_Damping3; + float g_StiffnessForLocalShapeMatching3; + float g_StiffnessForGlobalShapeMatching3; + float g_GlobalShapeMatchingEffectiveRange3; + + uint g_NumOfStrandsPerThreadGroup; + uint g_NumFollowHairsPerGuideHair; + float g_TipSeparationFactor; + + int g_bWarp; + int g_NumLocalShapeMatchingIterations; +}; + +layout(std140, set = 0, binding = IDSRV_HEAD_TRANSFORM) buffer HeadTransform +{ + mat4 g_ModelTransformForHead; + vec4 g_ModelRotateForHead; // quaternion + int bSingleHeadTransform; + float padding[3]; +}; + +bool IsMovable(vec4 particle) +{ + return particle.w > 0; +} diff --git a/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.frag b/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.frag new file mode 100644 index 0000000..5e9c914 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.frag @@ -0,0 +1,147 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" +#include "PackUnpack.glsl" +#include "ComputeShadow.glsl" +#include "ComputeHairShading.glsl" + +layout(set = 0, binding = IDSRV_HEAD_PPLL, r32ui) uniform restrict uimage2D PerPixelLinkedListHead; + +struct PerPixelListBucket +{ + float depth; + uint TangentAndCoverage; + uint next; +}; + +layout(std430, set = 0, binding = IDSRV_PPLL) buffer PerPixelLinkedList +{ + PerPixelListBucket PPLL[]; +}; + +#define K_BUFFER 8 + +struct FragmentElement { + float depth; + uint TangentAndCoverage; +}; + +layout(location = 0) out vec4 FragColor; + +//-------------------------------------------------------------------------------------- +// PS_KBuffer_Hair +// +// Second pass pixel shader which selects the nearest k fragments (k-buffer) and renders +// then in depth order for correct transparent blending of the hair. It uses the per-pixel +// linked list to access all of the layers of hair fragment so that the nearest k fragments +// are rendered at a higher quality than the remaining fragments. The lighting and shadows +// are calculated in screen space using the tangent and depth stored in the per-pixel linked +// list, similar to deferred shading. +// +//-------------------------------------------------------------------------------------- +void main() { + ivec2 iuv = ivec2(gl_FragCoord.xy); + uint ListBucketHead = imageLoad(PerPixelLinkedListHead, iuv).x; + if (ListBucketHead == -1) discard; + + FragmentElement kbuf[K_BUFFER]; + // Load first K_BUFFER element in temp array + int kbuf_size; + for (kbuf_size = 0; kbuf_size < K_BUFFER; kbuf_size++) + { + if (ListBucketHead == -1) + break; + kbuf[kbuf_size].depth = PPLL[ListBucketHead].depth; + kbuf[kbuf_size].TangentAndCoverage = PPLL[ListBucketHead].TangentAndCoverage; + ListBucketHead = PPLL[ListBucketHead].next; + } + + uint ListBucketId = ListBucketHead; + vec4 result = vec4(0., 0., 0., 1.); + + uint numfrag = 0; + while (ListBucketId != -1) { + numfrag++; + float max_depth = 0.; + uint max_idx = 0; + for (int i = 0; i < kbuf_size; i++) + { + float d = kbuf[i].depth; + max_depth = max(max_depth, d); + max_idx = (max_depth == d) ? i : max_idx; + } + + if (PPLL[ListBucketId].depth < max_depth) + { + float tmp = PPLL[ListBucketId].depth; + PPLL[ListBucketId].depth = kbuf[max_idx].depth; + kbuf[max_idx].depth = tmp; + uint tmpu = PPLL[ListBucketId].TangentAndCoverage; + PPLL[ListBucketId].TangentAndCoverage = kbuf[max_idx].TangentAndCoverage; + kbuf[max_idx].TangentAndCoverage = tmpu; + } + + float d = PPLL[ListBucketId].depth; + vec3 ndcPos = 2. * vec3(gl_FragCoord.x * g_WinSize.z, 1. - gl_FragCoord.y * g_WinSize.w, d) - 1.; + ndcPos.z = d; + vec4 Pos = g_mInvViewProj * vec4(ndcPos, 1.); + Pos /= Pos.w; + vec3 Tangent = GetTangent(PPLL[ListBucketId].TangentAndCoverage); + float FragmentAlpha = GetCoverage(PPLL[ListBucketId].TangentAndCoverage); + float amountOfLight = ComputeSimpleShadow(Pos.xyz, g_HairShadowAlpha); + vec3 FragmentColor = SimpleHairShading(Pos.xyz, Tangent, vec4(0.), amountOfLight); + result.xyz = result.xyz * (1. - FragmentAlpha) + FragmentAlpha * FragmentColor; + result.w *= (1. - FragmentAlpha); + + ListBucketId = PPLL[ListBucketId].next; + } + +//#define DEBUG +#ifdef DEBUG + result = vec4(0., 1., 0., 0.); + if (numfrag > 32) result.xyz = vec3(1., 1., 0.); + if (numfrag > 64) result.xyz = vec3(1., .5, 0.); + if (numfrag > 128) result.xyz = vec3(1., 0., 0.); + FragColor = result; + return; +#endif + + uint reverse = 0; + bool isSorted = false; + while (!isSorted) { + isSorted = true; + for (int i = 0; i < kbuf_size - 1; i++) + { + if (kbuf[i].depth < kbuf[i + 1].depth) { + isSorted = false; + float tmp = kbuf[i].depth; + kbuf[i].depth = kbuf[i + 1].depth; + kbuf[i + 1].depth = tmp; + uint ttmp = kbuf[i].TangentAndCoverage; + kbuf[i].TangentAndCoverage = kbuf[i + 1].TangentAndCoverage; + kbuf[i + 1].TangentAndCoverage = ttmp; + reverse++; + } + } + } + + for (int i = 0; i < kbuf_size; i++) + { + float d = kbuf[i].depth; + vec3 ndcPos = 2. * vec3(gl_FragCoord.x * g_WinSize.z, 1. - gl_FragCoord.y * g_WinSize.w, d) - 1.; + ndcPos.z = d; + vec4 Pos = g_mInvViewProj * vec4(ndcPos, 1.); + Pos /= Pos.w; + + vec3 Tangent = GetTangent(kbuf[i].TangentAndCoverage); + float FragmentAlpha = GetCoverage(kbuf[i].TangentAndCoverage); + float amountOfLight = ComputeShadow(Pos.xyz, g_HairShadowAlpha); + vec3 FragmentColor = ComputeHairShading(Pos.xyz, Tangent, vec4(0.), amountOfLight, g_MatBaseColor.xyz); + + result.xyz = result.xyz * (1. - FragmentAlpha) + FragmentAlpha * FragmentColor; + result.w *= (1. - FragmentAlpha); + } + FragColor = result; +} \ No newline at end of file diff --git a/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert b/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert new file mode 100644 index 0000000..946d661 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert @@ -0,0 +1,20 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + + +layout(location = 0) in vec4 Position; +layout(location = 1) in vec4 Texcoord; + +layout(location = 0) out vec2 vTex; + +out gl_PerVertex { + vec4 gl_Position; +}; + + +void main() +{ + gl_Position = vec4(Position.xyz, 1.0); + vTex = Texcoord.xy; +} diff --git a/amd_tressfx_vulkan/src/Shaders/TressFxRender.frag b/amd_tressfx_vulkan/src/Shaders/TressFxRender.frag new file mode 100644 index 0000000..27325e0 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/TressFxRender.frag @@ -0,0 +1,67 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "RenderConfig.glsl" +#include "PackUnpack.glsl" +#include "ComputeCoverage.glsl" + +layout(set = 0, binding = IDSRV_ATOMIC_COUNTER_BUFFER) buffer AtomicBuffer +{ + uint PixelCount; +}; +layout(set = 0, binding = IDSRV_HEAD_PPLL, r32ui) uniform restrict uimage2D PerPixelLinkedListHead; + +struct PerPixelListBucket +{ + float depth; + uint TangentAndCoverage; + uint next; +}; + +layout(std430, set = 0, binding = IDSRV_PPLL) buffer PerPixelLinkedList +{ + PerPixelListBucket PPLL[]; +}; +layout(early_fragment_tests) in; + +void StoreFragments_Hair(vec2 FragCoordXY, vec3 Tangent, float Coverage, float depth) +{ + uint pixel_id = atomicAdd(PixelCount, 1); + int pxid = int(pixel_id); + ivec2 iuv = ivec2(FragCoordXY); + uint tmp = imageAtomicExchange(PerPixelLinkedListHead, iuv, pixel_id); + PPLL[pxid].depth = depth; + PPLL[pxid].TangentAndCoverage = PackTangentAndCoverage(Tangent.xyz, Coverage); + PPLL[pxid].next = tmp; +} + +layout(location = 0) in float depth; +layout(location = 1) in vec4 p0p1; +layout(location = 2) in vec4 tangent; + + +//-------------------------------------------------------------------------------------- +// PS_ABuffer_Hair +// +// This is the first pass pixel shader for rendering hair geometry into an A-buffer. +// It keeps all of the layers of the transparent hair in a UAV per-pixel linked list. +// +// Coverage for antialiasing is calculated and stored in the linked list along with geometry +// and attributes necessary for lighting and shadows which are calculated in a subsequent +// pass by rendering a full screen quad. +// +//-------------------------------------------------------------------------------------- +void main() { + // Render AA Line, calculate pixel coverage + vec4 proj_pos = vec4(2 * gl_FragCoord.x * g_WinSize.z - 1., + 1. - 2 * gl_FragCoord.y * g_WinSize.w, + 1., 1.); + vec4 original_pos = g_mInvViewProj * proj_pos; // Not used ?? + + float coverage = (g_bUseCoverage != 0) ? ComputeCoverage(p0p1.xy, p0p1.zw, proj_pos.xy) : 1.; + + coverage *= g_FiberAlpha; + if (coverage > g_alphaThreshold) + StoreFragments_Hair(gl_FragCoord.xy, tangent.xyz, coverage, gl_FragCoord.z); +} diff --git a/amd_tressfx_vulkan/src/Shaders/UpdateFollowHair.comp b/amd_tressfx_vulkan/src/Shaders/UpdateFollowHair.comp new file mode 100644 index 0000000..fbc95a8 --- /dev/null +++ b/amd_tressfx_vulkan/src/Shaders/UpdateFollowHair.comp @@ -0,0 +1,37 @@ +#version 450 + +#include "SimulationConfig.glsl" + +layout (local_size_x = THREAD_GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; + +layout(std430, set = 1, binding = IDSRV_HAIR_VERTEX_POSITIONS) buffer writeablePositions +{ + vec4 g_HairVertexPositions[]; +}; +layout(set = 1, binding = IDSRV_HAIR_ROOT_OFFSET) uniform samplerBuffer g_FollowHairRootOffset; + +#include "IndicesComputations.glsl" + +shared vec4 sharedPos[THREAD_GROUP_SIZE]; + +// One thread computes one vertex. +void main() +{ + uint globalStrandIndex, localStrandIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType; + int globalVertexIndex; + CalcIndicesInVertexLevelMaster(gl_LocalInvocationID.x, gl_WorkGroupID.x, globalStrandIndex, localStrandIndex, globalVertexIndex, localVertexIndex, numVerticesInTheStrand, indexForSharedMem, strandType); + + sharedPos[indexForSharedMem] = g_HairVertexPositions[globalVertexIndex]; + barrier(); + + for (int i = 0; i < g_NumFollowHairsPerGuideHair; i++) + { + int globalFollowVertexIndex = globalVertexIndex + int(numVerticesInTheStrand) * (i + 1); + int globalFollowStrandIndex = int(globalStrandIndex) + i + 1; + float factor = g_TipSeparationFactor * (float(localVertexIndex) / float(numVerticesInTheStrand)) + 1.0f; + vec3 followPos = sharedPos[indexForSharedMem].xyz + factor * texelFetch(g_FollowHairRootOffset, globalFollowStrandIndex).xyz; + g_HairVertexPositions[globalFollowVertexIndex].xyz = followPos; + } + + return; +} diff --git a/amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp b/amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp new file mode 100644 index 0000000..12b5b5a --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp @@ -0,0 +1,1147 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXMesh.cpp +// +// Hair mesh code +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#include "TressFXMeshVulkan.h" +#include "AMD_Types.h" +#include "UtilVulkan.h" + +#include +#include + +#ifndef AMD_V_RETURN +#define AMD_V_RETURN(x) \ + { \ + vr = (x); \ + if (vr != VK_SUCCESS) \ + { \ + return vr; \ + } \ + } +#endif + +using namespace std; +using namespace DirectX; + +namespace AMD +{ + +//-------------------------------------------------------------------------------------- +// +// Constructor +// +// Used for initializing member variables to default values. +//-------------------------------------------------------------------------------------- +TressFXMesh::TressFXMesh(void) + : m_pIndexBuffer(NULL), m_pTriangleIndexBuffer(NULL), m_pThicknessCoeffsBuffer(NULL), + m_pTriangleIndexMemory(NULL), m_pThicknessCoeffsView(NULL) +{ + m_HairVertexPositionsBuffer = NULL; + m_HairVertexPositionsView = NULL; + m_HairVertexPositionsPrevBuffer = NULL; + + m_HairStrandTypeBuffer = NULL; + m_HairStrandTypeView = NULL; + + m_HairVertexPositionsView = NULL; + m_HairVertexPositionsPrevView = NULL; + + m_HairLengthBuffer = NULL; + m_HairRestLengthSRV = NULL; + + m_InitialHairPositionsBuffer = NULL; + m_InitialHairPositionsView = NULL; + + m_HairVertexTangentsBuffer = NULL; + m_HairVertexTangentsView = NULL; + + m_HairRefVectorsBuffer = NULL; + m_HairRefVecsInLocalFrameView = NULL; + + m_FollowHairRootOffsetBuffer = NULL; + m_FollowHairRootOffsetView = NULL; + + m_GlobalRotationsBuffer = NULL; + m_GlobalRotationsView = NULL; + + m_LocalRotationsBuffer = NULL; + m_LocalRotationsView = NULL; + + m_HairAsset.m_pHairStrandType = NULL; + m_HairAsset.m_pRefVectors = NULL; + m_HairAsset.m_pTriangleVertices = NULL; + m_HairAsset.m_pGlobalRotations = NULL; + m_HairAsset.m_pLocalRotations = NULL; + m_HairAsset.m_pVertices = NULL; + m_HairAsset.m_pTangents = NULL; + m_HairAsset.m_pThicknessCoeffs = NULL; + m_HairAsset.m_pRestLengths = NULL; + m_HairAsset.m_pFollowRootOffset = NULL; + + m_HairAsset.m_NumFollowHairsPerGuideHair = 4; + m_HairAsset.m_NumGuideHairStrands = 0; + m_HairAsset.m_NumOfVerticesInStrand = 2; + + m_HairSkinMappingBuffer = NULL; + m_HairTransformsBuffer = NULL; + m_HairSkinMappingView = NULL; + m_HairTransformsView = NULL; + m_pStrandTexCoordBuffer = NULL; + m_pStrandTexCoordView = NULL; +} + +//-------------------------------------------------------------------------------------- +// +// Destructor +// +//-------------------------------------------------------------------------------------- +TressFXMesh::~TressFXMesh(void) { OnDestroy(); } + +//-------------------------------------------------------------------------------------- +// +// OnCreate +// +// Called to create a hair mesh. This function creates the VK resources +// and stores the hair data into these resources. +// +//-------------------------------------------------------------------------------------- +VkResult TressFXMesh::OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, + TressFX_SceneMesh *sceneMesh, VkImageView pTexture, + uint32_t texture_buffer_memory_index, + VkCommandBuffer upload_cmd_buffer, VkBuffer scratchBuffer, + VkDeviceMemory scratchMemory, + VkDescriptorSetLayout GlobalConstraintsSetLayout, + VkDescriptorSetLayout LocalConstraintsSetLayout, + VkDescriptorSetLayout LenghtWindCollisionSetLayout, + VkDescriptorSetLayout PrepareFollowHairSetLayout, + VkDescriptorSetLayout UpdateFollowHaitSetLayout, + VkDescriptorSetLayout computeTangentSetLayout, + VkDescriptorSetLayout Pass1SetLayout, + VkDescriptorSetLayout ShadowSetLayout) +{ + VkResult vr; + + // load the binary file + if (!Deserialize(pHairBlob)) + { + return VK_ERROR_INITIALIZATION_FAILED; + } + + size_t sizeToUpload = m_HairAsset.m_NumTotalHairVertices * sizeof(float); + + void *uploadBuffer; + size_t offsetInUploadBuffer = 0; + vkMapMemory(pvkDevice, scratchMemory, 0, sizeToUpload, 0, &uploadBuffer); + + // thickness coeff buffer + { + VkBufferCreateInfo bd{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bd.usage = + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + bd.size = sizeof(float) * m_HairAsset.m_NumTotalHairVertices; + + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pThicknessCoeffsBuffer)); + m_pThicknessCoeffsMemory = allocBufferMemory(pvkDevice, m_pThicknessCoeffsBuffer, + texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pThicknessCoeffs, m_pThicknessCoeffsBuffer, + offsetInUploadBuffer, bd.size); + } + + // thickness coeff buffer srv + { + VkBufferViewCreateInfo SRVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + SRVDesc.format = VK_FORMAT_R32_SFLOAT; + SRVDesc.range = m_HairAsset.m_NumTotalHairVertices * sizeof(float); + SRVDesc.buffer = m_pThicknessCoeffsBuffer; + + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &SRVDesc, nullptr, &m_pThicknessCoeffsView)); + } + + //----------------------------------- + // Index buffer (lines and triangles) + //----------------------------------- + + // Line index buffer + m_TotalIndexCount = (int)m_HairAsset.m_LineIndices.size(); + + VkBufferCreateInfo bd{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bd.size = (UINT)(sizeof(unsigned int) * m_HairAsset.m_LineIndices.size()); + bd.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pIndexBuffer)); + m_pIndexMemory = + allocBufferMemory(pvkDevice, m_pIndexBuffer, texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + &m_HairAsset.m_LineIndices[0], m_pIndexBuffer, offsetInUploadBuffer, + bd.size); + + // Triangle index buffer + m_TotalTriangleIndexCount = (int)m_HairAsset.m_TriangleIndices.size(); + bd.size = (UINT)(sizeof(unsigned int) * m_HairAsset.m_TriangleIndices.size()); + + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pTriangleIndexBuffer)); + m_pTriangleIndexMemory = + allocBufferMemory(pvkDevice, m_pTriangleIndexBuffer, texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + &m_HairAsset.m_TriangleIndices[0], m_pTriangleIndexBuffer, + offsetInUploadBuffer, bd.size); + + vkUnmapMemory(pvkDevice, scratchMemory); + + m_pHairTextureSRV = pTexture; + + vr = CreateBufferAndViews(pvkDevice, sceneMesh, texture_buffer_memory_index, + upload_cmd_buffer, scratchBuffer, scratchMemory, + offsetInUploadBuffer); + vr = + AllocateDescriptorsSets(pvkDevice, GlobalConstraintsSetLayout, + LocalConstraintsSetLayout, LenghtWindCollisionSetLayout, + PrepareFollowHairSetLayout, UpdateFollowHaitSetLayout, + computeTangentSetLayout, Pass1SetLayout, ShadowSetLayout); + + VkBufferMemoryBarrier bufferBarrier[] = { + getBufferBarrier(m_pThicknessCoeffsBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_pIndexBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_INDEX_READ_BIT), + getBufferBarrier(m_pTriangleIndexBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_INDEX_READ_BIT), + getBufferBarrier(m_HairStrandTypeBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_InitialHairPositionsBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_HairLengthBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_HairRefVectorsBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_FollowHairRootOffsetBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_GlobalRotationsBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_LocalRotationsBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT), + }; + + vkCmdPipelineBarrier(upload_cmd_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(bufferBarrier), bufferBarrier, 0, nullptr); + + DestroyAsset(); + + return vr; +} + +//-------------------------------------------------------------------------------------- +// +// CreateBufferAndViews +// +// Called by the OnCreate function to create the VK resources +// +//-------------------------------------------------------------------------------------- +VkResult TressFXMesh::CreateBufferAndViews( + VkDevice pvkDevice, TressFX_SceneMesh *sceneMesh, + uint32_t texture_buffer_memory_index, VkCommandBuffer upload_cmd_buffer, + VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, size_t &offsetInUploadBuffer) +{ + VkResult vr; + m_pvkDevice = pvkDevice; + size_t sizeToUpload = + // m_HairStrandTypeSRV + m_HairAsset.m_NumTotalHairStrands * sizeof(int) + + // m_InitialHairPositionsSRV + m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4) + + // m_HairVertexPositionsUAB + 2 * m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4) + + // m_HairVertexTangentsUAB + m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4) + + // m_HairRestLengthSRV + m_HairAsset.m_NumTotalHairVertices * sizeof(float) + + // m_HairRefVecsInLocalFrameSRV + m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4) + + // m_FollowHairRootOffsetSRV + m_HairAsset.m_NumTotalHairStrands * sizeof(XMFLOAT4) + + // m_GlobalRotationsUAB + m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4) + + // m_LocalRotationsUAB + m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4) + + // m_pStrandTexCoordBuffer + m_HairAsset.m_NumTotalHairStrands * sizeof(float) * 2; + + void *uploadBuffer; + vkMapMemory(pvkDevice, scratchMemory, 0, sizeToUpload, 0, &uploadBuffer); + + //-------------------------------- + // m_HairStrandTypeSRV + //-------------------------------- + { + VkBufferCreateInfo bufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDesc.usage = + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + bufferDesc.size = m_HairAsset.m_NumTotalHairStrands * sizeof(int); + // AMD_SAFE_RELEASE(m_HairStrandTypeBuffer); + AMD_V_RETURN( + vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_HairStrandTypeBuffer)); + m_HairStrandTypeMemory = allocBufferMemory(pvkDevice, m_HairStrandTypeBuffer, + texture_buffer_memory_index); + + VkBufferViewCreateInfo SRVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + SRVDesc.format = VK_FORMAT_R32_SINT; + SRVDesc.range = m_HairAsset.m_NumTotalHairStrands * sizeof(int32_t); + SRVDesc.buffer = m_HairStrandTypeBuffer; + // AMD_SAFE_RELEASE(m_HairStrandTypeSRV); + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &SRVDesc, nullptr, &m_HairStrandTypeView)); + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pHairStrandType, m_HairStrandTypeBuffer, + offsetInUploadBuffer, bufferDesc.size); + } + + //--------------------------------- + // m_InitialHairPositionsSRV + // m_InitialHairPositionsUAV + //--------------------------------- + { + VkBufferCreateInfo bufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDesc.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + bufferDesc.usage = + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_InitialHairPositionsBuffer); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + &m_InitialHairPositionsBuffer)); + m_InitialHairPositionsMemory = allocBufferMemory( + pvkDevice, m_InitialHairPositionsBuffer, texture_buffer_memory_index); + + VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + desc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); + desc.buffer = m_InitialHairPositionsBuffer; + // AMD_SAFE_RELEASE(m_InitialHairPositionsSRV); + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &desc, nullptr, &m_InitialHairPositionsView)); + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pVertices, m_InitialHairPositionsBuffer, + offsetInUploadBuffer, bufferDesc.size); + } + + // ------------------------ + // m_HairVertexPositionsUAB + //------------------------- + { + VkBufferCreateInfo bufferDescUA{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDescUA.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + bufferDescUA.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_HairVertexPositionsUAB); + // AMD_SAFE_RELEASE(m_HairVertexPositionsPrevUAB); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + &m_HairVertexPositionsBuffer)); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + &m_HairVertexPositionsPrevBuffer)); + + m_HairVertexPositionsMemory = allocBufferMemory( + pvkDevice, m_HairVertexPositionsBuffer, texture_buffer_memory_index); + m_HairVertexPositionsPrevMemory = allocBufferMemory( + pvkDevice, m_HairVertexPositionsPrevBuffer, texture_buffer_memory_index); + // TODO: We could write only once to uploadBuffer and share data between + // the + // 3 buffers + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pVertices, m_HairVertexPositionsBuffer, + offsetInUploadBuffer, bufferDescUA.size); + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pVertices, m_HairVertexPositionsPrevBuffer, + offsetInUploadBuffer, bufferDescUA.size); + } + + // ----------------------------- + // m_HairVertexTangentsUAB + //------------------------------ + { + VkBufferCreateInfo bufferDescUA{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDescUA.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + bufferDescUA.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_HairVertexTangentsUAB); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + &m_HairVertexTangentsBuffer)); + m_HairVertexTangentsMemory = allocBufferMemory( + pvkDevice, m_HairVertexTangentsBuffer, texture_buffer_memory_index); + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pTangents, m_HairVertexTangentsBuffer, + offsetInUploadBuffer, bufferDescUA.size); + } + + //----------------------- + // m_HairVertexPositionsView + //----------------------- + { + VkBufferViewCreateInfo sbSRVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + sbSRVDesc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); + sbSRVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + sbSRVDesc.buffer = m_HairVertexPositionsBuffer; + // AMD_SAFE_RELEASE(m_HairVertexPositionsSRV); + AMD_V_RETURN(vkCreateBufferView(pvkDevice, &sbSRVDesc, nullptr, + &m_HairVertexPositionsView)); + } + + //----------------------- + // m_HairVertexTangentsView + //----------------------- + { + VkBufferViewCreateInfo sbSRVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + sbSRVDesc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); + sbSRVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + sbSRVDesc.buffer = m_HairVertexTangentsBuffer; + // AMD_SAFE_RELEASE(m_HairVertexTangentsSRV); + AMD_V_RETURN(vkCreateBufferView(pvkDevice, &sbSRVDesc, nullptr, + &m_HairVertexTangentsView)); + } + + //----------------------- + // m_HairVertexPositionsView + //----------------------- + { + VkBufferViewCreateInfo sbUAVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + sbUAVDesc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); + sbUAVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + sbUAVDesc.buffer = m_HairVertexPositionsPrevBuffer; + // AMD_SAFE_RELEASE(m_HairVertexPositionsUAV); + // AMD_SAFE_RELEASE(m_HairVertexPositionsPrevUAV); + AMD_V_RETURN(vkCreateBufferView(pvkDevice, &sbUAVDesc, nullptr, + &m_HairVertexPositionsPrevView)); + } + + //--------------------------- + // m_HairRestLengthSRV + //--------------------------- + { + VkBufferCreateInfo bufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDesc.size = m_HairAsset.m_NumTotalHairVertices * sizeof(float); + bufferDesc.usage = + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_HairLengthBuffer); + AMD_V_RETURN( + vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_HairLengthBuffer)); + m_HairLengthMemory = + allocBufferMemory(pvkDevice, m_HairLengthBuffer, texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pRestLengths, m_HairLengthBuffer, + offsetInUploadBuffer, bufferDesc.size); + + VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + desc.format = VK_FORMAT_R32_SFLOAT; + desc.range = m_HairAsset.m_NumTotalHairVertices * sizeof(float); + desc.buffer = m_HairLengthBuffer; + // AMD_SAFE_RELEASE(m_HairRestLengthSRV); + AMD_V_RETURN(vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairRestLengthSRV)); + } + + //----------------------------------- + // m_HairRefVecsInLocalFrameSRV + //----------------------------------- + { + + VkBufferCreateInfo bufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDesc.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + bufferDesc.usage = + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_HairRefVectorsBuffer); + AMD_V_RETURN( + vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_HairRefVectorsBuffer)); + m_HairRefVectorsMemory = allocBufferMemory(pvkDevice, m_HairRefVectorsBuffer, + texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pRefVectors, m_HairRefVectorsBuffer, + offsetInUploadBuffer, bufferDesc.size); + + VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + desc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); + desc.buffer = m_HairRefVectorsBuffer; + // AMD_SAFE_RELEASE(m_HairRefVecsInLocalFrameSRV); + AMD_V_RETURN(vkCreateBufferView(pvkDevice, &desc, nullptr, + &m_HairRefVecsInLocalFrameView)); + } + + //----------------------------------- + // m_FollowHairRootOffsetSRV + //----------------------------------- + { + VkBufferCreateInfo bufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDesc.size = m_HairAsset.m_NumTotalHairStrands * sizeof(XMFLOAT4); + bufferDesc.usage = + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_FollowHairRootOffsetBuffer); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + &m_FollowHairRootOffsetBuffer)); + m_FollowHairRootOffsetMemory = allocBufferMemory( + pvkDevice, m_FollowHairRootOffsetBuffer, texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pFollowRootOffset, m_FollowHairRootOffsetBuffer, + offsetInUploadBuffer, bufferDesc.size); + + VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + desc.range = m_HairAsset.m_NumTotalHairStrands * 4 * sizeof(float); + desc.buffer = m_FollowHairRootOffsetBuffer; + // AMD_SAFE_RELEASE(m_FollowHairRootOffsetSRV); + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &desc, nullptr, &m_FollowHairRootOffsetView)); + } + + // -------------------------------------------- + // m_GlobalRotationsUAB & m_GlobalRotationsUAV + //--------------------------------------------- + { + VkBufferCreateInfo bufferDescUA{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDescUA.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + bufferDescUA.usage = + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_GlobalRotationsUAB); + AMD_V_RETURN( + vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_GlobalRotationsBuffer)); + m_GlobalRotationsMemory = allocBufferMemory(pvkDevice, m_GlobalRotationsBuffer, + texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pGlobalRotations, m_GlobalRotationsBuffer, + offsetInUploadBuffer, bufferDescUA.size); + + VkBufferViewCreateInfo sbUAVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + sbUAVDesc.range = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + sbUAVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + sbUAVDesc.buffer = m_GlobalRotationsBuffer; + // AMD_SAFE_RELEASE(m_GlobalRotationsUAV); + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &sbUAVDesc, nullptr, &m_GlobalRotationsView)); + } + + // -------------------------------------------- + // m_LocalRotationsUAB & m_LocalRotationsUAV + //--------------------------------------------- + { + VkBufferCreateInfo bufferDescUA{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDescUA.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + bufferDescUA.usage = + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_LocalRotationsUAB); + AMD_V_RETURN( + vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_LocalRotationsBuffer)); + m_LocalRotationsMemory = allocBufferMemory(pvkDevice, m_LocalRotationsBuffer, + texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pLocalRotations, m_LocalRotationsBuffer, + offsetInUploadBuffer, bufferDescUA.size); + + VkBufferViewCreateInfo sbUAVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + sbUAVDesc.range = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); + sbUAVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + sbUAVDesc.buffer = m_LocalRotationsBuffer; + // AMD_SAFE_RELEASE(m_LocalRotationsUAV); + // AMD_V_RETURN( + // vkCreateBufferView(pvkDevice, &sbUAVDesc, nullptr, + // &m_LocalRotationsView)); + } + + if (m_HairAsset.m_pMapping != NULL) + { + // ----------------------------------------------- + // m_HairSkinMappingBuffer & m_HairSkinMappingSRV + //------------------------------------------------ + { + // D3D11_SUBRESOURCE_DATA initialData; + + // "flatten" the mapping for one big vertex array + for (int i = 0; i < m_HairAsset.m_NumTotalHairStrands; i++) + { + m_HairAsset.m_pMapping[i].triangle += + sceneMesh->meshOffsets[m_HairAsset.m_pMapping[i].mesh]; + } + + // initialData.pSysMem = m_HairAsset.m_pMapping; + VkBufferCreateInfo bufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDesc.size = + m_HairAsset.m_NumTotalHairStrands * sizeof(HairToTriangleMapping); + bufferDesc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + // AMD_SAFE_RELEASE(m_HairSkinMappingBuffer); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + &m_HairSkinMappingBuffer)); + + VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + desc.format = VK_FORMAT_UNDEFINED; + desc.range = + m_HairAsset.m_NumTotalHairStrands * sizeof(HairToTriangleMapping); + desc.buffer = m_HairSkinMappingBuffer; + // AMD_SAFE_RELEASE(m_HairSkinMappingSRV); + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairSkinMappingView)); + } + + // -------------------------------------------- + // m_HairTransformsBuffer & m_HairTransformsUAV + //--------------------------------------------- + { + TressFX_HairTransform *pTransforms = + new TressFX_HairTransform[m_HairAsset.m_NumTotalHairStrands]; + for (int i = 0; i < m_HairAsset.m_NumTotalHairStrands; i++) + { + for (int j = 0; j < 4; j++) + { + for (int k = 0; k < 4; k++) + { + if (j == k) + { + pTransforms[i].matrix[j][k] = 1.0f; + } + else + { + pTransforms[i].matrix[j][k] = 0.0f; + } + } + if (j == 3) + { + pTransforms[i].quaternion[j] = 1.0f; + } + else + { + pTransforms[i].quaternion[j] = 0.0f; + } + } + } + + // D3D11_SUBRESOURCE_DATA initialData; + // initialData.pSysMem = (void *)pTransforms; + + VkBufferCreateInfo bufferDescUA{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDescUA.size = + m_HairAsset.m_NumTotalHairStrands * sizeof(TressFX_HairTransform); + bufferDescUA.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + // AMD_SAFE_RELEASE(m_HairTransformsBuffer); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + &m_HairTransformsBuffer)); + + VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + desc.range = + m_HairAsset.m_NumTotalHairStrands * sizeof(TressFX_HairTransform); + desc.format = VK_FORMAT_UNDEFINED; + desc.buffer = m_HairTransformsBuffer; + // AMD_SAFE_RELEASE(m_HairTransformsSRV); + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairTransformsView)); + + AMD_SAFE_DELETE_ARRAY(pTransforms); + } + } + + if (m_HairAsset.m_pStrandTexCoords != NULL) + { + // ----------------------------------------------- + // m_pStrandTexCoordBuffer & m_pStrandTexCoordSRV + //------------------------------------------------ + { + VkBufferCreateInfo bufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bufferDesc.size = m_HairAsset.m_NumTotalHairStrands * sizeof(float) * 2; + bufferDesc.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT; + // AMD_SAFE_RELEASE(m_pStrandTexCoordBuffer); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + &m_pStrandTexCoordBuffer)); + m_pStrandTexCoordMemory = allocBufferMemory( + pvkDevice, m_pStrandTexCoordBuffer, texture_buffer_memory_index); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + m_HairAsset.m_pStrandTexCoords, m_pStrandTexCoordBuffer, + offsetInUploadBuffer, bufferDesc.size); + + VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + desc.format = VK_FORMAT_R32G32_SFLOAT; + desc.range = m_HairAsset.m_NumTotalHairStrands * sizeof(float) * 2; + desc.buffer = m_pStrandTexCoordBuffer; + // AMD_SAFE_RELEASE(m_pStrandTexCoordSRV); + AMD_V_RETURN( + vkCreateBufferView(pvkDevice, &desc, nullptr, &m_pStrandTexCoordView)); + } + } + vkUnmapMemory(pvkDevice, scratchMemory); + return VK_SUCCESS; +} + +VkResult TressFXMesh::AllocateDescriptorsSets( + VkDevice pvkDevice, VkDescriptorSetLayout GlobalConstraintsSetLayout, + VkDescriptorSetLayout LocalConstraintsSetLayout, + VkDescriptorSetLayout LenghtWindTangentSetLayout, + VkDescriptorSetLayout PrepareFollowHairSetLayout, + VkDescriptorSetLayout UpdateFollowHaitSetLayout, + VkDescriptorSetLayout computeTangentSetLayout, VkDescriptorSetLayout Pass1SetLayout, + VkDescriptorSetLayout ShadowSetLayout) +{ + VkDescriptorPoolSize poolSizes[] = {{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 17}, + {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 11}}; + VkDescriptorPoolCreateInfo info{VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; + info.maxSets = 8; + info.poolSizeCount = AMD_ARRAY_SIZE(poolSizes); + info.pPoolSizes = poolSizes; + VkResult vr; + AMD_V_RETURN(vkCreateDescriptorPool(pvkDevice, &info, nullptr, &m_descriptorPool)); + + const VkDescriptorSetLayout setLayouts[] = {GlobalConstraintsSetLayout, + LocalConstraintsSetLayout, + LenghtWindTangentSetLayout, + PrepareFollowHairSetLayout, + UpdateFollowHaitSetLayout, + computeTangentSetLayout, + Pass1SetLayout, + ShadowSetLayout}; + VkDescriptorSetAllocateInfo allocateInfo{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + allocateInfo.descriptorPool = m_descriptorPool; + allocateInfo.descriptorSetCount = AMD_ARRAY_SIZE(setLayouts); + allocateInfo.pSetLayouts = setLayouts; + + VkDescriptorSet sets[AMD_ARRAY_SIZE(setLayouts)]{}; + + AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &allocateInfo, sets)); + m_GlobalConstraintsSet = sets[0]; + m_LocalConstraintsSet = sets[1]; + m_LenghtWindCollisionSet = sets[2]; + m_PrepareFollowHairSet = sets[3]; + m_UpdateFollowHairSet = sets[4]; + m_ComputeTangentSet = sets[5]; + m_pass1_set = sets[6]; + m_shadow_pass_set = sets[7]; + + VkDescriptorBufferInfo positionInfo{m_HairVertexPositionsBuffer, 0, + m_HairAsset.m_NumTotalHairVertices * 4 * + sizeof(float)}; + VkDescriptorBufferInfo prevPositionInfo{m_HairVertexPositionsPrevBuffer, 0, + m_HairAsset.m_NumTotalHairVertices * 4 * + sizeof(float)}; + VkDescriptorBufferInfo tangentInfo{m_HairVertexTangentsBuffer, 0, + m_HairAsset.m_NumTotalHairVertices * 4 * + sizeof(float)}; + + VkWriteDescriptorSet writeDescriptorSets[] = { + getWriteDescriptor(m_GlobalConstraintsSet, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &positionInfo), + getWriteDescriptor(m_GlobalConstraintsSet, IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &prevPositionInfo), + getWriteDescriptor(m_GlobalConstraintsSet, IDSRV_HAIR_VERTEX_INITIAL_POSITIONS, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_InitialHairPositionsView), + getWriteDescriptor(m_GlobalConstraintsSet, IDSRV_HAIR_STRAND_TYPE, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairStrandTypeView), + + getWriteDescriptor(m_LocalConstraintsSet, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &positionInfo), + getWriteDescriptor(m_LocalConstraintsSet, IDSRV_HAIR_STRAND_TYPE, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairStrandTypeView), + getWriteDescriptor(m_LocalConstraintsSet, IDSRV_HAIR_GLOBAL_ROTATION, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_GlobalRotationsView), + getWriteDescriptor(m_LocalConstraintsSet, IDSRV_HAIR_LOCAL_REF_VEC, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairRefVecsInLocalFrameView), + + getWriteDescriptor(m_ComputeTangentSet, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairVertexPositionsView), + getWriteDescriptor(m_ComputeTangentSet, IDSRV_HAIR_STRAND_TYPE, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairStrandTypeView), + getWriteDescriptor(m_ComputeTangentSet, IDSRV_HAIR_TANGENTS, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &tangentInfo), + + getWriteDescriptor(m_LenghtWindCollisionSet, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &positionInfo), + getWriteDescriptor(m_LenghtWindCollisionSet, IDSRV_HAIR_STRAND_TYPE, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairStrandTypeView), + getWriteDescriptor(m_LenghtWindCollisionSet, IDSRV_HAIR_LENGTH, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, &m_HairRestLengthSRV), + + getWriteDescriptor(m_PrepareFollowHairSet, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairVertexPositionsView), + getWriteDescriptor(m_PrepareFollowHairSet, IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &prevPositionInfo), + getWriteDescriptor(m_PrepareFollowHairSet, IDSRV_HAIR_STRAND_TYPE, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairStrandTypeView), + + getWriteDescriptor(m_UpdateFollowHairSet, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &positionInfo), + getWriteDescriptor(m_UpdateFollowHairSet, IDSRV_HAIR_STRAND_TYPE, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairStrandTypeView), + getWriteDescriptor(m_UpdateFollowHairSet, IDSRV_HAIR_ROOT_OFFSET, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_FollowHairRootOffsetView), + + getWriteDescriptor(m_pass1_set, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairVertexPositionsView), + getWriteDescriptor(m_pass1_set, IDSRV_HAIR_TANGENTS, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairVertexTangentsView), + getWriteDescriptor(m_pass1_set, IDSRV_HAIR_THICKNESSES, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_pThicknessCoeffsView), + + getWriteDescriptor(m_shadow_pass_set, IDSRV_HAIR_VERTEX_POSITIONS, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + &m_HairVertexPositionsView), + }; + + vkUpdateDescriptorSets(pvkDevice, AMD_ARRAY_SIZE(writeDescriptorSets), + writeDescriptorSets, 0, nullptr); + + return VK_SUCCESS; +} + +#define AMD_SAFE_RELEASE(object, releaseFunction, device) \ + if (object != nullptr) \ + releaseFunction(device, object, nullptr); + +//-------------------------------------------------------------------------------------- +// +// OnDestroy +// +// Called when the D3D device is being destroyed. +// +//-------------------------------------------------------------------------------------- +void TressFXMesh::OnDestroy() +{ + AMD_SAFE_RELEASE(m_pTriangleIndexBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_pTriangleIndexMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_pIndexBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_pIndexMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_pThicknessCoeffsView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_pThicknessCoeffsBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_pThicknessCoeffsMemory, vkFreeMemory, m_pvkDevice); + + // compute shader variables + AMD_SAFE_RELEASE(m_HairVertexPositionsView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexPositionsBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexPositionsMemory, vkFreeMemory, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexPositionsPrevView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexPositionsPrevBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexPositionsPrevMemory, vkFreeMemory, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexTangentsView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexTangentsBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairVertexTangentsMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_HairStrandTypeView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairStrandTypeBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairStrandTypeMemory, vkFreeMemory, m_pvkDevice); + + // vertex buffers + AMD_SAFE_RELEASE(m_HairRestLengthSRV, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairLengthBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairLengthMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_InitialHairPositionsView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_InitialHairPositionsBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_InitialHairPositionsMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_HairRefVecsInLocalFrameView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairRefVectorsBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairRefVectorsMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_FollowHairRootOffsetView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_FollowHairRootOffsetBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_FollowHairRootOffsetMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_GlobalRotationsView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_GlobalRotationsBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_GlobalRotationsMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_LocalRotationsView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_LocalRotationsBuffer, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_LocalRotationsMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_HairSkinMappingView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairSkinMappingBuffer, vkDestroyBuffer, m_pvkDevice); + // AMD_SAFE_RELEASE(m_HairSkinMappingMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_HairTransformsView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_HairTransformsBuffer, vkDestroyBuffer, m_pvkDevice); + // AMD_SAFE_RELEASE(m_HairTransformsMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_pStrandTexCoordView, vkDestroyBufferView, m_pvkDevice); + AMD_SAFE_RELEASE(m_pStrandTexCoordBuffer, vkDestroyBuffer, m_pvkDevice); + // AMD_SAFE_RELEASE(m_pStrandTexCoordMemory, vkFreeMemory, m_pvkDevice); + + // AMD_SAFE_RELEASE(m_pHairTextureSRV); + AMD_SAFE_RELEASE(m_descriptorPool, vkDestroyDescriptorPool, m_pvkDevice); + + DestroyAsset(); +} + +//-------------------------------------------------------------------------------------- +// +// Deserialize +// +// Converts the hair blob from a serialized stream to a TressFXAsset structure. +// +//-------------------------------------------------------------------------------------- +bool TressFXMesh::Deserialize(TressFX_HairBlob *pHairBlob) +{ + string str; + str.assign((char *)pHairBlob->pHair, pHairBlob->size); + stringbuf buffer; + buffer.str(str); + + buffer.sgetn((char *)&m_HairAsset.m_NumTotalHairVertices, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumTotalHairStrands, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumOfVerticesInStrand, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumGuideHairVertices, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumGuideHairStrands, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumFollowHairsPerGuideHair, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_TipSeparationFactor, sizeof(float)); + buffer.sgetn((char *)&m_HairAsset.m_NumPerStrandTexCoords, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumPerVertexColors, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumPerVertexTexCoords, sizeof(int)); + buffer.sgetn((char *)&m_HairAsset.m_NumHairToTriangleMappings, sizeof(int)); + + m_HairAsset.m_pHairStrandType = new int[m_HairAsset.m_NumTotalHairStrands]; + buffer.sgetn((char *)m_HairAsset.m_pHairStrandType, + m_HairAsset.m_NumTotalHairStrands * sizeof(int)); + + m_HairAsset.m_pRefVectors = new DirectX::XMFLOAT4[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pRefVectors, + m_HairAsset.m_NumTotalHairVertices * sizeof(DirectX::XMFLOAT4)); + + m_HairAsset.m_pGlobalRotations = + new DirectX::XMFLOAT4[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pGlobalRotations, + m_HairAsset.m_NumTotalHairVertices * sizeof(DirectX::XMFLOAT4)); + + m_HairAsset.m_pLocalRotations = + new DirectX::XMFLOAT4[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pLocalRotations, + m_HairAsset.m_NumTotalHairVertices * sizeof(DirectX::XMFLOAT4)); + + m_HairAsset.m_pVertices = new DirectX::XMFLOAT4[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pVertices, + m_HairAsset.m_NumTotalHairVertices * sizeof(DirectX::XMFLOAT4)); + + m_HairAsset.m_pTangents = new DirectX::XMFLOAT4[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pTangents, + m_HairAsset.m_NumTotalHairVertices * sizeof(DirectX::XMFLOAT4)); + + m_HairAsset.m_pTriangleVertices = + new StrandVertex[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pTriangleVertices, + m_HairAsset.m_NumTotalHairVertices * sizeof(StrandVertex)); + + m_HairAsset.m_pThicknessCoeffs = new float[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pThicknessCoeffs, + m_HairAsset.m_NumTotalHairVertices * sizeof(float)); + + m_HairAsset.m_pFollowRootOffset = + new DirectX::XMFLOAT4[m_HairAsset.m_NumTotalHairStrands]; + buffer.sgetn((char *)m_HairAsset.m_pFollowRootOffset, + m_HairAsset.m_NumTotalHairStrands * sizeof(XMFLOAT4)); + + m_HairAsset.m_pRestLengths = new float[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pRestLengths, + m_HairAsset.m_NumTotalHairVertices * sizeof(float)); + + buffer.sgetn((char *)&m_HairAsset.m_bSphere, sizeof(BSphere)); + + m_HairAsset.m_TriangleIndices.clear(); + + int size; + buffer.sgetn((char *)&size, sizeof(int)); + int *pIndices = new int[size]; + buffer.sgetn((char *)pIndices, size * sizeof(int)); + for (int i = 0; i < size; i++) + { + m_HairAsset.m_TriangleIndices.push_back(pIndices[i]); + } + AMD_SAFE_DELETE_ARRAY(pIndices); + + m_HairAsset.m_LineIndices.clear(); + buffer.sgetn((char *)&size, sizeof(int)); + pIndices = new int[size]; + buffer.sgetn((char *)pIndices, size * sizeof(int)); + for (int i = 0; i < size; i++) + { + m_HairAsset.m_LineIndices.push_back(pIndices[i]); + } + AMD_SAFE_DELETE_ARRAY(pIndices); + + if (m_HairAsset.m_NumPerStrandTexCoords) + { + m_HairAsset.m_pStrandTexCoords = + new DirectX::XMFLOAT2[m_HairAsset.m_NumTotalHairStrands]; + buffer.sgetn((char *)m_HairAsset.m_pStrandTexCoords, + m_HairAsset.m_NumTotalHairStrands * sizeof(DirectX::XMFLOAT2)); + } + else + { + m_HairAsset.m_pStrandTexCoords = NULL; + } + + if (m_HairAsset.m_NumPerVertexColors) + { + m_HairAsset.m_pVertexColors = + new DirectX::XMFLOAT4[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pVertexColors, + m_HairAsset.m_NumTotalHairVertices * sizeof(DirectX::XMFLOAT4)); + } + else + { + m_HairAsset.m_pVertexColors = NULL; + } + + if (m_HairAsset.m_NumPerVertexTexCoords) + { + m_HairAsset.m_pVertexTexCoords = + new DirectX::XMFLOAT2[m_HairAsset.m_NumTotalHairVertices]; + buffer.sgetn((char *)m_HairAsset.m_pVertexTexCoords, + m_HairAsset.m_NumTotalHairVertices * sizeof(DirectX::XMFLOAT2)); + } + else + { + m_HairAsset.m_pVertexTexCoords = NULL; + } + + if (m_HairAsset.m_NumHairToTriangleMappings > 0) + { + m_HairAsset.m_pMapping = + new HairToTriangleMapping[m_HairAsset.m_NumTotalHairStrands]; + buffer.sgetn((char *)m_HairAsset.m_pMapping, + m_HairAsset.m_NumTotalHairStrands * sizeof(HairToTriangleMapping)); + } + else + { + m_HairAsset.m_pMapping = NULL; + } + + return true; +} + +//-------------------------------------------------------------------------------------- +// +// Destructor +// +//-------------------------------------------------------------------------------------- +void TressFXMesh::DestroyAsset(void) +{ + m_HairAsset.m_TriangleIndices.clear(); + m_HairAsset.m_LineIndices.clear(); + + if (m_HairAsset.m_pVertices) + { + delete[] m_HairAsset.m_pVertices; + m_HairAsset.m_pVertices = NULL; + } + + if (m_HairAsset.m_pTangents) + { + delete[] m_HairAsset.m_pTangents; + m_HairAsset.m_pTangents = NULL; + } + + if (m_HairAsset.m_pStrandTexCoords) + { + delete[] m_HairAsset.m_pStrandTexCoords; + m_HairAsset.m_pStrandTexCoords = NULL; + } + + if (m_HairAsset.m_pHairStrandType) + { + delete[] m_HairAsset.m_pHairStrandType; + m_HairAsset.m_pHairStrandType = NULL; + } + + if (m_HairAsset.m_pLocalRotations) + { + delete[] m_HairAsset.m_pLocalRotations; + m_HairAsset.m_pLocalRotations = NULL; + } + + if (m_HairAsset.m_pGlobalRotations) + { + delete[] m_HairAsset.m_pGlobalRotations; + m_HairAsset.m_pGlobalRotations = NULL; + } + + if (m_HairAsset.m_pRefVectors) + { + delete[] m_HairAsset.m_pRefVectors; + m_HairAsset.m_pRefVectors = NULL; + } + + if (m_HairAsset.m_pTriangleVertices) + { + delete[] m_HairAsset.m_pTriangleVertices; + m_HairAsset.m_pTriangleVertices = NULL; + } + + if (m_HairAsset.m_pThicknessCoeffs) + { + delete[] m_HairAsset.m_pThicknessCoeffs; + m_HairAsset.m_pThicknessCoeffs = NULL; + } + + if (m_HairAsset.m_pRestLengths) + { + delete[] m_HairAsset.m_pRestLengths; + m_HairAsset.m_pRestLengths = NULL; + } + + if (m_HairAsset.m_pFollowRootOffset) + { + delete[] m_HairAsset.m_pFollowRootOffset; + m_HairAsset.m_pFollowRootOffset = NULL; + } + + if (m_HairAsset.m_pMapping) + { + delete[] m_HairAsset.m_pMapping; + m_HairAsset.m_pMapping = NULL; + } +} + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXMeshVulkan.h b/amd_tressfx_vulkan/src/TressFXMeshVulkan.h new file mode 100644 index 0000000..eed8992 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXMeshVulkan.h @@ -0,0 +1,171 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXMesh.h +// +// Hair mesh code +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#pragma once +#include "TressFXAsset.h" +#include "Util.h" + +namespace AMD +{ + +class TressFXMesh +{ + private: + VkDevice m_pvkDevice; + // private member function + VkResult CreateBufferAndViews(VkDevice pvkDevice, TressFX_SceneMesh *sceneMesh, + uint32_t texture_buffer_memory_index, + VkCommandBuffer upload_cmd_buffer, + VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, + size_t &offsetInUploadBuffer); + + VkResult AllocateDescriptorsSets(VkDevice pvkDevice, + VkDescriptorSetLayout GlobalConstraintsSetLayout, + VkDescriptorSetLayout LocalConstraintsSetLayout, + VkDescriptorSetLayout LenghtWindTangentSetLayout, + VkDescriptorSetLayout PrepareFollowHairSetLayout, + VkDescriptorSetLayout UpdateFollowHaitSetLayout, + VkDescriptorSetLayout computeTangentSetLayout, + VkDescriptorSetLayout Pass1SetLayout, + VkDescriptorSetLayout ShadowSetLayout); + + VkDescriptorPool m_descriptorPool; + + public: + VkBuffer m_pIndexBuffer; + VkDeviceMemory m_pIndexMemory; + VkBuffer m_pTriangleIndexBuffer; + VkDeviceMemory m_pTriangleIndexMemory; + VkBuffer m_pThicknessCoeffsBuffer; + VkDeviceMemory m_pThicknessCoeffsMemory; + VkBufferView m_pThicknessCoeffsView; + int m_TotalIndexCount; + int m_TotalTriangleIndexCount; + TressFXAsset m_HairAsset; + + // Simulation Descriptor Sets + VkDescriptorSet m_GlobalConstraintsSet; + VkDescriptorSet m_LocalConstraintsSet; + VkDescriptorSet m_LenghtWindCollisionSet; + VkDescriptorSet m_ComputeTangentSet; + VkDescriptorSet m_PrepareFollowHairSet; + VkDescriptorSet m_UpdateFollowHairSet; + + // Rendering Descriptor Sets + VkDescriptorSet m_pass1_set; + VkDescriptorSet m_shadow_pass_set; + + // vertex positions + VkBuffer m_HairVertexPositionsBuffer; + VkDeviceMemory m_HairVertexPositionsMemory; + VkBufferView m_HairVertexPositionsView; + + VkBuffer m_HairVertexPositionsPrevBuffer; + VkDeviceMemory m_HairVertexPositionsPrevMemory; + VkBufferView m_HairVertexPositionsPrevView; + + VkBuffer m_InitialHairPositionsBuffer; + VkDeviceMemory m_InitialHairPositionsMemory; + VkBufferView m_InitialHairPositionsView; + + // strand type + VkBuffer m_HairStrandTypeBuffer; + VkDeviceMemory m_HairStrandTypeMemory; + VkBufferView m_HairStrandTypeView; + + // rest length + VkBuffer m_HairLengthBuffer; + VkDeviceMemory m_HairLengthMemory; + VkBufferView m_HairRestLengthSRV; + + // reference vectors + VkBuffer m_HairRefVectorsBuffer; + VkDeviceMemory m_HairRefVectorsMemory; + VkBufferView m_HairRefVecsInLocalFrameView; + + // follow hair root offset + VkBuffer m_FollowHairRootOffsetBuffer; + VkDeviceMemory m_FollowHairRootOffsetMemory; + VkBufferView m_FollowHairRootOffsetView; + + // global and local transforms for each vertex + VkBuffer m_GlobalRotationsBuffer; + VkDeviceMemory m_GlobalRotationsMemory; + VkBufferView m_GlobalRotationsView; + + VkBuffer m_LocalRotationsBuffer; + VkDeviceMemory m_LocalRotationsMemory; + VkBufferView m_LocalRotationsView; + + // vertex tangents + VkBuffer m_HairVertexTangentsBuffer; + VkDeviceMemory m_HairVertexTangentsMemory; + VkBufferView m_HairVertexTangentsView; + + // mapping from hair to skinned mesh + VkBuffer m_HairSkinMappingBuffer; + VkDeviceMemory m_HairSkinMappingMemory; + VkBufferView m_HairSkinMappingView; + + // per-strand transformations for skinning + VkBuffer m_HairTransformsBuffer; + VkDeviceMemory m_HairTransformsMemory; + VkBufferView m_HairTransformsView; + + // per-strand texture coordinates + VkBuffer m_pStrandTexCoordBuffer; + VkDeviceMemory m_pStrandTexCoordMemory; + VkBufferView m_pStrandTexCoordView; + + // hair texture + VkImageView m_pHairTextureSRV; + + // public member functions + TressFXMesh(void); + ~TressFXMesh(void); + + VkResult OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, + TressFX_SceneMesh *sceneMesh, VkImageView pTexture, + uint32_t MemoryIndexGPU, VkCommandBuffer upload_cmd_buffer, + VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, + VkDescriptorSetLayout GlobalConstraintsSetLayout, + VkDescriptorSetLayout LocalConstraintsSetLayout, + VkDescriptorSetLayout LenghtWindCollisiontSetLayout, + VkDescriptorSetLayout PrepareFollowHairSetLayout, + VkDescriptorSetLayout UpdateFollowHaitSetLayout, + VkDescriptorSetLayout ComputeTangetSetLayout, + VkDescriptorSetLayout Pass1SetLayout, + VkDescriptorSetLayout ShadowSetLayout); + void OnDestroy(); + + void DestroyAsset(); + + bool Deserialize(TressFX_HairBlob *pHairBlob); +}; + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp new file mode 100644 index 0000000..69891e7 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp @@ -0,0 +1,228 @@ +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#include "TressFXOpaqueVulkan.h" + +namespace AMD +{ +void TressFX_OpaqueDesc::Initialize(TressFX_Desc &desc, VkImageView depthTexture, + VkImageView colorTexture, + VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, + size_t &offsetInScratchBuffer, + uint32_t cpu_memory_index, uint32_t gpu_memory_index) +{ + if (initialized == false) + { + refCount = 0; + tressFXSimulation.OnCreateDevice(desc.pvkDevice, &desc.collisionCapsule, + desc.maxConstantBuffers, cpu_memory_index, + gpu_memory_index); + tressFXRenderer.OnCreateDevice( + desc.pvkDevice, desc.backBufferWidth, desc.backBufferHeight, desc.bShortCutOn, + desc.maxConstantBuffers, cpu_memory_index, desc.memoryIndexDeviceLocal, + depthTexture, colorTexture, commandBuffer, scratchMemory, scratchBuffer, + offsetInScratchBuffer); + initialized = true; + } + refCount++; +} + +void TressFX_OpaqueDesc::Release(VkDevice pvkDevice) +{ + refCount--; + if (refCount <= 0) + { + initialized = false; + tressFXRenderer.OnDestroy(); + tressFXSimulation.OnDestroy(pvkDevice); + refCount = 0; + } +} + +bool TressFX_OpaqueDesc::LoadAppendAsset( + TressFX_HairBlob *pRawHairBlob, const TressFX_GuideFollowParams &guideFollowParams, + int groupId) +{ + return tressFXAssetLoader.LoadAppend(pRawHairBlob, guideFollowParams, groupId); +} + +bool TressFX_OpaqueDesc::CreateProcessedAsset( + TressFX_Desc &desc, TressFX_HairBlob **ppHairBlob, TressFX_SceneMesh *sceneMesh, + VkImageView hairTexture, uint32_t texture_buffer_memory_index, + VkCommandBuffer uploadCmdBuffer, VkBuffer scratchBuffer, VkDeviceMemory scratchMemory) +{ + tressFXAssetLoader.GenerateFollowHairs(); + tressFXAssetLoader.ProcessVertices(); + + if (desc.tressFXHair.pHair != NULL) + { + delete desc.tressFXHair.pHair; + desc.tressFXHair.pHair = NULL; + desc.tressFXHair.size = 0; + } + + tressFXAssetLoader.Serialize(&desc.tressFXHair); + + TressFXMesh *pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + if (pTressFXMesh != NULL) + { + delete pTressFXMesh; + } + pTressFXMesh = new TressFXMesh(); + pTressFXMesh->OnCreate(desc.pvkDevice, &desc.tressFXHair, sceneMesh, hairTexture, + texture_buffer_memory_index, uploadCmdBuffer, scratchBuffer, + scratchMemory, tressFXSimulation.m_GlobalConstraintsSetLayout, + tressFXSimulation.m_LocalConstraintsSetLayout, + tressFXSimulation.m_LenghtWindTangentSetLayout, + tressFXSimulation.m_PrepareFollowHairSetLayout, + tressFXSimulation.m_UpdateFollowHaitSetLayout, + desc.pOpaque->tressFXSimulation.m_ComputeTangentSetLayout, + tressFXRenderer.m_pass1_hair_set_layout, + tressFXRenderer.m_shadow_pass_hair_set_layout); + + desc.numTotalHairStrands = pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; + desc.numTotalHairVertices = pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; + desc.pTressFXMesh = (void *)pTressFXMesh; + + if (ppHairBlob != NULL) + { + *ppHairBlob = &desc.tressFXHair; + } + + tressFXAssetLoader.Clear(); + + return true; +} + +bool TressFX_OpaqueDesc::Simulate(TressFX_Desc &desc, VkCommandBuffer commandBuffer, + float elapsedTime, uint32_t uniformBufferIndex) +{ + tressFXSimulation.m_pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + desc.numTotalHairStrands = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; + desc.numTotalHairVertices = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; + tressFXSimulation.SetSimulationParams(desc.simulationParams); + tressfx_vec3 windDir; + windDir.x = desc.simulationParams.windDir.x; + windDir.y = desc.simulationParams.windDir.y; + windDir.z = desc.simulationParams.windDir.z; + VkResult vr = tressFXSimulation.Simulate( + desc.pvkDevice, commandBuffer, elapsedTime, desc.hairParams.density, windDir, + desc.simulationParams.windMag, &desc.modelTransformForHead, nullptr, + desc.targetFrameRate, desc.bSingleHeadTransform, false, uniformBufferIndex); + + return vr == VK_SUCCESS; +} + +bool TressFX_OpaqueDesc::Begin(TressFX_Desc &desc, uint32_t uniformBufferIndex) +{ + tressFXRenderer.m_pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + tressFXSimulation.m_pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + desc.numTotalHairStrands = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; + desc.numTotalHairVertices = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; + tressFXRenderer.m_hairParams = desc.hairParams; + tressFXRenderer.BeginHairFrame( + desc.pvkDevice, desc.eyePoint, desc.lightPosition, &desc.modelTransformForHead, + &desc.mViewProj, &desc.mViewProjLightFromLibrary, (float)desc.backBufferWidth, + (float)desc.backBufferHeight, desc.bSingleHeadTransform, uniformBufferIndex); + return true; +} + +bool TressFX_OpaqueDesc::RenderShadowMap(TressFX_Desc &desc, + VkCommandBuffer commandBuffer, + uint32_t uniformBufferIndex) +{ + tressFXRenderer.GenerateShadowMap(desc.pvkDevice, commandBuffer, + desc.hairParams.density, uniformBufferIndex); + desc.pHairShadowMapSRV = tressFXRenderer.GetShadowMapSRV(); + return true; +} + +bool TressFX_OpaqueDesc::RenderHair(TressFX_Desc &desc, VkCommandBuffer commandBuffer, + uint32_t uniformBufferIndex) +{ + if (desc.bShortCutOn) + { + tressFXRenderer.RenderHairShortcut(desc.pvkDevice, commandBuffer, + desc.backBufferWidth, desc.backBufferHeight, + uniformBufferIndex); + } + else + { + tressFXRenderer.RenderHair(desc.pvkDevice, commandBuffer, desc.backBufferWidth, + desc.backBufferHeight, uniformBufferIndex); + } + return true; +} + +bool TressFX_OpaqueDesc::End(TressFX_Desc &desc) +{ + tressFXRenderer.EndHairFrame(desc.pvkDevice); + return true; +} + +bool TressFX_OpaqueDesc::Resize(TressFX_Desc &desc, uint32_t texture_memory_index) +{ + VkResult vr = tressFXRenderer.OnResizedSwapChain( + desc.pvkDevice, desc.backBufferWidth, desc.backBufferHeight, desc.bShortCutOn, + texture_memory_index); + return (vr == VK_SUCCESS); +} + +bool TressFX_OpaqueDesc::GenerateTransforms(TressFX_Desc &desc, + TressFX_SceneMesh &sceneMesh) +{ + (void)desc; + (void)sceneMesh; + /* tressFXSimulation.m_pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + desc.numTotalHairStrands = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; + desc.numTotalHairVertices = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; + HRESULT hr = tressFXSimulation.GenerateTransforms(desc.pd3dDeviceContext, + sceneMesh, + &desc.pSkinningTransformationsUAV, &desc.modelTransformForHead); + return (hr == S_OK);*/ + return true; +} + +bool TressFX_OpaqueDesc::ApplyRigidTransforms(TressFX_Desc &desc) +{ + (void)desc; + /* tressFXSimulation.m_pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + desc.numTotalHairStrands = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; + desc.numTotalHairVertices = + tressFXSimulation.m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; + HRESULT hr = + tressFXSimulation.ApplyTransformGlobally(desc.pd3dDeviceContext, + desc.pSkinningTransformationsUAV, desc.hairParams.density, + desc.bSingleHeadTransform, &desc.modelTransformForHead); + return (hr == S_OK);*/ + return true; +} + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h new file mode 100644 index 0000000..ce10d73 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h @@ -0,0 +1,75 @@ +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMD_TRESSFX_OPAQUE_H +#define AMD_TRESSFX_OPAQUE_H + +#include "TressFXAsset.h" +#include "TressFXMeshVulkan.h" +#include "TressFXRendererVulkan.h" +#include "TressFXSimulationVulkan.h" + +namespace AMD +{ + +struct TressFX_OpaqueDesc +{ + public: + TressFX_OpaqueDesc() : initialized(false), refCount(0) {} + void Initialize(TressFX_Desc &desc, VkImageView depthTexture, + VkImageView colorTexture, VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, + size_t &offsetInScratchBuffer, uint32_t cpu_memory_index, + uint32_t gpu_memory_index); + void Release(VkDevice pvkDevice); + + bool LoadAppendAsset(TressFX_HairBlob *pRawHairBlob, + const TressFX_GuideFollowParams &guideFollowParams, int groupId); + bool CreateProcessedAsset(TressFX_Desc &desc, TressFX_HairBlob **ppHairBlob, + TressFX_SceneMesh *sceneMesh, VkImageView hairTexture, + uint32_t texture_buffer_memory_index, + VkCommandBuffer uploadCmdBuffer, VkBuffer scratchBuffer, + VkDeviceMemory scratchMemor); + + bool Begin(TressFX_Desc &desc, uint32_t uniformBufferIndex); + bool End(TressFX_Desc &desc); + bool RenderShadowMap(TressFX_Desc &desc, VkCommandBuffer commandBuffer, + uint32_t uniformBufferIndex); + bool RenderHair(TressFX_Desc &desc, VkCommandBuffer commandBuffer, + uint32_t uniformBufferIndex); + bool Simulate(TressFX_Desc &desc, VkCommandBuffer commandBuffer, float elapsedTime, + uint32_t uniformBufferIndex); + bool GenerateTransforms(TressFX_Desc &desc, TressFX_SceneMesh &sceneMesh); + bool ApplyRigidTransforms(TressFX_Desc &desc); + bool Resize(TressFX_Desc &desc, uint32_t texture_memory_index); + + TressFXSimulation tressFXSimulation; // Hair simulation class + TressFXRenderer tressFXRenderer; // Hair rendering class + private: + bool initialized; // only initialize this structure once + TressFXAssetLoader tressFXAssetLoader; // Hair asset loading class + int refCount; // reference count - delete allocations when 0 +}; + +} // namespace AMD + +#endif diff --git a/amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h b/amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h new file mode 100644 index 0000000..8824d61 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h @@ -0,0 +1,49053 @@ +#include +const std::vector hair_shadow_vertex = {119734787, +65536, +524289, +40, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +0, +4, +1852399981, +0, +10, +28, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +393221, +8, +1348430951, +1700164197, +2019914866, +0, +393222, +8, +0, +1348430951, +1953067887, +7237481, +196613, +10, +0, +327685, +15, +1936617283, +1953390964, +115, +393222, +15, +0, +1466785639, +1684828783, +0, +393222, +15, +1, +1450008423, +1350002025, +6975346, +458758, +15, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +15, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +15, +4, +1165385575, +25977, +327686, +15, +5, +1986420583, +7761734, +524294, +15, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +15, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +15, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +15, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +15, +10, +1632460647, +1633045364, +6649196, +458758, +15, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +15, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +15, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +15, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +15, +15, +1767333735, +2053722990, +101, +458758, +15, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +15, +17, +1415733095, +1416522088, +28777, +458758, +15, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +15, +19, +1181114215, +1766617697, +7628903, +393222, +15, +20, +1416191847, +1399350117, +77, +458758, +15, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +15, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +15, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +15, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +15, +25, +1214668647, +1265789281, +12915, +393222, +15, +26, +1214668647, +1165125985, +12920, +589830, +15, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +17, +0, +524293, +25, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +393221, +28, +1449094247, +1702130277, +1684949368, +30821, +327752, +8, +0, +11, +0, +196679, +8, +2, +262216, +15, +0, +5, +327752, +15, +0, +35, +0, +327752, +15, +0, +7, +16, +262216, +15, +1, +5, +327752, +15, +1, +35, +64, +327752, +15, +1, +7, +16, +262216, +15, +2, +5, +327752, +15, +2, +35, +128, +327752, +15, +2, +7, +16, +262216, +15, +3, +5, +327752, +15, +3, +35, +192, +327752, +15, +3, +7, +16, +327752, +15, +4, +35, +256, +327752, +15, +5, +35, +268, +327752, +15, +6, +35, +272, +327752, +15, +7, +35, +288, +327752, +15, +8, +35, +304, +327752, +15, +9, +35, +320, +327752, +15, +10, +35, +336, +327752, +15, +11, +35, +352, +327752, +15, +12, +35, +356, +327752, +15, +13, +35, +360, +327752, +15, +14, +35, +364, +327752, +15, +15, +35, +368, +327752, +15, +16, +35, +384, +327752, +15, +17, +35, +388, +327752, +15, +18, +35, +392, +327752, +15, +19, +35, +396, +327752, +15, +20, +35, +400, +327752, +15, +21, +35, +404, +327752, +15, +22, +35, +408, +327752, +15, +23, +35, +412, +327752, +15, +24, +35, +416, +327752, +15, +25, +35, +420, +327752, +15, +26, +35, +424, +262216, +15, +27, +5, +327752, +15, +27, +35, +432, +327752, +15, +27, +7, +16, +196679, +15, +2, +262215, +17, +34, +0, +262215, +17, +33, +16, +262215, +25, +34, +1, +262215, +25, +33, +7, +262215, +28, +11, +42, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +196638, +8, +7, +262176, +9, +3, +8, +262203, +9, +10, +3, +262165, +11, +32, +1, +262187, +11, +12, +0, +262168, +13, +7, +4, +262167, +14, +6, +3, +1966110, +15, +13, +13, +13, +13, +14, +6, +7, +7, +7, +7, +7, +6, +6, +6, +6, +7, +6, +6, +6, +6, +11, +11, +11, +11, +6, +6, +6, +13, +262176, +16, +2, +15, +262203, +16, +17, +2, +262187, +11, +18, +3, +262176, +19, +2, +13, +589849, +22, +6, +5, +0, +0, +0, +1, +0, +196635, +23, +22, +262176, +24, +0, +23, +262203, +24, +25, +0, +262176, +27, +1, +11, +262203, +27, +28, +1, +262187, +6, +32, +1065353216, +262176, +38, +3, +7, +327734, +2, +4, +0, +3, +131320, +5, +327745, +19, +20, +17, +18, +262205, +13, +21, +20, +262205, +23, +26, +25, +262205, +11, +29, +28, +327775, +7, +30, +26, +29, +524367, +14, +31, +30, +30, +0, +1, +2, +327761, +6, +33, +31, +0, +327761, +6, +34, +31, +1, +327761, +6, +35, +31, +2, +458832, +7, +36, +33, +34, +35, +32, +327825, +7, +37, +21, +36, +327745, +38, +39, +10, +12, +196670, +39, +37, +65789, +65592, +}; +const std::vector hair_shadow_fragment = {119734787, +65536, +524289, +6, +0, +131089, +1, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +327695, +4, +4, +1852399981, +0, +196624, +4, +7, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +262149, +4, +1852399981, +0, +131091, +2, +196641, +3, +2, +327734, +2, +4, +0, +3, +131320, +5, +65789, +65592, +}; +const std::vector render_hair_vertex = {119734787, +65536, +524289, +228, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +720911, +0, +4, +1852399981, +0, +65, +164, +199, +206, +213, +227, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +458757, +11, +1701208403, +1919905375, +1768710509, +1982358906, +3879526, +196613, +10, +6514038, +458757, +17, +1701208403, +1919905375, +1768710509, +1982358906, +3879782, +196613, +16, +6514038, +196613, +20, +7234924, +196613, +40, +7234924, +196613, +57, +118, +524293, +61, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +393221, +65, +1449094247, +1702130277, +1684949368, +30821, +262149, +72, +1735287124, +7630437, +524293, +73, +1632132967, +1700164201, +2019914866, +1735287124, +1937010277, +0, +262149, +79, +1769234802, +111, +327685, +82, +1936617283, +1953390964, +115, +393222, +82, +0, +1466785639, +1684828783, +0, +393222, +82, +1, +1450008423, +1350002025, +6975346, +458758, +82, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +82, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +82, +4, +1165385575, +25977, +327686, +82, +5, +1986420583, +7761734, +524294, +82, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +82, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +82, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +82, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +82, +10, +1632460647, +1633045364, +6649196, +458758, +82, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +82, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +82, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +82, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +82, +15, +1767333735, +2053722990, +101, +458758, +82, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +82, +17, +1415733095, +1416522088, +28777, +458758, +82, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +82, +19, +1181114215, +1766617697, +7628903, +393222, +82, +20, +1416191847, +1399350117, +77, +458758, +82, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +82, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +82, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +82, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +82, +25, +1214668647, +1265789281, +12915, +393222, +82, +26, +1214668647, +1165125985, +12920, +589830, +82, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +84, +0, +524293, +92, +1632132967, +1750364777, +1852531561, +1131639653, +1717986671, +115, +262149, +103, +1751607666, +116, +262149, +113, +1634886000, +109, +327685, +115, +1785688688, +1734963807, +29800, +262149, +126, +1634886000, +109, +393221, +129, +1634760805, +1766876270, +1936483704, +0, +327685, +140, +1919501414, +1701080649, +120, +262149, +150, +1886217588, +0, +393221, +162, +1348430951, +1700164197, +2019914866, +0, +393222, +162, +0, +1348430951, +1953067887, +7237481, +196613, +164, +0, +262149, +199, +1953523044, +104, +262149, +206, +1735287156, +7630437, +262149, +213, +829436016, +0, +327685, +227, +1634890867, +1866687598, +7499628, +262215, +61, +34, +1, +262215, +61, +33, +7, +262215, +65, +11, +42, +262215, +73, +34, +1, +262215, +73, +33, +8, +262216, +82, +0, +5, +327752, +82, +0, +35, +0, +327752, +82, +0, +7, +16, +262216, +82, +1, +5, +327752, +82, +1, +35, +64, +327752, +82, +1, +7, +16, +262216, +82, +2, +5, +327752, +82, +2, +35, +128, +327752, +82, +2, +7, +16, +262216, +82, +3, +5, +327752, +82, +3, +35, +192, +327752, +82, +3, +7, +16, +327752, +82, +4, +35, +256, +327752, +82, +5, +35, +268, +327752, +82, +6, +35, +272, +327752, +82, +7, +35, +288, +327752, +82, +8, +35, +304, +327752, +82, +9, +35, +320, +327752, +82, +10, +35, +336, +327752, +82, +11, +35, +352, +327752, +82, +12, +35, +356, +327752, +82, +13, +35, +360, +327752, +82, +14, +35, +364, +327752, +82, +15, +35, +368, +327752, +82, +16, +35, +384, +327752, +82, +17, +35, +388, +327752, +82, +18, +35, +392, +327752, +82, +19, +35, +396, +327752, +82, +20, +35, +400, +327752, +82, +21, +35, +404, +327752, +82, +22, +35, +408, +327752, +82, +23, +35, +412, +327752, +82, +24, +35, +416, +327752, +82, +25, +35, +420, +327752, +82, +26, +35, +424, +262216, +82, +27, +5, +327752, +82, +27, +35, +432, +327752, +82, +27, +7, +16, +196679, +82, +2, +262215, +84, +34, +0, +262215, +84, +33, +16, +262215, +92, +34, +1, +262215, +92, +33, +6, +327752, +162, +0, +11, +0, +196679, +162, +2, +262215, +199, +30, +0, +262215, +206, +30, +2, +262215, +213, +30, +1, +262215, +227, +30, +3, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +2, +262176, +8, +7, +7, +262177, +9, +7, +8, +262167, +13, +6, +3, +262176, +14, +7, +13, +262177, +15, +13, +14, +262176, +19, +7, +6, +262187, +6, +25, +869711765, +131092, +26, +262187, +6, +35, +0, +327724, +7, +36, +35, +35, +393260, +13, +53, +35, +35, +35, +589849, +58, +6, +5, +0, +0, +0, +1, +0, +196635, +59, +58, +262176, +60, +0, +59, +262203, +60, +61, +0, +262165, +63, +32, +1, +262176, +64, +1, +63, +262203, +64, +65, +1, +262187, +63, +67, +2, +262167, +69, +6, +4, +262203, +60, +73, +0, +262168, +81, +69, +4, +1966110, +82, +81, +81, +81, +81, +13, +6, +69, +69, +69, +69, +69, +6, +6, +6, +6, +69, +6, +6, +6, +6, +63, +63, +63, +63, +6, +6, +6, +81, +262176, +83, +2, +82, +262203, +83, +84, +2, +262187, +63, +85, +17, +262176, +86, +2, +6, +262203, +60, +92, +0, +262165, +97, +32, +0, +262187, +97, +98, +0, +262187, +6, +101, +1065353216, +262187, +63, +106, +4, +262176, +107, +2, +13, +262187, +63, +116, +1, +262176, +117, +2, +81, +262187, +63, +131, +13, +262187, +6, +138, +1060487823, +262187, +6, +147, +3212836864, +262187, +63, +157, +14, +196638, +162, +69, +262176, +163, +3, +162, +262203, +163, +164, +3, +262187, +63, +165, +0, +262176, +174, +3, +69, +262187, +63, +182, +15, +262187, +97, +183, +1, +262187, +97, +192, +3, +262176, +193, +3, +6, +262203, +193, +199, +3, +262187, +97, +200, +2, +262203, +174, +206, +3, +262203, +174, +213, +3, +262203, +174, +227, +3, +327734, +2, +4, +0, +3, +131320, +5, +262203, +14, +57, +7, +262203, +14, +72, +7, +262203, +19, +79, +7, +262203, +19, +80, +7, +262203, +14, +103, +7, +262203, +14, +113, +7, +262203, +8, +115, +7, +262203, +8, +126, +7, +262203, +19, +129, +7, +262203, +19, +130, +7, +262203, +19, +140, +7, +262203, +19, +141, +7, +262203, +14, +150, +7, +262205, +59, +62, +61, +262205, +63, +66, +65, +327815, +63, +68, +66, +67, +327775, +69, +70, +62, +68, +524367, +13, +71, +70, +70, +0, +1, +2, +196670, +57, +71, +262205, +59, +74, +73, +262205, +63, +75, +65, +327815, +63, +76, +75, +67, +327775, +69, +77, +74, +76, +524367, +13, +78, +77, +77, +0, +1, +2, +196670, +72, +78, +327745, +86, +87, +84, +85, +262205, +6, +88, +87, +327866, +26, +89, +88, +35, +196855, +91, +0, +262394, +89, +90, +100, +131320, +90, +262205, +59, +93, +92, +262205, +63, +94, +65, +327815, +63, +95, +94, +67, +327775, +69, +96, +93, +95, +327761, +6, +99, +96, +0, +196670, +80, +99, +131321, +91, +131320, +100, +196670, +80, +101, +131321, +91, +131320, +91, +262205, +6, +102, +80, +196670, +79, +102, +262205, +13, +104, +72, +262205, +13, +105, +57, +327745, +107, +108, +84, +106, +262205, +13, +109, +108, +327811, +13, +110, +105, +109, +393228, +13, +111, +1, +69, +110, +458764, +13, +112, +1, +68, +104, +111, +196670, +113, +112, +327737, +13, +114, +17, +113, +196670, +103, +114, +327745, +117, +118, +84, +116, +262205, +81, +119, +118, +262205, +13, +120, +103, +327761, +6, +121, +120, +0, +327761, +6, +122, +120, +1, +327761, +6, +123, +120, +2, +458832, +69, +124, +121, +122, +123, +35, +327825, +69, +125, +119, +124, +458831, +7, +127, +125, +125, +0, +1, +196670, +126, +127, +327737, +7, +128, +11, +126, +196670, +115, +128, +327745, +86, +132, +84, +131, +262205, +6, +133, +132, +327864, +26, +134, +133, +35, +196855, +136, +0, +262394, +134, +135, +137, +131320, +135, +196670, +130, +35, +131321, +136, +131320, +137, +196670, +130, +138, +131321, +136, +131320, +136, +262205, +6, +139, +130, +196670, +129, +139, +262205, +63, +142, +65, +327819, +63, +143, +142, +67, +327850, +26, +144, +143, +116, +196855, +146, +0, +262394, +144, +145, +148, +131320, +145, +196670, +141, +147, +131321, +146, +131320, +148, +196670, +141, +101, +131321, +146, +131320, +146, +262205, +6, +149, +141, +196670, +140, +149, +262205, +13, +151, +57, +262205, +6, +152, +140, +262205, +13, +153, +103, +327822, +13, +154, +153, +152, +262205, +6, +155, +79, +327822, +13, +156, +154, +155, +327745, +86, +158, +84, +157, +262205, +6, +159, +158, +327822, +13, +160, +156, +159, +327809, +13, +161, +151, +160, +196670, +150, +161, +327745, +117, +166, +84, +116, +262205, +81, +167, +166, +262205, +13, +168, +150, +327761, +6, +169, +168, +0, +327761, +6, +170, +168, +1, +327761, +6, +171, +168, +2, +458832, +69, +172, +169, +170, +171, +101, +327825, +69, +173, +167, +172, +327745, +174, +175, +164, +165, +196670, +175, +173, +327745, +174, +176, +164, +165, +262205, +69, +177, +176, +262205, +6, +178, +140, +262205, +7, +179, +115, +262205, +6, +180, +129, +327822, +7, +181, +179, +180, +393281, +86, +184, +84, +182, +183, +262205, +6, +185, +184, +327760, +7, +186, +185, +185, +327816, +7, +187, +181, +186, +327761, +6, +188, +187, +0, +327761, +6, +189, +187, +1, +458832, +69, +190, +188, +189, +35, +35, +327822, +69, +191, +190, +178, +393281, +193, +194, +164, +165, +192, +262205, +6, +195, +194, +327822, +69, +196, +191, +195, +327809, +69, +197, +177, +196, +327745, +174, +198, +164, +165, +196670, +198, +197, +393281, +193, +201, +164, +165, +200, +262205, +6, +202, +201, +393281, +193, +203, +164, +165, +192, +262205, +6, +204, +203, +327816, +6, +205, +202, +204, +196670, +199, +205, +262205, +13, +207, +72, +262205, +6, +208, +79, +327761, +6, +209, +207, +0, +327761, +6, +210, +207, +1, +327761, +6, +211, +207, +2, +458832, +69, +212, +209, +210, +211, +208, +196670, +206, +212, +262205, +13, +214, +57, +458831, +7, +215, +214, +214, +0, +1, +262205, +59, +216, +61, +262205, +63, +217, +65, +327815, +63, +218, +217, +67, +327808, +63, +219, +218, +116, +327775, +69, +220, +216, +219, +458831, +7, +221, +220, +220, +0, +1, +327761, +6, +222, +215, +0, +327761, +6, +223, +215, +1, +327761, +6, +224, +221, +0, +327761, +6, +225, +221, +1, +458832, +69, +226, +222, +223, +224, +225, +196670, +213, +226, +65789, +65592, +327734, +7, +11, +0, +9, +196663, +8, +10, +131320, +12, +262203, +19, +20, +7, +262203, +8, +23, +7, +262205, +7, +21, +10, +393228, +6, +22, +1, +66, +21, +196670, +20, +22, +262205, +6, +24, +20, +327870, +26, +27, +24, +25, +196855, +29, +0, +262394, +27, +28, +34, +131320, +28, +262205, +7, +30, +10, +262205, +6, +31, +20, +327760, +7, +32, +31, +31, +327816, +7, +33, +30, +32, +196670, +23, +33, +131321, +29, +131320, +34, +196670, +23, +36, +131321, +29, +131320, +29, +262205, +7, +37, +23, +131326, +37, +65592, +327734, +13, +17, +0, +15, +196663, +14, +16, +131320, +18, +262203, +19, +40, +7, +262203, +14, +43, +7, +262205, +13, +41, +16, +393228, +6, +42, +1, +66, +41, +196670, +40, +42, +262205, +6, +44, +40, +327870, +26, +45, +44, +25, +196855, +47, +0, +262394, +45, +46, +52, +131320, +46, +262205, +13, +48, +16, +262205, +6, +49, +40, +393296, +13, +50, +49, +49, +49, +327816, +13, +51, +48, +50, +196670, +43, +51, +131321, +47, +131320, +52, +196670, +43, +53, +131321, +47, +131320, +47, +262205, +13, +54, +43, +131326, +54, +65592, +}; +const std::vector render_hair_aa_vertex = {119734787, +65536, +524289, +252, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +720911, +0, +4, +1852399981, +0, +65, +201, +230, +234, +241, +251, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +458757, +11, +1701208403, +1919905375, +1768710509, +1982358906, +3879526, +196613, +10, +6514038, +458757, +17, +1701208403, +1919905375, +1768710509, +1982358906, +3879782, +196613, +16, +6514038, +196613, +20, +7234924, +196613, +40, +7234924, +196613, +57, +118, +524293, +61, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +393221, +65, +1449094247, +1702130277, +1684949368, +30821, +262149, +72, +1735287124, +7630437, +524293, +73, +1632132967, +1700164201, +2019914866, +1735287124, +1937010277, +0, +262149, +79, +1769234802, +111, +327685, +82, +1936617283, +1953390964, +115, +393222, +82, +0, +1466785639, +1684828783, +0, +393222, +82, +1, +1450008423, +1350002025, +6975346, +458758, +82, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +82, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +82, +4, +1165385575, +25977, +327686, +82, +5, +1986420583, +7761734, +524294, +82, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +82, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +82, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +82, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +82, +10, +1632460647, +1633045364, +6649196, +458758, +82, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +82, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +82, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +82, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +82, +15, +1767333735, +2053722990, +101, +458758, +82, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +82, +17, +1415733095, +1416522088, +28777, +458758, +82, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +82, +19, +1181114215, +1766617697, +7628903, +393222, +82, +20, +1416191847, +1399350117, +77, +458758, +82, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +82, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +82, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +82, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +82, +25, +1214668647, +1265789281, +12915, +393222, +82, +26, +1214668647, +1165125985, +12920, +589830, +82, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +84, +0, +524293, +92, +1632132967, +1750364777, +1852531561, +1131639653, +1717986671, +115, +262149, +103, +1751607666, +116, +262149, +113, +1634886000, +109, +327685, +115, +1785688688, +1734963807, +29800, +262149, +126, +1634886000, +109, +458757, +130, +1919508840, +1701274693, +1769172816, +1852795252, +12403, +458757, +145, +1919508840, +1701274693, +1769172816, +1852795252, +12659, +393221, +178, +1634760805, +1766876270, +1936483704, +0, +327685, +189, +1919501414, +1701080649, +120, +393221, +199, +1348430951, +1700164197, +2019914866, +0, +393222, +199, +0, +1348430951, +1953067887, +7237481, +196613, +201, +0, +262149, +230, +1953523044, +104, +262149, +234, +1735287156, +7630437, +262149, +241, +829436016, +0, +327685, +251, +1634890867, +1866687598, +7499628, +262215, +61, +34, +1, +262215, +61, +33, +7, +262215, +65, +11, +42, +262215, +73, +34, +1, +262215, +73, +33, +8, +262216, +82, +0, +5, +327752, +82, +0, +35, +0, +327752, +82, +0, +7, +16, +262216, +82, +1, +5, +327752, +82, +1, +35, +64, +327752, +82, +1, +7, +16, +262216, +82, +2, +5, +327752, +82, +2, +35, +128, +327752, +82, +2, +7, +16, +262216, +82, +3, +5, +327752, +82, +3, +35, +192, +327752, +82, +3, +7, +16, +327752, +82, +4, +35, +256, +327752, +82, +5, +35, +268, +327752, +82, +6, +35, +272, +327752, +82, +7, +35, +288, +327752, +82, +8, +35, +304, +327752, +82, +9, +35, +320, +327752, +82, +10, +35, +336, +327752, +82, +11, +35, +352, +327752, +82, +12, +35, +356, +327752, +82, +13, +35, +360, +327752, +82, +14, +35, +364, +327752, +82, +15, +35, +368, +327752, +82, +16, +35, +384, +327752, +82, +17, +35, +388, +327752, +82, +18, +35, +392, +327752, +82, +19, +35, +396, +327752, +82, +20, +35, +400, +327752, +82, +21, +35, +404, +327752, +82, +22, +35, +408, +327752, +82, +23, +35, +412, +327752, +82, +24, +35, +416, +327752, +82, +25, +35, +420, +327752, +82, +26, +35, +424, +262216, +82, +27, +5, +327752, +82, +27, +35, +432, +327752, +82, +27, +7, +16, +196679, +82, +2, +262215, +84, +34, +0, +262215, +84, +33, +16, +262215, +92, +34, +1, +262215, +92, +33, +6, +327752, +199, +0, +11, +0, +196679, +199, +2, +262215, +230, +30, +0, +262215, +234, +30, +2, +262215, +241, +30, +1, +262215, +251, +30, +3, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +2, +262176, +8, +7, +7, +262177, +9, +7, +8, +262167, +13, +6, +3, +262176, +14, +7, +13, +262177, +15, +13, +14, +262176, +19, +7, +6, +262187, +6, +25, +869711765, +131092, +26, +262187, +6, +35, +0, +327724, +7, +36, +35, +35, +393260, +13, +53, +35, +35, +35, +589849, +58, +6, +5, +0, +0, +0, +1, +0, +196635, +59, +58, +262176, +60, +0, +59, +262203, +60, +61, +0, +262165, +63, +32, +1, +262176, +64, +1, +63, +262203, +64, +65, +1, +262187, +63, +67, +2, +262167, +69, +6, +4, +262203, +60, +73, +0, +262168, +81, +69, +4, +1966110, +82, +81, +81, +81, +81, +13, +6, +69, +69, +69, +69, +69, +6, +6, +6, +6, +69, +6, +6, +6, +6, +63, +63, +63, +63, +6, +6, +6, +81, +262176, +83, +2, +82, +262203, +83, +84, +2, +262187, +63, +85, +17, +262176, +86, +2, +6, +262203, +60, +92, +0, +262165, +97, +32, +0, +262187, +97, +98, +0, +262187, +6, +101, +1065353216, +262187, +63, +106, +4, +262176, +107, +2, +13, +262187, +63, +116, +1, +262176, +117, +2, +81, +262176, +129, +7, +69, +262187, +63, +136, +14, +262187, +97, +168, +3, +262187, +63, +180, +13, +262187, +6, +187, +1060487823, +262187, +6, +196, +3212836864, +196638, +199, +69, +262176, +200, +3, +199, +262203, +200, +201, +3, +262187, +63, +202, +0, +262187, +63, +216, +15, +262187, +97, +217, +1, +262176, +227, +3, +69, +262176, +229, +3, +6, +262203, +229, +230, +3, +262187, +97, +231, +2, +262203, +227, +234, +3, +262203, +227, +241, +3, +262203, +227, +251, +3, +327734, +2, +4, +0, +3, +131320, +5, +262203, +14, +57, +7, +262203, +14, +72, +7, +262203, +19, +79, +7, +262203, +19, +80, +7, +262203, +14, +103, +7, +262203, +14, +113, +7, +262203, +8, +115, +7, +262203, +8, +126, +7, +262203, +129, +130, +7, +262203, +129, +145, +7, +262203, +19, +178, +7, +262203, +19, +179, +7, +262203, +19, +189, +7, +262203, +19, +190, +7, +262203, +129, +203, +7, +262205, +59, +62, +61, +262205, +63, +66, +65, +327815, +63, +68, +66, +67, +327775, +69, +70, +62, +68, +524367, +13, +71, +70, +70, +0, +1, +2, +196670, +57, +71, +262205, +59, +74, +73, +262205, +63, +75, +65, +327815, +63, +76, +75, +67, +327775, +69, +77, +74, +76, +524367, +13, +78, +77, +77, +0, +1, +2, +196670, +72, +78, +327745, +86, +87, +84, +85, +262205, +6, +88, +87, +327866, +26, +89, +88, +35, +196855, +91, +0, +262394, +89, +90, +100, +131320, +90, +262205, +59, +93, +92, +262205, +63, +94, +65, +327815, +63, +95, +94, +67, +327775, +69, +96, +93, +95, +327761, +6, +99, +96, +0, +196670, +80, +99, +131321, +91, +131320, +100, +196670, +80, +101, +131321, +91, +131320, +91, +262205, +6, +102, +80, +196670, +79, +102, +262205, +13, +104, +72, +262205, +13, +105, +57, +327745, +107, +108, +84, +106, +262205, +13, +109, +108, +327811, +13, +110, +105, +109, +393228, +13, +111, +1, +69, +110, +458764, +13, +112, +1, +68, +104, +111, +196670, +113, +112, +327737, +13, +114, +17, +113, +196670, +103, +114, +327745, +117, +118, +84, +116, +262205, +81, +119, +118, +262205, +13, +120, +103, +327761, +6, +121, +120, +0, +327761, +6, +122, +120, +1, +327761, +6, +123, +120, +2, +458832, +69, +124, +121, +122, +123, +35, +327825, +69, +125, +119, +124, +458831, +7, +127, +125, +125, +0, +1, +196670, +126, +127, +327737, +7, +128, +11, +126, +196670, +115, +128, +262205, +13, +131, +57, +262205, +13, +132, +103, +327822, +13, +133, +132, +101, +262205, +6, +134, +79, +327822, +13, +135, +133, +134, +327745, +86, +137, +84, +136, +262205, +6, +138, +137, +327822, +13, +139, +135, +138, +327811, +13, +140, +131, +139, +327761, +6, +141, +140, +0, +327761, +6, +142, +140, +1, +327761, +6, +143, +140, +2, +458832, +69, +144, +141, +142, +143, +101, +196670, +130, +144, +262205, +13, +146, +57, +262205, +13, +147, +103, +327822, +13, +148, +147, +101, +262205, +6, +149, +79, +327822, +13, +150, +148, +149, +327745, +86, +151, +84, +136, +262205, +6, +152, +151, +327822, +13, +153, +150, +152, +327809, +13, +154, +146, +153, +327761, +6, +155, +154, +0, +327761, +6, +156, +154, +1, +327761, +6, +157, +154, +2, +458832, +69, +158, +155, +156, +157, +101, +196670, +145, +158, +327745, +117, +159, +84, +116, +262205, +81, +160, +159, +262205, +69, +161, +130, +327825, +69, +162, +160, +161, +196670, +130, +162, +327745, +117, +163, +84, +116, +262205, +81, +164, +163, +262205, +69, +165, +145, +327825, +69, +166, +164, +165, +196670, +145, +166, +262205, +69, +167, +130, +327745, +19, +169, +130, +168, +262205, +6, +170, +169, +458832, +69, +171, +170, +170, +170, +170, +327816, +69, +172, +167, +171, +196670, +130, +172, +262205, +69, +173, +145, +327745, +19, +174, +145, +168, +262205, +6, +175, +174, +458832, +69, +176, +175, +175, +175, +175, +327816, +69, +177, +173, +176, +196670, +145, +177, +327745, +86, +181, +84, +180, +262205, +6, +182, +181, +327864, +26, +183, +182, +35, +196855, +185, +0, +262394, +183, +184, +186, +131320, +184, +196670, +179, +35, +131321, +185, +131320, +186, +196670, +179, +187, +131321, +185, +131320, +185, +262205, +6, +188, +179, +196670, +178, +188, +262205, +63, +191, +65, +327819, +63, +192, +191, +67, +327850, +26, +193, +192, +116, +196855, +195, +0, +262394, +193, +194, +197, +131320, +194, +196670, +190, +196, +131321, +195, +131320, +197, +196670, +190, +101, +131321, +195, +131320, +195, +262205, +6, +198, +190, +196670, +189, +198, +262205, +6, +204, +189, +327860, +26, +205, +204, +196, +196855, +207, +0, +262394, +205, +206, +209, +131320, +206, +262205, +69, +208, +130, +196670, +203, +208, +131321, +207, +131320, +209, +262205, +69, +210, +145, +196670, +203, +210, +131321, +207, +131320, +207, +262205, +69, +211, +203, +262205, +6, +212, +189, +262205, +7, +213, +115, +262205, +6, +214, +178, +327822, +7, +215, +213, +214, +393281, +86, +218, +84, +216, +217, +262205, +6, +219, +218, +327760, +7, +220, +219, +219, +327816, +7, +221, +215, +220, +327761, +6, +222, +221, +0, +327761, +6, +223, +221, +1, +458832, +69, +224, +222, +223, +35, +35, +327822, +69, +225, +224, +212, +327809, +69, +226, +211, +225, +327745, +227, +228, +201, +202, +196670, +228, +226, +393281, +229, +232, +201, +202, +231, +262205, +6, +233, +232, +196670, +230, +233, +262205, +13, +235, +72, +262205, +6, +236, +79, +327761, +6, +237, +235, +0, +327761, +6, +238, +235, +1, +327761, +6, +239, +235, +2, +458832, +69, +240, +237, +238, +239, +236, +196670, +234, +240, +262205, +69, +242, +130, +458831, +7, +243, +242, +242, +0, +1, +262205, +69, +244, +145, +458831, +7, +245, +244, +244, +0, +1, +327761, +6, +246, +243, +0, +327761, +6, +247, +243, +1, +327761, +6, +248, +245, +0, +327761, +6, +249, +245, +1, +458832, +69, +250, +246, +247, +248, +249, +196670, +241, +250, +65789, +65592, +327734, +7, +11, +0, +9, +196663, +8, +10, +131320, +12, +262203, +19, +20, +7, +262203, +8, +23, +7, +262205, +7, +21, +10, +393228, +6, +22, +1, +66, +21, +196670, +20, +22, +262205, +6, +24, +20, +327870, +26, +27, +24, +25, +196855, +29, +0, +262394, +27, +28, +34, +131320, +28, +262205, +7, +30, +10, +262205, +6, +31, +20, +327760, +7, +32, +31, +31, +327816, +7, +33, +30, +32, +196670, +23, +33, +131321, +29, +131320, +34, +196670, +23, +36, +131321, +29, +131320, +29, +262205, +7, +37, +23, +131326, +37, +65592, +327734, +13, +17, +0, +15, +196663, +14, +16, +131320, +18, +262203, +19, +40, +7, +262203, +14, +43, +7, +262205, +13, +41, +16, +393228, +6, +42, +1, +66, +41, +196670, +40, +42, +262205, +6, +44, +40, +327870, +26, +45, +44, +25, +196855, +47, +0, +262394, +45, +46, +52, +131320, +46, +262205, +13, +48, +16, +262205, +6, +49, +40, +393296, +13, +50, +49, +49, +49, +327816, +13, +51, +48, +50, +196670, +43, +51, +131321, +47, +131320, +52, +196670, +43, +53, +131321, +47, +131320, +47, +262205, +13, +54, +43, +131326, +54, +65592, +}; +const std::vector render_hair_strand_copies_vertex = {119734787, +65536, +524289, +285, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +786447, +0, +4, +1852399981, +0, +61, +66, +218, +253, +260, +267, +284, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +458757, +11, +1701208403, +1919905375, +1768710509, +1982358906, +3879526, +196613, +10, +6514038, +458757, +17, +1701208403, +1919905375, +1768710509, +1982358906, +3879782, +196613, +16, +6514038, +196613, +20, +7234924, +196613, +40, +7234924, +262149, +59, +1701080681, +120, +393221, +61, +1449094247, +1702130277, +1684949368, +30821, +393221, +65, +1684955506, +1936090703, +1850307685, +7890276, +458757, +66, +1230990439, +1635021678, +1231381358, +2019910766, +0, +327685, +70, +1684366707, +1684955474, +0, +393221, +82, +1684366707, +1668834644, +1685221999, +0, +327685, +93, +1684955506, +1936090703, +29797, +327685, +98, +2020892519, +1936289614, +101, +393221, +102, +1634951015, +1852394605, +1467113829, +7364978, +262149, +117, +1735287124, +7630437, +524293, +121, +1632132967, +1700164201, +2019914866, +1735287124, +1937010277, +0, +196613, +127, +118, +524293, +129, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +262149, +136, +1769234802, +111, +327685, +139, +1936617283, +1953390964, +115, +393222, +139, +0, +1466785639, +1684828783, +0, +393222, +139, +1, +1450008423, +1350002025, +6975346, +458758, +139, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +139, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +139, +4, +1165385575, +25977, +327686, +139, +5, +1986420583, +7761734, +524294, +139, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +139, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +139, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +139, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +139, +10, +1632460647, +1633045364, +6649196, +458758, +139, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +139, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +139, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +139, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +139, +15, +1767333735, +2053722990, +101, +458758, +139, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +139, +17, +1415733095, +1416522088, +28777, +458758, +139, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +139, +19, +1181114215, +1766617697, +7628903, +393222, +139, +20, +1416191847, +1399350117, +77, +458758, +139, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +139, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +139, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +139, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +139, +25, +1214668647, +1265789281, +12915, +393222, +139, +26, +1214668647, +1165125985, +12920, +589830, +139, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +141, +0, +524293, +149, +1632132967, +1750364777, +1852531561, +1131639653, +1717986671, +115, +262149, +158, +1751607666, +116, +262149, +168, +1634886000, +109, +327685, +170, +1785688688, +1734963807, +29800, +262149, +180, +1634886000, +109, +393221, +183, +1634760805, +1766876270, +1936483704, +0, +327685, +194, +1919501414, +1701080649, +120, +262149, +204, +1886217588, +0, +393221, +216, +1348430951, +1700164197, +2019914866, +0, +393222, +216, +0, +1348430951, +1953067887, +7237481, +196613, +218, +0, +262149, +253, +1953523044, +104, +262149, +260, +1735287156, +7630437, +262149, +267, +829436016, +0, +327685, +284, +1634890867, +1866687598, +7499628, +262215, +61, +11, +42, +262215, +66, +11, +43, +262215, +98, +34, +0, +262215, +98, +33, +5, +262215, +102, +34, +0, +262215, +102, +33, +18, +262215, +121, +34, +1, +262215, +121, +33, +8, +262215, +129, +34, +1, +262215, +129, +33, +7, +262216, +139, +0, +5, +327752, +139, +0, +35, +0, +327752, +139, +0, +7, +16, +262216, +139, +1, +5, +327752, +139, +1, +35, +64, +327752, +139, +1, +7, +16, +262216, +139, +2, +5, +327752, +139, +2, +35, +128, +327752, +139, +2, +7, +16, +262216, +139, +3, +5, +327752, +139, +3, +35, +192, +327752, +139, +3, +7, +16, +327752, +139, +4, +35, +256, +327752, +139, +5, +35, +268, +327752, +139, +6, +35, +272, +327752, +139, +7, +35, +288, +327752, +139, +8, +35, +304, +327752, +139, +9, +35, +320, +327752, +139, +10, +35, +336, +327752, +139, +11, +35, +352, +327752, +139, +12, +35, +356, +327752, +139, +13, +35, +360, +327752, +139, +14, +35, +364, +327752, +139, +15, +35, +368, +327752, +139, +16, +35, +384, +327752, +139, +17, +35, +388, +327752, +139, +18, +35, +392, +327752, +139, +19, +35, +396, +327752, +139, +20, +35, +400, +327752, +139, +21, +35, +404, +327752, +139, +22, +35, +408, +327752, +139, +23, +35, +412, +327752, +139, +24, +35, +416, +327752, +139, +25, +35, +420, +327752, +139, +26, +35, +424, +262216, +139, +27, +5, +327752, +139, +27, +35, +432, +327752, +139, +27, +7, +16, +196679, +139, +2, +262215, +141, +34, +0, +262215, +141, +33, +16, +262215, +149, +34, +1, +262215, +149, +33, +6, +327752, +216, +0, +11, +0, +196679, +216, +2, +262215, +253, +30, +0, +262215, +260, +30, +2, +262215, +267, +30, +1, +262215, +284, +30, +3, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +2, +262176, +8, +7, +7, +262177, +9, +7, +8, +262167, +13, +6, +3, +262176, +14, +7, +13, +262177, +15, +13, +14, +262176, +19, +7, +6, +262187, +6, +25, +869711765, +131092, +26, +262187, +6, +35, +0, +327724, +7, +36, +35, +35, +393260, +13, +53, +35, +35, +35, +262165, +57, +32, +1, +262176, +58, +7, +57, +262176, +60, +1, +57, +262203, +60, +61, +1, +262187, +57, +63, +2, +262203, +60, +66, +1, +262165, +68, +32, +0, +262176, +69, +7, +68, +262187, +57, +72, +64, +262187, +57, +74, +1, +262187, +57, +79, +512, +262187, +68, +84, +512, +262187, +6, +91, +989855744, +589849, +96, +6, +1, +0, +0, +0, +1, +0, +262176, +97, +0, +96, +262203, +97, +98, +0, +131098, +100, +262176, +101, +0, +100, +262203, +101, +102, +0, +196635, +104, +96, +262167, +107, +6, +4, +262187, +6, +111, +1073741824, +262187, +6, +114, +1065353216, +589849, +118, +6, +5, +0, +0, +0, +1, +0, +196635, +119, +118, +262176, +120, +0, +119, +262203, +120, +121, +0, +262203, +120, +129, +0, +262168, +138, +107, +4, +1966110, +139, +138, +138, +138, +138, +13, +6, +107, +107, +107, +107, +107, +6, +6, +6, +6, +107, +6, +6, +6, +6, +57, +57, +57, +57, +6, +6, +6, +138, +262176, +140, +2, +139, +262203, +140, +141, +2, +262187, +57, +142, +17, +262176, +143, +2, +6, +262203, +120, +149, +0, +262187, +68, +154, +0, +262187, +57, +161, +4, +262176, +162, +2, +13, +262176, +171, +2, +138, +262187, +57, +185, +13, +262187, +6, +192, +1060487823, +262187, +6, +201, +3212836864, +262187, +57, +211, +14, +196638, +216, +107, +262176, +217, +3, +216, +262203, +217, +218, +3, +262187, +57, +219, +0, +262176, +228, +3, +107, +262187, +57, +236, +15, +262187, +68, +237, +1, +262187, +68, +246, +3, +262176, +247, +3, +6, +262203, +247, +253, +3, +262187, +68, +254, +2, +262203, +228, +260, +3, +262203, +228, +267, +3, +262203, +228, +284, +3, +327734, +2, +4, +0, +3, +131320, +5, +262203, +58, +59, +7, +262203, +58, +65, +7, +262203, +69, +70, +7, +262203, +8, +82, +7, +262203, +14, +93, +7, +262203, +14, +117, +7, +262203, +14, +127, +7, +262203, +19, +136, +7, +262203, +19, +137, +7, +262203, +14, +158, +7, +262203, +14, +168, +7, +262203, +8, +170, +7, +262203, +8, +180, +7, +262203, +19, +183, +7, +262203, +19, +184, +7, +262203, +19, +194, +7, +262203, +19, +195, +7, +262203, +14, +204, +7, +262205, +57, +62, +61, +327815, +57, +64, +62, +63, +196670, +59, +64, +262205, +57, +67, +66, +196670, +65, +67, +262205, +57, +71, +59, +327815, +57, +73, +71, +72, +327808, +57, +75, +73, +74, +262205, +57, +76, +65, +327808, +57, +77, +76, +74, +327812, +57, +78, +75, +77, +327819, +57, +80, +78, +79, +262268, +68, +81, +80, +196670, +70, +81, +262205, +68, +83, +70, +327817, +68, +85, +83, +84, +262256, +6, +86, +85, +262205, +68, +87, +70, +327814, +68, +88, +87, +84, +262256, +6, +89, +88, +327760, +7, +90, +86, +89, +327822, +7, +92, +90, +91, +196670, +82, +92, +262205, +57, +94, +65, +262255, +6, +95, +94, +262205, +96, +99, +98, +262205, +100, +103, +102, +327766, +104, +105, +99, +103, +262205, +7, +106, +82, +458840, +107, +108, +105, +106, +2, +35, +524367, +13, +109, +108, +108, +0, +1, +2, +327822, +13, +110, +109, +95, +196670, +93, +110, +262205, +13, +112, +93, +327822, +13, +113, +112, +111, +393296, +13, +115, +114, +114, +114, +327811, +13, +116, +113, +115, +196670, +93, +116, +262205, +119, +122, +121, +262205, +57, +123, +61, +327815, +57, +124, +123, +63, +327775, +107, +125, +122, +124, +524367, +13, +126, +125, +125, +0, +1, +2, +196670, +117, +126, +262205, +13, +128, +93, +262205, +119, +130, +129, +262205, +57, +131, +61, +327815, +57, +132, +131, +63, +327775, +107, +133, +130, +132, +524367, +13, +134, +133, +133, +0, +1, +2, +327809, +13, +135, +128, +134, +196670, +127, +135, +327745, +143, +144, +141, +142, +262205, +6, +145, +144, +327866, +26, +146, +145, +35, +196855, +148, +0, +262394, +146, +147, +156, +131320, +147, +262205, +119, +150, +149, +262205, +57, +151, +61, +327815, +57, +152, +151, +63, +327775, +107, +153, +150, +152, +327761, +6, +155, +153, +0, +196670, +137, +155, +131321, +148, +131320, +156, +196670, +137, +114, +131321, +148, +131320, +148, +262205, +6, +157, +137, +196670, +136, +157, +262205, +13, +159, +117, +262205, +13, +160, +127, +327745, +162, +163, +141, +161, +262205, +13, +164, +163, +327811, +13, +165, +160, +164, +393228, +13, +166, +1, +69, +165, +458764, +13, +167, +1, +68, +159, +166, +196670, +168, +167, +327737, +13, +169, +17, +168, +196670, +158, +169, +327745, +171, +172, +141, +74, +262205, +138, +173, +172, +262205, +13, +174, +158, +327761, +6, +175, +174, +0, +327761, +6, +176, +174, +1, +327761, +6, +177, +174, +2, +458832, +107, +178, +175, +176, +177, +35, +327825, +107, +179, +173, +178, +458831, +7, +181, +179, +179, +0, +1, +196670, +180, +181, +327737, +7, +182, +11, +180, +196670, +170, +182, +327745, +143, +186, +141, +185, +262205, +6, +187, +186, +327864, +26, +188, +187, +35, +196855, +190, +0, +262394, +188, +189, +191, +131320, +189, +196670, +184, +35, +131321, +190, +131320, +191, +196670, +184, +192, +131321, +190, +131320, +190, +262205, +6, +193, +184, +196670, +183, +193, +262205, +57, +196, +61, +327819, +57, +197, +196, +63, +327850, +26, +198, +197, +74, +196855, +200, +0, +262394, +198, +199, +202, +131320, +199, +196670, +195, +201, +131321, +200, +131320, +202, +196670, +195, +114, +131321, +200, +131320, +200, +262205, +6, +203, +195, +196670, +194, +203, +262205, +13, +205, +127, +262205, +6, +206, +194, +262205, +13, +207, +158, +327822, +13, +208, +207, +206, +262205, +6, +209, +136, +327822, +13, +210, +208, +209, +327745, +143, +212, +141, +211, +262205, +6, +213, +212, +327822, +13, +214, +210, +213, +327809, +13, +215, +205, +214, +196670, +204, +215, +327745, +171, +220, +141, +74, +262205, +138, +221, +220, +262205, +13, +222, +204, +327761, +6, +223, +222, +0, +327761, +6, +224, +222, +1, +327761, +6, +225, +222, +2, +458832, +107, +226, +223, +224, +225, +114, +327825, +107, +227, +221, +226, +327745, +228, +229, +218, +219, +196670, +229, +227, +327745, +228, +230, +218, +219, +262205, +107, +231, +230, +262205, +6, +232, +194, +262205, +7, +233, +170, +262205, +6, +234, +183, +327822, +7, +235, +233, +234, +393281, +143, +238, +141, +236, +237, +262205, +6, +239, +238, +327760, +7, +240, +239, +239, +327816, +7, +241, +235, +240, +327761, +6, +242, +241, +0, +327761, +6, +243, +241, +1, +458832, +107, +244, +242, +243, +35, +35, +327822, +107, +245, +244, +232, +393281, +247, +248, +218, +219, +246, +262205, +6, +249, +248, +327822, +107, +250, +245, +249, +327809, +107, +251, +231, +250, +327745, +228, +252, +218, +219, +196670, +252, +251, +393281, +247, +255, +218, +219, +254, +262205, +6, +256, +255, +393281, +247, +257, +218, +219, +246, +262205, +6, +258, +257, +327816, +6, +259, +256, +258, +196670, +253, +259, +262205, +13, +261, +117, +262205, +6, +262, +136, +327761, +6, +263, +261, +0, +327761, +6, +264, +261, +1, +327761, +6, +265, +261, +2, +458832, +107, +266, +263, +264, +265, +262, +196670, +260, +266, +262205, +13, +268, +127, +458831, +7, +269, +268, +268, +0, +1, +262205, +13, +270, +93, +458831, +7, +271, +270, +270, +0, +1, +262205, +119, +272, +129, +262205, +57, +273, +61, +327815, +57, +274, +273, +63, +327808, +57, +275, +274, +74, +327775, +107, +276, +272, +275, +458831, +7, +277, +276, +276, +0, +1, +327809, +7, +278, +271, +277, +327761, +6, +279, +269, +0, +327761, +6, +280, +269, +1, +327761, +6, +281, +278, +0, +327761, +6, +282, +278, +1, +458832, +107, +283, +279, +280, +281, +282, +196670, +267, +283, +65789, +65592, +327734, +7, +11, +0, +9, +196663, +8, +10, +131320, +12, +262203, +19, +20, +7, +262203, +8, +23, +7, +262205, +7, +21, +10, +393228, +6, +22, +1, +66, +21, +196670, +20, +22, +262205, +6, +24, +20, +327870, +26, +27, +24, +25, +196855, +29, +0, +262394, +27, +28, +34, +131320, +28, +262205, +7, +30, +10, +262205, +6, +31, +20, +327760, +7, +32, +31, +31, +327816, +7, +33, +30, +32, +196670, +23, +33, +131321, +29, +131320, +34, +196670, +23, +36, +131321, +29, +131320, +29, +262205, +7, +37, +23, +131326, +37, +65592, +327734, +13, +17, +0, +15, +196663, +14, +16, +131320, +18, +262203, +19, +40, +7, +262203, +14, +43, +7, +262205, +13, +41, +16, +393228, +6, +42, +1, +66, +41, +196670, +40, +42, +262205, +6, +44, +40, +327870, +26, +45, +44, +25, +196855, +47, +0, +262394, +45, +46, +52, +131320, +46, +262205, +13, +48, +16, +262205, +6, +49, +40, +393296, +13, +50, +49, +49, +49, +327816, +13, +51, +48, +50, +196670, +43, +51, +131321, +47, +131320, +52, +196670, +43, +53, +131321, +47, +131320, +47, +262205, +13, +54, +43, +131326, +54, +65592, +}; +const std::vector render_hair_aa_strand_copies_vertex = {119734787, +65536, +524289, +321, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +786447, +0, +4, +1852399981, +0, +61, +66, +244, +286, +293, +300, +320, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +458757, +11, +1701208403, +1919905375, +1768710509, +1982358906, +3879526, +196613, +10, +6514038, +458757, +17, +1701208403, +1919905375, +1768710509, +1982358906, +3879782, +196613, +16, +6514038, +196613, +20, +7234924, +196613, +40, +7234924, +262149, +59, +1701080681, +120, +393221, +61, +1449094247, +1702130277, +1684949368, +30821, +393221, +65, +1684955506, +1936090703, +1850307685, +7890276, +458757, +66, +1230990439, +1635021678, +1231381358, +2019910766, +0, +327685, +70, +1684366707, +1684955474, +0, +393221, +82, +1684366707, +1668834644, +1685221999, +0, +327685, +93, +1684955506, +1936090703, +29797, +327685, +98, +2020892519, +1936289614, +101, +393221, +102, +1634951015, +1852394605, +1467113829, +7364978, +262149, +117, +1735287124, +7630437, +524293, +121, +1632132967, +1700164201, +2019914866, +1735287124, +1937010277, +0, +196613, +127, +118, +524293, +129, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +262149, +136, +1769234802, +111, +327685, +139, +1936617283, +1953390964, +115, +393222, +139, +0, +1466785639, +1684828783, +0, +393222, +139, +1, +1450008423, +1350002025, +6975346, +458758, +139, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +139, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +139, +4, +1165385575, +25977, +327686, +139, +5, +1986420583, +7761734, +524294, +139, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +139, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +139, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +139, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +139, +10, +1632460647, +1633045364, +6649196, +458758, +139, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +139, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +139, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +139, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +139, +15, +1767333735, +2053722990, +101, +458758, +139, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +139, +17, +1415733095, +1416522088, +28777, +458758, +139, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +139, +19, +1181114215, +1766617697, +7628903, +393222, +139, +20, +1416191847, +1399350117, +77, +458758, +139, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +139, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +139, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +139, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +139, +25, +1214668647, +1265789281, +12915, +393222, +139, +26, +1214668647, +1165125985, +12920, +589830, +139, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +141, +0, +524293, +149, +1632132967, +1750364777, +1852531561, +1131639653, +1717986671, +115, +262149, +158, +1751607666, +116, +262149, +168, +1634886000, +109, +327685, +170, +1785688688, +1734963807, +29800, +262149, +180, +1634886000, +109, +393221, +183, +1634760805, +1766876270, +1936483704, +0, +458757, +195, +1919508840, +1701274693, +1769172816, +1852795252, +12403, +458757, +210, +1919508840, +1701274693, +1769172816, +1852795252, +12659, +327685, +232, +1919501414, +1701080649, +120, +393221, +242, +1348430951, +1700164197, +2019914866, +0, +393222, +242, +0, +1348430951, +1953067887, +7237481, +196613, +244, +0, +262149, +286, +1953523044, +104, +262149, +293, +1735287156, +7630437, +262149, +300, +829436016, +0, +327685, +320, +1634890867, +1866687598, +7499628, +262215, +61, +11, +42, +262215, +66, +11, +43, +262215, +98, +34, +0, +262215, +98, +33, +5, +262215, +102, +34, +0, +262215, +102, +33, +18, +262215, +121, +34, +1, +262215, +121, +33, +8, +262215, +129, +34, +1, +262215, +129, +33, +7, +262216, +139, +0, +5, +327752, +139, +0, +35, +0, +327752, +139, +0, +7, +16, +262216, +139, +1, +5, +327752, +139, +1, +35, +64, +327752, +139, +1, +7, +16, +262216, +139, +2, +5, +327752, +139, +2, +35, +128, +327752, +139, +2, +7, +16, +262216, +139, +3, +5, +327752, +139, +3, +35, +192, +327752, +139, +3, +7, +16, +327752, +139, +4, +35, +256, +327752, +139, +5, +35, +268, +327752, +139, +6, +35, +272, +327752, +139, +7, +35, +288, +327752, +139, +8, +35, +304, +327752, +139, +9, +35, +320, +327752, +139, +10, +35, +336, +327752, +139, +11, +35, +352, +327752, +139, +12, +35, +356, +327752, +139, +13, +35, +360, +327752, +139, +14, +35, +364, +327752, +139, +15, +35, +368, +327752, +139, +16, +35, +384, +327752, +139, +17, +35, +388, +327752, +139, +18, +35, +392, +327752, +139, +19, +35, +396, +327752, +139, +20, +35, +400, +327752, +139, +21, +35, +404, +327752, +139, +22, +35, +408, +327752, +139, +23, +35, +412, +327752, +139, +24, +35, +416, +327752, +139, +25, +35, +420, +327752, +139, +26, +35, +424, +262216, +139, +27, +5, +327752, +139, +27, +35, +432, +327752, +139, +27, +7, +16, +196679, +139, +2, +262215, +141, +34, +0, +262215, +141, +33, +16, +262215, +149, +34, +1, +262215, +149, +33, +6, +327752, +242, +0, +11, +0, +196679, +242, +2, +262215, +286, +30, +0, +262215, +293, +30, +2, +262215, +300, +30, +1, +262215, +320, +30, +3, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +2, +262176, +8, +7, +7, +262177, +9, +7, +8, +262167, +13, +6, +3, +262176, +14, +7, +13, +262177, +15, +13, +14, +262176, +19, +7, +6, +262187, +6, +25, +869711765, +131092, +26, +262187, +6, +35, +0, +327724, +7, +36, +35, +35, +393260, +13, +53, +35, +35, +35, +262165, +57, +32, +1, +262176, +58, +7, +57, +262176, +60, +1, +57, +262203, +60, +61, +1, +262187, +57, +63, +2, +262203, +60, +66, +1, +262165, +68, +32, +0, +262176, +69, +7, +68, +262187, +57, +72, +64, +262187, +57, +74, +1, +262187, +57, +79, +512, +262187, +68, +84, +512, +262187, +6, +91, +989855744, +589849, +96, +6, +1, +0, +0, +0, +1, +0, +262176, +97, +0, +96, +262203, +97, +98, +0, +131098, +100, +262176, +101, +0, +100, +262203, +101, +102, +0, +196635, +104, +96, +262167, +107, +6, +4, +262187, +6, +111, +1073741824, +262187, +6, +114, +1065353216, +589849, +118, +6, +5, +0, +0, +0, +1, +0, +196635, +119, +118, +262176, +120, +0, +119, +262203, +120, +121, +0, +262203, +120, +129, +0, +262168, +138, +107, +4, +1966110, +139, +138, +138, +138, +138, +13, +6, +107, +107, +107, +107, +107, +6, +6, +6, +6, +107, +6, +6, +6, +6, +57, +57, +57, +57, +6, +6, +6, +138, +262176, +140, +2, +139, +262203, +140, +141, +2, +262187, +57, +142, +17, +262176, +143, +2, +6, +262203, +120, +149, +0, +262187, +68, +154, +0, +262187, +57, +161, +4, +262176, +162, +2, +13, +262176, +171, +2, +138, +262187, +57, +185, +13, +262187, +6, +192, +1060487823, +262176, +194, +7, +107, +262187, +57, +201, +14, +262187, +6, +239, +3212836864, +196638, +242, +107, +262176, +243, +3, +242, +262203, +243, +244, +3, +262187, +57, +245, +0, +262187, +57, +259, +15, +262187, +68, +260, +1, +262187, +68, +274, +3, +262176, +283, +3, +107, +262176, +285, +3, +6, +262203, +285, +286, +3, +262187, +68, +287, +2, +262203, +283, +293, +3, +262203, +283, +300, +3, +262203, +283, +320, +3, +327734, +2, +4, +0, +3, +131320, +5, +262203, +58, +59, +7, +262203, +58, +65, +7, +262203, +69, +70, +7, +262203, +8, +82, +7, +262203, +14, +93, +7, +262203, +14, +117, +7, +262203, +14, +127, +7, +262203, +19, +136, +7, +262203, +19, +137, +7, +262203, +14, +158, +7, +262203, +14, +168, +7, +262203, +8, +170, +7, +262203, +8, +180, +7, +262203, +19, +183, +7, +262203, +19, +184, +7, +262203, +194, +195, +7, +262203, +194, +210, +7, +262203, +19, +232, +7, +262203, +19, +233, +7, +262203, +194, +246, +7, +262203, +19, +269, +7, +262205, +57, +62, +61, +327815, +57, +64, +62, +63, +196670, +59, +64, +262205, +57, +67, +66, +196670, +65, +67, +262205, +57, +71, +59, +327815, +57, +73, +71, +72, +327808, +57, +75, +73, +74, +262205, +57, +76, +65, +327808, +57, +77, +76, +74, +327812, +57, +78, +75, +77, +327819, +57, +80, +78, +79, +262268, +68, +81, +80, +196670, +70, +81, +262205, +68, +83, +70, +327817, +68, +85, +83, +84, +262256, +6, +86, +85, +262205, +68, +87, +70, +327814, +68, +88, +87, +84, +262256, +6, +89, +88, +327760, +7, +90, +86, +89, +327822, +7, +92, +90, +91, +196670, +82, +92, +262205, +57, +94, +65, +262255, +6, +95, +94, +262205, +96, +99, +98, +262205, +100, +103, +102, +327766, +104, +105, +99, +103, +262205, +7, +106, +82, +458840, +107, +108, +105, +106, +2, +35, +524367, +13, +109, +108, +108, +0, +1, +2, +327822, +13, +110, +109, +95, +196670, +93, +110, +262205, +13, +112, +93, +327822, +13, +113, +112, +111, +393296, +13, +115, +114, +114, +114, +327811, +13, +116, +113, +115, +196670, +93, +116, +262205, +119, +122, +121, +262205, +57, +123, +61, +327815, +57, +124, +123, +63, +327775, +107, +125, +122, +124, +524367, +13, +126, +125, +125, +0, +1, +2, +196670, +117, +126, +262205, +13, +128, +93, +262205, +119, +130, +129, +262205, +57, +131, +61, +327815, +57, +132, +131, +63, +327775, +107, +133, +130, +132, +524367, +13, +134, +133, +133, +0, +1, +2, +327809, +13, +135, +128, +134, +196670, +127, +135, +327745, +143, +144, +141, +142, +262205, +6, +145, +144, +327866, +26, +146, +145, +35, +196855, +148, +0, +262394, +146, +147, +156, +131320, +147, +262205, +119, +150, +149, +262205, +57, +151, +61, +327815, +57, +152, +151, +63, +327775, +107, +153, +150, +152, +327761, +6, +155, +153, +0, +196670, +137, +155, +131321, +148, +131320, +156, +196670, +137, +114, +131321, +148, +131320, +148, +262205, +6, +157, +137, +196670, +136, +157, +262205, +13, +159, +117, +262205, +13, +160, +127, +327745, +162, +163, +141, +161, +262205, +13, +164, +163, +327811, +13, +165, +160, +164, +393228, +13, +166, +1, +69, +165, +458764, +13, +167, +1, +68, +159, +166, +196670, +168, +167, +327737, +13, +169, +17, +168, +196670, +158, +169, +327745, +171, +172, +141, +74, +262205, +138, +173, +172, +262205, +13, +174, +158, +327761, +6, +175, +174, +0, +327761, +6, +176, +174, +1, +327761, +6, +177, +174, +2, +458832, +107, +178, +175, +176, +177, +35, +327825, +107, +179, +173, +178, +458831, +7, +181, +179, +179, +0, +1, +196670, +180, +181, +327737, +7, +182, +11, +180, +196670, +170, +182, +327745, +143, +186, +141, +185, +262205, +6, +187, +186, +327864, +26, +188, +187, +35, +196855, +190, +0, +262394, +188, +189, +191, +131320, +189, +196670, +184, +35, +131321, +190, +131320, +191, +196670, +184, +192, +131321, +190, +131320, +190, +262205, +6, +193, +184, +196670, +183, +193, +262205, +13, +196, +127, +262205, +13, +197, +158, +327822, +13, +198, +197, +114, +262205, +6, +199, +136, +327822, +13, +200, +198, +199, +327745, +143, +202, +141, +201, +262205, +6, +203, +202, +327822, +13, +204, +200, +203, +327811, +13, +205, +196, +204, +327761, +6, +206, +205, +0, +327761, +6, +207, +205, +1, +327761, +6, +208, +205, +2, +458832, +107, +209, +206, +207, +208, +114, +196670, +195, +209, +262205, +13, +211, +127, +262205, +13, +212, +158, +327822, +13, +213, +212, +114, +262205, +6, +214, +136, +327822, +13, +215, +213, +214, +327745, +143, +216, +141, +201, +262205, +6, +217, +216, +327822, +13, +218, +215, +217, +327809, +13, +219, +211, +218, +327761, +6, +220, +219, +0, +327761, +6, +221, +219, +1, +327761, +6, +222, +219, +2, +458832, +107, +223, +220, +221, +222, +114, +196670, +210, +223, +327745, +171, +224, +141, +74, +262205, +138, +225, +224, +262205, +107, +226, +195, +327825, +107, +227, +225, +226, +196670, +195, +227, +327745, +171, +228, +141, +74, +262205, +138, +229, +228, +262205, +107, +230, +210, +327825, +107, +231, +229, +230, +196670, +210, +231, +262205, +57, +234, +61, +327819, +57, +235, +234, +63, +327850, +26, +236, +235, +74, +196855, +238, +0, +262394, +236, +237, +240, +131320, +237, +196670, +233, +239, +131321, +238, +131320, +240, +196670, +233, +114, +131321, +238, +131320, +238, +262205, +6, +241, +233, +196670, +232, +241, +262205, +6, +247, +232, +327860, +26, +248, +247, +239, +196855, +250, +0, +262394, +248, +249, +252, +131320, +249, +262205, +107, +251, +195, +196670, +246, +251, +131321, +250, +131320, +252, +262205, +107, +253, +210, +196670, +246, +253, +131321, +250, +131320, +250, +262205, +107, +254, +246, +262205, +6, +255, +232, +262205, +7, +256, +170, +262205, +6, +257, +183, +327822, +7, +258, +256, +257, +393281, +143, +261, +141, +259, +260, +262205, +6, +262, +261, +327760, +7, +263, +262, +262, +327816, +7, +264, +258, +263, +327761, +6, +265, +264, +0, +327761, +6, +266, +264, +1, +458832, +107, +267, +265, +266, +35, +35, +327822, +107, +268, +267, +255, +262205, +6, +270, +232, +327860, +26, +271, +270, +239, +196855, +273, +0, +262394, +271, +272, +277, +131320, +272, +327745, +19, +275, +195, +274, +262205, +6, +276, +275, +196670, +269, +276, +131321, +273, +131320, +277, +327745, +19, +278, +210, +274, +262205, +6, +279, +278, +196670, +269, +279, +131321, +273, +131320, +273, +262205, +6, +280, +269, +327822, +107, +281, +268, +280, +327809, +107, +282, +254, +281, +327745, +283, +284, +244, +245, +196670, +284, +282, +393281, +285, +288, +244, +245, +287, +262205, +6, +289, +288, +393281, +285, +290, +244, +245, +274, +262205, +6, +291, +290, +327816, +6, +292, +289, +291, +196670, +286, +292, +262205, +13, +294, +117, +262205, +6, +295, +136, +327761, +6, +296, +294, +0, +327761, +6, +297, +294, +1, +327761, +6, +298, +294, +2, +458832, +107, +299, +296, +297, +298, +295, +196670, +293, +299, +262205, +107, +301, +195, +458831, +7, +302, +301, +301, +0, +1, +327745, +19, +303, +195, +274, +262205, +6, +304, +303, +458764, +6, +305, +1, +40, +304, +25, +327760, +7, +306, +305, +305, +327816, +7, +307, +302, +306, +262205, +107, +308, +210, +458831, +7, +309, +308, +308, +0, +1, +327745, +19, +310, +210, +274, +262205, +6, +311, +310, +458764, +6, +312, +1, +40, +311, +25, +327760, +7, +313, +312, +312, +327816, +7, +314, +309, +313, +327761, +6, +315, +307, +0, +327761, +6, +316, +307, +1, +327761, +6, +317, +314, +0, +327761, +6, +318, +314, +1, +458832, +107, +319, +315, +316, +317, +318, +196670, +300, +319, +65789, +65592, +327734, +7, +11, +0, +9, +196663, +8, +10, +131320, +12, +262203, +19, +20, +7, +262203, +8, +23, +7, +262205, +7, +21, +10, +393228, +6, +22, +1, +66, +21, +196670, +20, +22, +262205, +6, +24, +20, +327870, +26, +27, +24, +25, +196855, +29, +0, +262394, +27, +28, +34, +131320, +28, +262205, +7, +30, +10, +262205, +6, +31, +20, +327760, +7, +32, +31, +31, +327816, +7, +33, +30, +32, +196670, +23, +33, +131321, +29, +131320, +34, +196670, +23, +36, +131321, +29, +131320, +29, +262205, +7, +37, +23, +131326, +37, +65592, +327734, +13, +17, +0, +15, +196663, +14, +16, +131320, +18, +262203, +19, +40, +7, +262203, +14, +43, +7, +262205, +13, +41, +16, +393228, +6, +42, +1, +66, +41, +196670, +40, +42, +262205, +6, +44, +40, +327870, +26, +45, +44, +25, +196855, +47, +0, +262394, +45, +46, +52, +131320, +46, +262205, +13, +48, +16, +262205, +6, +49, +40, +393296, +13, +50, +49, +49, +49, +327816, +13, +51, +48, +50, +196670, +43, +51, +131321, +47, +131320, +52, +196670, +43, +53, +131321, +47, +131320, +47, +262205, +13, +54, +43, +131326, +54, +65592, +}; +const std::vector pass1_fragment = {119734787, +65536, +524289, +346, +0, +131089, +1, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +589839, +4, +4, +1852399981, +0, +276, +308, +332, +345, +196624, +4, +7, +196624, +4, +9, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +262149, +4, +1852399981, +0, +524293, +12, +1801675088, +1634692166, +1850291316, +1767206772, +1982362734, +3880038, +262149, +11, +1818318454, +25973, +589829, +17, +1634758229, +1767205731, +1850307694, +1816555380, +880042351, +993097000, +0, +262149, +16, +1818318453, +25973, +655365, +25, +1801675088, +1735287124, +1098149477, +1866687598, +1634887030, +1982358887, +1715155814, +15153, +262149, +23, +1735287156, +7630437, +327685, +24, +1702260579, +1701273970, +0, +393221, +29, +1416914247, +1701277281, +1965585518, +15153, +393221, +28, +1801675120, +1632920677, +1852139374, +116, +393221, +33, +1131701575, +1919252079, +677734241, +3879285, +393221, +32, +1801675120, +1866687589, +1634887030, +25959, +655365, +41, +1886220099, +1130722421, +1919252079, +677734241, +993158774, +993158774, +993158774, +0, +196613, +38, +12400, +196613, +39, +12656, +327685, +40, +1702390128, +1668238444, +0, +720901, +48, +1919906899, +1634879077, +1852140903, +1214215028, +678586721, +993158774, +993224310, +1715155302, +15153, +327685, +44, +1734439494, +1919905603, +5855332, +262149, +45, +1735287124, +7630437, +327685, +46, +1702260547, +1701273970, +0, +262149, +47, +1953523044, +104, +262149, +50, +1702132066, +51, +262149, +59, +1702132066, +50, +262149, +66, +1702132066, +49, +262149, +73, +1702132066, +48, +262149, +131, +1634886000, +109, +262149, +136, +1634886000, +109, +262149, +146, +1634886000, +109, +327685, +153, +1936617283, +1953390964, +115, +393222, +153, +0, +1466785639, +1684828783, +0, +393222, +153, +1, +1450008423, +1350002025, +6975346, +458758, +153, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +153, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +153, +4, +1165385575, +25977, +327686, +153, +5, +1986420583, +7761734, +524294, +153, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +153, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +153, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +153, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +153, +10, +1632460647, +1633045364, +6649196, +458758, +153, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +153, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +153, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +153, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +153, +15, +1767333735, +2053722990, +101, +458758, +153, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +153, +17, +1415733095, +1416522088, +28777, +458758, +153, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +153, +19, +1181114215, +1766617697, +7628903, +393222, +153, +20, +1416191847, +1399350117, +77, +458758, +153, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +153, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +153, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +153, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +153, +25, +1214668647, +1265789281, +12915, +393222, +153, +26, +1214668647, +1165125985, +12920, +589830, +153, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +155, +0, +262149, +178, +1768173680, +29811, +262149, +183, +1768173936, +29811, +327685, +188, +1919508840, +1952737623, +104, +262149, +195, +1937012079, +6644841, +262149, +208, +1852270963, +0, +262149, +215, +1147954546, +7631721, +327685, +227, +1702390128, +1684627308, +0, +393221, +228, +1836020801, +1967285097, +1919247974, +0, +393222, +228, +0, +1702390096, +1970226028, +29806, +196613, +230, +0, +262149, +236, +1684633712, +0, +196613, +241, +7763305, +196613, +244, +7368052, +524293, +247, +1349674320, +1818589289, +1802398028, +1766614117, +1699247219, +25697, +458757, +253, +1349674320, +1818589289, +1953720652, +1801680194, +29797, +327686, +253, +0, +1953523044, +104, +524294, +253, +1, +1735287124, +1098149477, +1866687598, +1634887030, +25959, +327686, +253, +2, +1954047342, +0, +458757, +255, +1349674320, +1818589289, +1802398028, +1766614117, +29811, +327686, +255, +0, +1280069712, +0, +196613, +257, +0, +262149, +264, +1634886000, +109, +262149, +266, +1634886000, +109, +327685, +274, +1785688688, +1936683103, +0, +393221, +276, +1180658791, +1130848626, +1685221231, +0, +393221, +293, +1734963823, +1818324585, +1936683103, +0, +327685, +299, +1702260579, +1701273970, +0, +262149, +308, +829436016, +0, +262149, +309, +1634886000, +109, +262149, +312, +1634886000, +109, +262149, +315, +1634886000, +109, +262149, +332, +1735287156, +7630437, +262149, +333, +1634886000, +109, +262149, +336, +1634886000, +109, +262149, +339, +1634886000, +109, +262149, +341, +1634886000, +109, +262149, +345, +1953523044, +104, +262216, +153, +0, +5, +327752, +153, +0, +35, +0, +327752, +153, +0, +7, +16, +262216, +153, +1, +5, +327752, +153, +1, +35, +64, +327752, +153, +1, +7, +16, +262216, +153, +2, +5, +327752, +153, +2, +35, +128, +327752, +153, +2, +7, +16, +262216, +153, +3, +5, +327752, +153, +3, +35, +192, +327752, +153, +3, +7, +16, +327752, +153, +4, +35, +256, +327752, +153, +5, +35, +268, +327752, +153, +6, +35, +272, +327752, +153, +7, +35, +288, +327752, +153, +8, +35, +304, +327752, +153, +9, +35, +320, +327752, +153, +10, +35, +336, +327752, +153, +11, +35, +352, +327752, +153, +12, +35, +356, +327752, +153, +13, +35, +360, +327752, +153, +14, +35, +364, +327752, +153, +15, +35, +368, +327752, +153, +16, +35, +384, +327752, +153, +17, +35, +388, +327752, +153, +18, +35, +392, +327752, +153, +19, +35, +396, +327752, +153, +20, +35, +400, +327752, +153, +21, +35, +404, +327752, +153, +22, +35, +408, +327752, +153, +23, +35, +412, +327752, +153, +24, +35, +416, +327752, +153, +25, +35, +420, +327752, +153, +26, +35, +424, +262216, +153, +27, +5, +327752, +153, +27, +35, +432, +327752, +153, +27, +7, +16, +196679, +153, +2, +262215, +155, +34, +0, +262215, +155, +33, +16, +327752, +228, +0, +35, +0, +196679, +228, +3, +262215, +230, +34, +0, +262215, +230, +33, +17, +262215, +247, +34, +0, +262215, +247, +33, +1, +196679, +247, +19, +327752, +253, +0, +35, +0, +327752, +253, +1, +35, +4, +327752, +253, +2, +35, +8, +262215, +254, +6, +12, +327752, +255, +0, +35, +0, +196679, +255, +3, +262215, +257, +34, +0, +262215, +257, +33, +0, +262215, +276, +11, +15, +262215, +308, +30, +1, +262215, +332, +30, +2, +262215, +345, +30, +0, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +262165, +9, +32, +0, +262177, +10, +9, +8, +262176, +14, +7, +9, +262177, +15, +7, +14, +262167, +19, +6, +3, +262176, +20, +7, +19, +262176, +21, +7, +6, +327713, +22, +9, +20, +21, +262177, +27, +19, +14, +262177, +31, +6, +14, +262167, +35, +6, +2, +262176, +36, +7, +35, +393249, +37, +6, +36, +36, +36, +458785, +43, +2, +36, +20, +21, +21, +262187, +9, +51, +0, +262187, +6, +54, +1132396544, +262187, +9, +57, +255, +262187, +9, +60, +1, +262187, +9, +67, +2, +262187, +9, +74, +3, +262165, +81, +32, +1, +262187, +81, +82, +24, +262187, +81, +85, +16, +262187, +81, +89, +8, +262187, +9, +97, +4278190080, +262187, +9, +103, +16711680, +262187, +9, +109, +65280, +262187, +6, +122, +1056964608, +262187, +6, +135, +1073741824, +262187, +6, +141, +1065353216, +262168, +152, +7, +4, +1966110, +153, +152, +152, +152, +152, +19, +6, +7, +7, +7, +7, +7, +6, +6, +6, +6, +7, +6, +6, +6, +6, +81, +81, +81, +81, +6, +6, +6, +152, +262176, +154, +2, +153, +262203, +154, +155, +2, +262187, +81, +156, +15, +262176, +157, +2, +7, +262187, +6, +168, +3212836864, +131092, +193, +262176, +194, +7, +193, +262187, +6, +199, +0, +262167, +205, +193, +2, +196638, +228, +9, +262176, +229, +2, +228, +262203, +229, +230, +2, +262187, +81, +231, +0, +262176, +232, +2, +9, +262176, +235, +7, +81, +262167, +239, +81, +2, +262176, +240, +7, +239, +589849, +245, +9, +1, +0, +0, +0, +2, +33, +262176, +246, +0, +245, +262203, +246, +247, +0, +262176, +250, +11, +9, +327710, +253, +6, +9, +9, +196637, +254, +253, +196638, +255, +254, +262176, +256, +2, +255, +262203, +256, +257, +2, +262176, +260, +2, +6, +262187, +81, +263, +1, +262187, +81, +271, +2, +262176, +275, +1, +7, +262203, +275, +276, +1, +262176, +277, +1, +6, +262176, +294, +2, +152, +262187, +81, +301, +21, +262176, +302, +2, +81, +262203, +275, +308, +1, +262187, +81, +321, +11, +262203, +275, +332, +1, +262203, +277, +345, +1, +327734, +2, +4, +0, +3, +131320, +5, +262203, +8, +274, +7, +262203, +8, +293, +7, +262203, +21, +299, +7, +262203, +21, +300, +7, +262203, +36, +309, +7, +262203, +36, +312, +7, +262203, +36, +315, +7, +262203, +36, +333, +7, +262203, +20, +336, +7, +262203, +21, +339, +7, +262203, +21, +341, +7, +327745, +277, +278, +276, +51, +262205, +6, +279, +278, +327813, +6, +280, +135, +279, +393281, +260, +281, +155, +156, +67, +262205, +6, +282, +281, +327813, +6, +283, +280, +282, +327811, +6, +284, +283, +141, +327745, +277, +285, +276, +60, +262205, +6, +286, +285, +327813, +6, +287, +135, +286, +393281, +260, +288, +155, +156, +74, +262205, +6, +289, +288, +327813, +6, +290, +287, +289, +327811, +6, +291, +141, +290, +458832, +7, +292, +284, +291, +141, +141, +196670, +274, +292, +327745, +294, +295, +155, +271, +262205, +152, +296, +295, +262205, +7, +297, +274, +327825, +7, +298, +296, +297, +196670, +293, +298, +327745, +302, +303, +155, +301, +262205, +81, +304, +303, +327851, +193, +305, +304, +231, +196855, +307, +0, +262394, +305, +306, +319, +131320, +306, +262205, +7, +310, +308, +458831, +35, +311, +310, +310, +0, +1, +196670, +309, +311, +262205, +7, +313, +308, +458831, +35, +314, +313, +313, +2, +3, +196670, +312, +314, +262205, +7, +316, +274, +458831, +35, +317, +316, +316, +0, +1, +196670, +315, +317, +458809, +6, +318, +41, +309, +312, +315, +196670, +300, +318, +131321, +307, +131320, +319, +196670, +300, +141, +131321, +307, +131320, +307, +262205, +6, +320, +300, +196670, +299, +320, +327745, +260, +322, +155, +321, +262205, +6, +323, +322, +262205, +6, +324, +299, +327813, +6, +325, +324, +323, +196670, +299, +325, +262205, +6, +326, +299, +327745, +260, +327, +155, +82, +262205, +6, +328, +327, +327866, +193, +329, +326, +328, +196855, +331, +0, +262394, +329, +330, +331, +131320, +330, +262205, +7, +334, +276, +458831, +35, +335, +334, +334, +0, +1, +196670, +333, +335, +262205, +7, +337, +332, +524367, +19, +338, +337, +337, +0, +1, +2, +196670, +336, +338, +262205, +6, +340, +299, +196670, +339, +340, +327745, +277, +342, +276, +67, +262205, +6, +343, +342, +196670, +341, +343, +524345, +2, +344, +48, +333, +336, +339, +341, +131321, +331, +131320, +331, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +262203, +14, +50, +7, +262203, +14, +59, +7, +262203, +14, +66, +7, +262203, +14, +73, +7, +327745, +21, +52, +11, +51, +262205, +6, +53, +52, +327813, +6, +55, +53, +54, +262253, +9, +56, +55, +327879, +9, +58, +56, +57, +196670, +50, +58, +327745, +21, +61, +11, +60, +262205, +6, +62, +61, +327813, +6, +63, +62, +54, +262253, +9, +64, +63, +327879, +9, +65, +64, +57, +196670, +59, +65, +327745, +21, +68, +11, +67, +262205, +6, +69, +68, +327813, +6, +70, +69, +54, +262253, +9, +71, +70, +327879, +9, +72, +71, +57, +196670, +66, +72, +327745, +21, +75, +11, +74, +262205, +6, +76, +75, +327813, +6, +77, +76, +54, +262253, +9, +78, +77, +327879, +9, +79, +78, +57, +196670, +73, +79, +262205, +9, +80, +50, +327876, +9, +83, +80, +82, +262205, +9, +84, +59, +327876, +9, +86, +84, +85, +327877, +9, +87, +83, +86, +262205, +9, +88, +66, +327876, +9, +90, +88, +89, +327877, +9, +91, +87, +90, +262205, +9, +92, +73, +327877, +9, +93, +91, +92, +131326, +93, +65592, +327734, +7, +17, +0, +15, +196663, +14, +16, +131320, +18, +262205, +9, +96, +16, +327879, +9, +98, +96, +97, +327874, +9, +99, +98, +82, +262256, +6, +100, +99, +327816, +6, +101, +100, +54, +262205, +9, +102, +16, +327879, +9, +104, +102, +103, +327874, +9, +105, +104, +85, +262256, +6, +106, +105, +327816, +6, +107, +106, +54, +262205, +9, +108, +16, +327879, +9, +110, +108, +109, +327874, +9, +111, +110, +89, +262256, +6, +112, +111, +327816, +6, +113, +112, +54, +262205, +9, +114, +16, +327879, +9, +115, +114, +57, +262256, +6, +116, +115, +327816, +6, +117, +116, +54, +458832, +7, +118, +101, +107, +113, +117, +131326, +118, +65592, +327734, +9, +25, +0, +22, +196663, +20, +23, +196663, +21, +24, +131320, +26, +262203, +8, +131, +7, +262205, +19, +121, +23, +327822, +19, +123, +121, +122, +393296, +19, +124, +122, +122, +122, +327809, +19, +125, +123, +124, +262205, +6, +126, +24, +327761, +6, +127, +125, +0, +327761, +6, +128, +125, +1, +327761, +6, +129, +125, +2, +458832, +7, +130, +127, +128, +129, +126, +196670, +131, +130, +327737, +9, +132, +12, +131, +131326, +132, +65592, +327734, +19, +29, +0, +27, +196663, +14, +28, +131320, +30, +262203, +14, +136, +7, +262205, +9, +137, +28, +196670, +136, +137, +327737, +7, +138, +17, +136, +524367, +19, +139, +138, +138, +0, +1, +2, +327822, +19, +140, +139, +135, +393296, +19, +142, +141, +141, +141, +327811, +19, +143, +140, +142, +131326, +143, +65592, +327734, +6, +33, +0, +31, +196663, +14, +32, +131320, +34, +262203, +14, +146, +7, +262205, +9, +147, +32, +196670, +146, +147, +327737, +7, +148, +17, +146, +327761, +6, +149, +148, +3, +131326, +149, +65592, +327734, +6, +41, +0, +37, +196663, +36, +38, +196663, +36, +39, +196663, +36, +40, +131320, +42, +262203, +21, +178, +7, +262203, +21, +183, +7, +262203, +21, +188, +7, +262203, +194, +195, +7, +262203, +21, +208, +7, +262203, +21, +209, +7, +262203, +21, +215, +7, +327745, +157, +158, +155, +156, +262205, +7, +159, +158, +458831, +35, +160, +159, +159, +0, +1, +262205, +35, +161, +38, +327813, +35, +162, +161, +160, +196670, +38, +162, +327745, +157, +163, +155, +156, +262205, +7, +164, +163, +458831, +35, +165, +164, +164, +0, +1, +262205, +35, +166, +39, +327813, +35, +167, +166, +165, +196670, +39, +167, +327745, +21, +169, +40, +60, +262205, +6, +170, +169, +327813, +6, +171, +170, +168, +327745, +21, +172, +40, +60, +196670, +172, +171, +327745, +157, +173, +155, +156, +262205, +7, +174, +173, +458831, +35, +175, +174, +174, +0, +1, +262205, +35, +176, +40, +327813, +35, +177, +176, +175, +196670, +40, +177, +262205, +35, +179, +38, +262205, +35, +180, +40, +327811, +35, +181, +179, +180, +393228, +6, +182, +1, +66, +181, +196670, +178, +182, +262205, +35, +184, +39, +262205, +35, +185, +40, +327811, +35, +186, +184, +185, +393228, +6, +187, +1, +66, +186, +196670, +183, +187, +262205, +35, +189, +38, +262205, +35, +190, +39, +327811, +35, +191, +189, +190, +393228, +6, +192, +1, +66, +191, +196670, +188, +192, +262205, +6, +196, +188, +262205, +6, +197, +178, +458764, +6, +198, +1, +48, +196, +197, +327866, +193, +200, +198, +199, +262205, +6, +201, +188, +262205, +6, +202, +183, +458764, +6, +203, +1, +48, +201, +202, +327866, +193, +204, +203, +199, +327760, +205, +206, +200, +204, +262298, +193, +207, +206, +196670, +195, +207, +262205, +193, +210, +195, +196855, +212, +0, +262394, +210, +211, +213, +131320, +211, +196670, +209, +168, +131321, +212, +131320, +213, +196670, +209, +141, +131321, +212, +131320, +212, +262205, +6, +214, +209, +196670, +208, +214, +262205, +6, +216, +208, +262205, +6, +217, +178, +262205, +6, +218, +183, +458764, +6, +219, +1, +37, +217, +218, +524300, +6, +220, +1, +43, +219, +199, +141, +327813, +6, +221, +216, +220, +196670, +215, +221, +262205, +6, +222, +215, +327809, +6, +223, +222, +141, +327813, +6, +224, +223, +122, +131326, +224, +65592, +327734, +2, +48, +0, +43, +196663, +36, +44, +196663, +20, +45, +196663, +21, +46, +196663, +21, +47, +131320, +49, +262203, +14, +227, +7, +262203, +235, +236, +7, +262203, +240, +241, +7, +262203, +14, +244, +7, +262203, +20, +264, +7, +262203, +21, +266, +7, +327745, +232, +233, +230, +231, +458986, +9, +234, +233, +60, +51, +60, +196670, +227, +234, +262205, +9, +237, +227, +262268, +81, +238, +237, +196670, +236, +238, +262205, +35, +242, +44, +262254, +239, +243, +242, +196670, +241, +243, +262205, +239, +248, +241, +262205, +9, +249, +227, +393276, +250, +251, +247, +248, +51, +458981, +9, +252, +251, +60, +51, +249, +196670, +244, +252, +262205, +81, +258, +236, +262205, +6, +259, +47, +458817, +260, +261, +257, +231, +258, +231, +196670, +261, +259, +262205, +81, +262, +236, +262205, +19, +265, +45, +196670, +264, +265, +262205, +6, +267, +46, +196670, +266, +267, +393273, +9, +268, +25, +264, +266, +458817, +232, +269, +257, +231, +262, +263, +196670, +269, +268, +262205, +81, +270, +236, +262205, +9, +272, +244, +458817, +232, +273, +257, +231, +270, +271, +196670, +273, +272, +65789, +65592, +}; +const std::vector pass2_vertex = {119734787, +65536, +524289, +31, +0, +131089, +1, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +589839, +0, +4, +1852399981, +0, +10, +14, +27, +28, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +262149, +4, +1852399981, +0, +393221, +8, +1348430951, +1700164197, +2019914866, +0, +393222, +8, +0, +1348430951, +1953067887, +7237481, +196613, +10, +0, +327685, +14, +1769172816, +1852795252, +0, +262149, +27, +2019906678, +0, +327685, +28, +1668834644, +1685221231, +0, +327752, +8, +0, +11, +0, +196679, +8, +2, +262215, +14, +30, +0, +262215, +27, +30, +0, +262215, +28, +30, +1, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +196638, +8, +7, +262176, +9, +3, +8, +262203, +9, +10, +3, +262165, +11, +32, +1, +262187, +11, +12, +0, +262176, +13, +1, +7, +262203, +13, +14, +1, +262167, +15, +6, +3, +262187, +6, +18, +1065353216, +262176, +23, +3, +7, +262167, +25, +6, +2, +262176, +26, +3, +25, +262203, +26, +27, +3, +262203, +13, +28, +1, +327734, +2, +4, +0, +3, +131320, +5, +262205, +7, +16, +14, +524367, +15, +17, +16, +16, +0, +1, +2, +327761, +6, +19, +17, +0, +327761, +6, +20, +17, +1, +327761, +6, +21, +17, +2, +458832, +7, +22, +19, +20, +21, +18, +327745, +23, +24, +10, +12, +196670, +24, +22, +262205, +7, +29, +28, +458831, +25, +30, +29, +29, +0, +1, +196670, +27, +30, +65789, +65592, +}; +const std::vector pass2_fragment = {119734787, +65536, +524289, +1047, +0, +131089, +1, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +4, +4, +1852399981, +0, +655, +1045, +196624, +4, +7, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +262149, +4, +1852399981, +0, +524293, +12, +1801675088, +1634692166, +1850291316, +1767206772, +1982362734, +3880038, +262149, +11, +1818318454, +25973, +589829, +17, +1634758229, +1767205731, +1850307694, +1816555380, +880042351, +993097000, +0, +262149, +16, +1818318453, +25973, +655365, +25, +1801675088, +1735287124, +1098149477, +1866687598, +1634887030, +1982358887, +1715155814, +15153, +262149, +23, +1735287156, +7630437, +327685, +24, +1702260579, +1701273970, +0, +393221, +29, +1416914247, +1701277281, +1965585518, +15153, +393221, +28, +1801675120, +1632920677, +1852139374, +116, +393221, +33, +1131701575, +1919252079, +677734241, +3879285, +393221, +32, +1801675120, +1866687589, +1634887030, +25959, +524293, +38, +1886220099, +1399157877, +1868849512, +1719019639, +828783411, +59, +327685, +36, +1819438967, +1936674916, +0, +262149, +37, +1752198241, +97, +589829, +42, +1886220099, +1399157877, +1819307369, +1634227045, +678915940, +993224310, +3879270, +327685, +40, +1819438967, +1936674916, +0, +262149, +41, +1752198241, +97, +786437, +50, +1886220099, +1214608501, +1400007009, +1768186216, +1982359406, +1983591270, +1983591270, +1715156070, +1719024433, +15155, +262149, +45, +1936674921, +0, +327685, +46, +1851872361, +1953391975, +0, +262149, +47, +2019906665, +0, +327685, +48, +1970236769, +1766618222, +7628903, +262149, +49, +1869377379, +114, +720901, +57, +1886218579, +1632134508, +1750299241, +1852400737, +1719019623, +1719024435, +1719024435, +828783412, +59, +262149, +53, +1936674921, +0, +327685, +54, +1851872361, +1953391975, +0, +262149, +55, +2019906665, +0, +327685, +56, +1970236769, +1766618222, +7628903, +262149, +59, +1702132066, +51, +262149, +68, +1702132066, +50, +262149, +75, +1702132066, +49, +262149, +82, +1702132066, +48, +262149, +140, +1634886000, +109, +262149, +145, +1634886000, +109, +262149, +155, +1634886000, +109, +393221, +161, +1785688688, +1282633552, +1952999273, +0, +327685, +163, +1936617283, +1953390964, +115, +393222, +163, +0, +1466785639, +1684828783, +0, +393222, +163, +1, +1450008423, +1350002025, +6975346, +458758, +163, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +163, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +163, +4, +1165385575, +25977, +327686, +163, +5, +1986420583, +7761734, +524294, +163, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +163, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +163, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +163, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +163, +10, +1632460647, +1633045364, +6649196, +458758, +163, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +163, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +163, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +163, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +163, +15, +1767333735, +2053722990, +101, +458758, +163, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +163, +17, +1415733095, +1416522088, +28777, +458758, +163, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +163, +19, +1181114215, +1766617697, +7628903, +393222, +163, +20, +1416191847, +1399350117, +77, +458758, +163, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +163, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +163, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +163, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +163, +25, +1214668647, +1265789281, +12915, +393222, +163, +26, +1214668647, +1165125985, +12920, +589830, +163, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +165, +0, +262149, +186, +1400399220, +77, +262149, +196, +1953523044, +104, +262149, +202, +1769173093, +7237484, +393221, +206, +1953523044, +1919311720, +1701668705, +29806, +393221, +209, +1635020660, +1702322028, +1952999273, +0, +458757, +211, +1970236769, +1766618222, +1601464423, +1919508840, +0, +196613, +213, +30820, +196613, +224, +31076, +262149, +232, +1702521203, +0, +262149, +234, +1835493747, +97, +196613, +238, +7370853, +262149, +254, +1734960503, +29800, +327685, +265, +1953523044, +1213027176, +7498081, +393221, +268, +1919508808, +1684105299, +1632466799, +112, +393221, +272, +1634951015, +1768902765, +1816360046, +7368033, +393221, +290, +1953523044, +1836277608, +1852403536, +116, +327685, +308, +1953523044, +1634885480, +6645614, +327685, +313, +1181578606, +1919246953, +115, +458757, +352, +1970236769, +1766618222, +1601464423, +1852138355, +101, +393221, +358, +1785688688, +1282633552, +1952999273, +0, +262149, +375, +1400399220, +77, +262149, +385, +1953523044, +104, +262149, +391, +1769173093, +7237484, +393221, +394, +1953523044, +1919311720, +1701668705, +29806, +458757, +397, +1970236769, +1766618222, +1601464423, +1852138355, +101, +327685, +398, +1953523044, +1213027176, +7498081, +393221, +407, +1953523044, +1836277608, +1852403536, +116, +327685, +422, +1953523044, +1634885480, +6645614, +327685, +427, +1181578606, +1919246953, +115, +458757, +444, +1970236769, +1766618222, +1601464423, +1919508840, +0, +327685, +453, +1702060386, +1869377347, +114, +327685, +459, +1684955506, +1818326623, +25973, +196613, +460, +24907, +196613, +464, +25675, +196613, +467, +3240779, +196613, +470, +3242053, +196613, +473, +3306315, +196613, +477, +3307589, +327685, +481, +1751607660, +1936674932, +0, +327685, +485, +1734954102, +1766093928, +114, +262149, +490, +1702446454, +7498052, +262149, +498, +1735287156, +7630437, +262149, +501, +1416851299, +76, +262149, +505, +1416522099, +76, +262149, +511, +1717987684, +6648693, +262149, +513, +1752198241, +97, +262149, +521, +1416851299, +19538, +262149, +524, +1416522099, +19538, +262149, +526, +1416851299, +69, +262149, +530, +1416522099, +69, +327685, +536, +1416851299, +1918848082, +7630703, +327685, +548, +1416522099, +1918848082, +7630703, +393221, +554, +1667592307, +1918987381, +1869574751, +116, +327685, +563, +1416851299, +1952402514, +28777, +327685, +576, +1416522099, +1952402514, +28777, +393221, +582, +1667592307, +1918987381, +1885959263, +0, +262149, +591, +1819231094, +29295, +327685, +633, +1702060386, +1869377347, +114, +196613, +637, +25675, +262149, +640, +1819231094, +29295, +196613, +653, +7763305, +393221, +655, +1180658791, +1130848626, +1685221231, +0, +393221, +659, +1953720652, +1801680194, +1699247205, +25697, +524293, +662, +1349674320, +1818589289, +1802398028, +1766614117, +1699247219, +25697, +327685, +674, +1718968939, +2053731167, +101, +393221, +688, +1734439494, +1953391981, +1835363397, +7630437, +327686, +688, +0, +1953523044, +104, +524294, +688, +1, +1735287124, +1098149477, +1866687598, +1634887030, +25959, +262149, +692, +1718968939, +0, +458757, +694, +1349674320, +1818589289, +1953720652, +1801680194, +29797, +327686, +694, +0, +1953523044, +104, +524294, +694, +1, +1735287124, +1098149477, +1866687598, +1634887030, +25959, +327686, +694, +2, +1954047342, +0, +458757, +696, +1349674320, +1818589289, +1802398028, +1766614117, +29811, +327686, +696, +0, +1280069712, +0, +196613, +698, +0, +393221, +714, +1953720652, +1801680194, +1682535525, +0, +262149, +716, +1970496882, +29804, +262149, +718, +1718449518, +6775154, +327685, +728, +1601724781, +1953523044, +104, +262149, +729, +1601724781, +7890025, +196613, +730, +105, +196613, +739, +100, +196613, +766, +7368052, +262149, +778, +1970302324, +0, +196613, +790, +100, +262149, +794, +1348691054, +29551, +196613, +815, +7565136, +262149, +829, +1735287124, +7630437, +262149, +831, +1634886000, +109, +393221, +835, +1734439494, +1953391981, +1752198209, +97, +262149, +837, +1634886000, +109, +393221, +841, +1970236769, +1716483182, +1751607628, +116, +262149, +843, +1634886000, +109, +262149, +846, +1634886000, +109, +393221, +850, +1734439494, +1953391981, +1869377347, +114, +262149, +852, +1634886000, +109, +262149, +855, +1634886000, +109, +262149, +857, +1634886000, +109, +262149, +858, +1634886000, +109, +262149, +881, +1702258034, +6648690, +327685, +883, +1867740009, +1684370546, +0, +196613, +893, +105, +196613, +913, +7368052, +262149, +927, +1886221428, +0, +196613, +945, +105, +196613, +954, +100, +262149, +958, +1348691054, +29551, +196613, +977, +7565136, +262149, +991, +1735287124, +7630437, +262149, +993, +1634886000, +109, +393221, +997, +1734439494, +1953391981, +1752198209, +97, +262149, +999, +1634886000, +109, +393221, +1003, +1970236769, +1716483182, +1751607628, +116, +262149, +1004, +1634886000, +109, +262149, +1007, +1634886000, +109, +393221, +1011, +1734439494, +1953391981, +1869377347, +114, +262149, +1012, +1634886000, +109, +262149, +1015, +1634886000, +109, +262149, +1017, +1634886000, +109, +262149, +1018, +1634886000, +109, +262149, +1020, +1634886000, +109, +327685, +1045, +1734439494, +1869377347, +114, +262216, +163, +0, +5, +327752, +163, +0, +35, +0, +327752, +163, +0, +7, +16, +262216, +163, +1, +5, +327752, +163, +1, +35, +64, +327752, +163, +1, +7, +16, +262216, +163, +2, +5, +327752, +163, +2, +35, +128, +327752, +163, +2, +7, +16, +262216, +163, +3, +5, +327752, +163, +3, +35, +192, +327752, +163, +3, +7, +16, +327752, +163, +4, +35, +256, +327752, +163, +5, +35, +268, +327752, +163, +6, +35, +272, +327752, +163, +7, +35, +288, +327752, +163, +8, +35, +304, +327752, +163, +9, +35, +320, +327752, +163, +10, +35, +336, +327752, +163, +11, +35, +352, +327752, +163, +12, +35, +356, +327752, +163, +13, +35, +360, +327752, +163, +14, +35, +364, +327752, +163, +15, +35, +368, +327752, +163, +16, +35, +384, +327752, +163, +17, +35, +388, +327752, +163, +18, +35, +392, +327752, +163, +19, +35, +396, +327752, +163, +20, +35, +400, +327752, +163, +21, +35, +404, +327752, +163, +22, +35, +408, +327752, +163, +23, +35, +412, +327752, +163, +24, +35, +416, +327752, +163, +25, +35, +420, +327752, +163, +26, +35, +424, +262216, +163, +27, +5, +327752, +163, +27, +35, +432, +327752, +163, +27, +7, +16, +196679, +163, +2, +262215, +165, +34, +0, +262215, +165, +33, +16, +262215, +268, +34, +0, +262215, +268, +33, +3, +262215, +272, +34, +0, +262215, +272, +33, +19, +262215, +655, +11, +15, +262215, +662, +34, +0, +262215, +662, +33, +1, +196679, +662, +19, +327752, +694, +0, +35, +0, +327752, +694, +1, +35, +4, +327752, +694, +2, +35, +8, +262215, +695, +6, +12, +327752, +696, +0, +35, +0, +196679, +696, +3, +262215, +698, +34, +0, +262215, +698, +33, +0, +262215, +1045, +30, +0, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +262165, +9, +32, +0, +262177, +10, +9, +8, +262176, +14, +7, +9, +262177, +15, +7, +14, +262167, +19, +6, +3, +262176, +20, +7, +19, +262176, +21, +7, +6, +327713, +22, +9, +20, +21, +262177, +27, +19, +14, +262177, +31, +6, +14, +327713, +35, +6, +20, +21, +524321, +44, +19, +20, +20, +8, +21, +20, +458785, +52, +19, +20, +20, +8, +21, +262187, +9, +60, +0, +262187, +6, +63, +1132396544, +262187, +9, +66, +255, +262187, +9, +69, +1, +262187, +9, +76, +2, +262187, +9, +83, +3, +262165, +90, +32, +1, +262187, +90, +91, +24, +262187, +90, +94, +16, +262187, +90, +98, +8, +262187, +9, +106, +4278190080, +262187, +9, +112, +16711680, +262187, +9, +118, +65280, +262187, +6, +131, +1056964608, +262187, +6, +144, +1073741824, +262187, +6, +150, +1065353216, +262168, +162, +7, +4, +1966110, +163, +162, +162, +162, +162, +19, +6, +7, +7, +7, +7, +7, +6, +6, +6, +6, +7, +6, +6, +6, +6, +90, +90, +90, +90, +6, +6, +6, +162, +262176, +164, +2, +163, +262203, +164, +165, +2, +262187, +90, +166, +3, +262176, +167, +2, +162, +262167, +178, +6, +2, +262176, +185, +7, +178, +262187, +6, +204, +1008981770, +262187, +6, +210, +0, +262176, +212, +7, +90, +262187, +90, +214, +4294967294, +262187, +90, +221, +2, +131092, +222, +262187, +6, +233, +1075419546, +262187, +6, +235, +1075838976, +262187, +90, +239, +4294967295, +262187, +6, +255, +1086911939, +262187, +6, +261, +1076677837, +589849, +266, +6, +1, +0, +0, +0, +1, +0, +262176, +267, +0, +266, +262203, +267, +268, +0, +131098, +270, +262176, +271, +0, +270, +262203, +271, +272, +0, +196635, +274, +266, +262187, +6, +282, +1142947840, +262187, +90, +291, +18, +262176, +292, +2, +6, +262187, +90, +296, +19, +262187, +90, +317, +14, +262187, +6, +324, +925353388, +262187, +90, +345, +1, +262187, +90, +454, +9, +262176, +455, +2, +7, +262187, +90, +461, +10, +262187, +90, +474, +25, +262187, +90, +478, +26, +262187, +90, +491, +4, +262176, +492, +2, +19, +262187, +6, +515, +1092616192, +262187, +6, +517, +1078523331, +262187, +6, +519, +1127481344, +262187, +6, +565, +3225419776, +262187, +90, +593, +6, +262187, +90, +601, +7, +262167, +651, +90, +2, +262176, +652, +7, +651, +262176, +654, +1, +7, +262203, +654, +655, +1, +589849, +660, +9, +1, +0, +0, +0, +2, +33, +262176, +661, +0, +660, +262203, +661, +662, +0, +262167, +665, +9, +4, +262187, +9, +669, +4294967295, +262187, +90, +675, +0, +262174, +688, +6, +9, +262187, +9, +689, +8, +262172, +690, +688, +689, +262176, +691, +7, +690, +327710, +694, +6, +9, +9, +196637, +695, +694, +196638, +696, +695, +262176, +697, +2, +696, +262203, +697, +698, +2, +262176, +705, +2, +9, +458796, +7, +717, +210, +210, +210, +150, +262176, +795, +1, +6, +262187, +90, +798, +15, +262187, +90, +842, +12, +458796, +7, +851, +210, +210, +210, +210, +262176, +882, +7, +222, +196650, +222, +884, +196649, +222, +892, +262176, +1044, +3, +7, +262203, +1044, +1045, +3, +327734, +2, +4, +0, +3, +131320, +5, +262203, +652, +653, +7, +262203, +14, +659, +7, +262203, +212, +674, +7, +262203, +691, +692, +7, +262203, +14, +714, +7, +262203, +8, +716, +7, +262203, +14, +718, +7, +262203, +21, +728, +7, +262203, +14, +729, +7, +262203, +212, +730, +7, +262203, +21, +739, +7, +262203, +14, +746, +7, +262203, +21, +766, +7, +262203, +14, +778, +7, +262203, +21, +790, +7, +262203, +20, +794, +7, +262203, +8, +815, +7, +262203, +20, +829, +7, +262203, +14, +831, +7, +262203, +21, +835, +7, +262203, +14, +837, +7, +262203, +21, +841, +7, +262203, +20, +843, +7, +262203, +21, +846, +7, +262203, +20, +850, +7, +262203, +20, +852, +7, +262203, +20, +855, +7, +262203, +8, +857, +7, +262203, +21, +858, +7, +262203, +14, +881, +7, +262203, +882, +883, +7, +262203, +212, +893, +7, +262203, +21, +913, +7, +262203, +14, +927, +7, +262203, +212, +945, +7, +262203, +21, +954, +7, +262203, +20, +958, +7, +262203, +8, +977, +7, +262203, +20, +991, +7, +262203, +14, +993, +7, +262203, +21, +997, +7, +262203, +14, +999, +7, +262203, +21, +1003, +7, +262203, +20, +1004, +7, +262203, +21, +1007, +7, +262203, +20, +1011, +7, +262203, +20, +1012, +7, +262203, +20, +1015, +7, +262203, +8, +1017, +7, +262203, +21, +1018, +7, +262203, +20, +1020, +7, +262205, +7, +656, +655, +458831, +178, +657, +656, +656, +0, +1, +262254, +651, +658, +657, +196670, +653, +658, +262205, +660, +663, +662, +262205, +651, +664, +653, +327778, +665, +666, +663, +664, +327761, +9, +667, +666, +0, +196670, +659, +667, +262205, +9, +668, +659, +327850, +222, +670, +668, +669, +196855, +672, +0, +262394, +670, +671, +672, +131320, +671, +65788, +131320, +672, +196670, +674, +675, +131321, +676, +131320, +676, +262390, +678, +679, +0, +131321, +680, +131320, +680, +262205, +90, +681, +674, +327857, +222, +682, +681, +98, +262394, +682, +677, +678, +131320, +677, +262205, +9, +683, +659, +327850, +222, +684, +683, +669, +196855, +686, +0, +262394, +684, +685, +686, +131320, +685, +131321, +678, +131320, +686, +262205, +90, +693, +674, +262205, +9, +699, +659, +458817, +292, +700, +698, +675, +699, +675, +262205, +6, +701, +700, +393281, +21, +702, +692, +693, +675, +196670, +702, +701, +262205, +90, +703, +674, +262205, +9, +704, +659, +458817, +705, +706, +698, +675, +704, +345, +262205, +9, +707, +706, +393281, +14, +708, +692, +703, +345, +196670, +708, +707, +262205, +9, +709, +659, +458817, +705, +710, +698, +675, +709, +221, +262205, +9, +711, +710, +196670, +659, +711, +131321, +679, +131320, +679, +262205, +90, +712, +674, +327808, +90, +713, +712, +345, +196670, +674, +713, +131321, +676, +131320, +678, +262205, +9, +715, +659, +196670, +714, +715, +196670, +716, +717, +196670, +718, +60, +131321, +719, +131320, +719, +262390, +721, +722, +0, +131321, +723, +131320, +723, +262205, +9, +724, +714, +327851, +222, +725, +724, +669, +262394, +725, +720, +721, +131320, +720, +262205, +9, +726, +718, +327808, +9, +727, +726, +345, +196670, +718, +727, +196670, +728, +210, +196670, +729, +60, +196670, +730, +675, +131321, +731, +131320, +731, +262390, +733, +734, +0, +131321, +735, +131320, +735, +262205, +90, +736, +730, +262205, +90, +737, +674, +327857, +222, +738, +736, +737, +262394, +738, +732, +733, +131320, +732, +262205, +90, +740, +730, +393281, +21, +741, +692, +740, +675, +262205, +6, +742, +741, +196670, +739, +742, +262205, +6, +743, +728, +262205, +6, +744, +739, +458764, +6, +745, +1, +40, +743, +744, +196670, +728, +745, +262205, +6, +747, +728, +262205, +6, +748, +739, +327860, +222, +749, +747, +748, +196855, +751, +0, +262394, +749, +750, +754, +131320, +750, +262205, +90, +752, +730, +262268, +9, +753, +752, +196670, +746, +753, +131321, +751, +131320, +754, +262205, +9, +755, +729, +196670, +746, +755, +131321, +751, +131320, +751, +262205, +9, +756, +746, +196670, +729, +756, +131321, +734, +131320, +734, +262205, +90, +757, +730, +327808, +90, +758, +757, +345, +196670, +730, +758, +131321, +731, +131320, +733, +262205, +9, +759, +714, +458817, +292, +760, +698, +675, +759, +675, +262205, +6, +761, +760, +262205, +6, +762, +728, +327864, +222, +763, +761, +762, +196855, +765, +0, +262394, +763, +764, +765, +131320, +764, +262205, +9, +767, +714, +458817, +292, +768, +698, +675, +767, +675, +262205, +6, +769, +768, +196670, +766, +769, +262205, +9, +770, +714, +262205, +9, +771, +729, +393281, +21, +772, +692, +771, +675, +262205, +6, +773, +772, +458817, +292, +774, +698, +675, +770, +675, +196670, +774, +773, +262205, +9, +775, +729, +262205, +6, +776, +766, +393281, +21, +777, +692, +775, +675, +196670, +777, +776, +262205, +9, +779, +714, +458817, +705, +780, +698, +675, +779, +345, +262205, +9, +781, +780, +196670, +778, +781, +262205, +9, +782, +714, +262205, +9, +783, +729, +393281, +14, +784, +692, +783, +345, +262205, +9, +785, +784, +458817, +705, +786, +698, +675, +782, +345, +196670, +786, +785, +262205, +9, +787, +729, +262205, +9, +788, +778, +393281, +14, +789, +692, +787, +345, +196670, +789, +788, +131321, +765, +131320, +765, +262205, +9, +791, +714, +458817, +292, +792, +698, +675, +791, +675, +262205, +6, +793, +792, +196670, +790, +793, +327745, +795, +796, +655, +60, +262205, +6, +797, +796, +393281, +292, +799, +165, +798, +76, +262205, +6, +800, +799, +327813, +6, +801, +797, +800, +327745, +795, +802, +655, +69, +262205, +6, +803, +802, +393281, +292, +804, +165, +798, +83, +262205, +6, +805, +804, +327813, +6, +806, +803, +805, +327811, +6, +807, +150, +806, +262205, +6, +808, +790, +393296, +19, +809, +801, +807, +808, +327822, +19, +810, +809, +144, +393296, +19, +811, +150, +150, +150, +327811, +19, +812, +810, +811, +196670, +794, +812, +262205, +6, +813, +790, +327745, +21, +814, +794, +76, +196670, +814, +813, +327745, +167, +816, +165, +221, +262205, +162, +817, +816, +262205, +19, +818, +794, +327761, +6, +819, +818, +0, +327761, +6, +820, +818, +1, +327761, +6, +821, +818, +2, +458832, +7, +822, +819, +820, +821, +150, +327825, +7, +823, +817, +822, +196670, +815, +823, +327745, +21, +824, +815, +83, +262205, +6, +825, +824, +262205, +7, +826, +815, +458832, +7, +827, +825, +825, +825, +825, +327816, +7, +828, +826, +827, +196670, +815, +828, +262205, +9, +830, +714, +458817, +705, +832, +698, +675, +830, +345, +262205, +9, +833, +832, +196670, +831, +833, +327737, +19, +834, +29, +831, +196670, +829, +834, +262205, +9, +836, +714, +458817, +705, +838, +698, +675, +836, +345, +262205, +9, +839, +838, +196670, +837, +839, +327737, +6, +840, +33, +837, +196670, +835, +840, +262205, +7, +844, +815, +524367, +19, +845, +844, +844, +0, +1, +2, +196670, +843, +845, +327745, +292, +847, +165, +842, +262205, +6, +848, +847, +196670, +846, +848, +393273, +6, +849, +42, +843, +846, +196670, +841, +849, +262205, +7, +853, +815, +524367, +19, +854, +853, +853, +0, +1, +2, +196670, +852, +854, +262205, +19, +856, +829, +196670, +855, +856, +196670, +857, +851, +262205, +6, +859, +841, +196670, +858, +859, +524345, +19, +860, +57, +852, +855, +857, +858, +196670, +850, +860, +262205, +7, +861, +716, +524367, +19, +862, +861, +861, +0, +1, +2, +262205, +6, +863, +835, +327811, +6, +864, +150, +863, +327822, +19, +865, +862, +864, +262205, +6, +866, +835, +262205, +19, +867, +850, +327822, +19, +868, +867, +866, +327809, +19, +869, +865, +868, +262205, +7, +870, +716, +589903, +7, +871, +870, +869, +4, +5, +6, +3, +196670, +716, +871, +262205, +6, +872, +835, +327811, +6, +873, +150, +872, +327745, +21, +874, +716, +83, +262205, +6, +875, +874, +327813, +6, +876, +875, +873, +327745, +21, +877, +716, +83, +196670, +877, +876, +262205, +9, +878, +714, +458817, +705, +879, +698, +675, +878, +221, +262205, +9, +880, +879, +196670, +714, +880, +131321, +722, +131320, +722, +131321, +719, +131320, +721, +196670, +881, +60, +196670, +883, +884, +131321, +885, +131320, +885, +262390, +887, +888, +0, +131321, +889, +131320, +889, +262205, +222, +890, +883, +262312, +222, +891, +890, +262394, +891, +886, +887, +131320, +886, +196670, +883, +892, +196670, +893, +675, +131321, +894, +131320, +894, +262390, +896, +897, +0, +131321, +898, +131320, +898, +262205, +90, +899, +893, +262205, +90, +900, +674, +327810, +90, +901, +900, +345, +327857, +222, +902, +899, +901, +262394, +902, +895, +896, +131320, +895, +262205, +90, +903, +893, +393281, +21, +904, +692, +903, +675, +262205, +6, +905, +904, +262205, +90, +906, +893, +327808, +90, +907, +906, +345, +393281, +21, +908, +692, +907, +675, +262205, +6, +909, +908, +327864, +222, +910, +905, +909, +196855, +912, +0, +262394, +910, +911, +912, +131320, +911, +196670, +883, +884, +262205, +90, +914, +893, +393281, +21, +915, +692, +914, +675, +262205, +6, +916, +915, +196670, +913, +916, +262205, +90, +917, +893, +262205, +90, +918, +893, +327808, +90, +919, +918, +345, +393281, +21, +920, +692, +919, +675, +262205, +6, +921, +920, +393281, +21, +922, +692, +917, +675, +196670, +922, +921, +262205, +90, +923, +893, +327808, +90, +924, +923, +345, +262205, +6, +925, +913, +393281, +21, +926, +692, +924, +675, +196670, +926, +925, +262205, +90, +928, +893, +393281, +14, +929, +692, +928, +345, +262205, +9, +930, +929, +196670, +927, +930, +262205, +90, +931, +893, +262205, +90, +932, +893, +327808, +90, +933, +932, +345, +393281, +14, +934, +692, +933, +345, +262205, +9, +935, +934, +393281, +14, +936, +692, +931, +345, +196670, +936, +935, +262205, +90, +937, +893, +327808, +90, +938, +937, +345, +262205, +9, +939, +927, +393281, +14, +940, +692, +938, +345, +196670, +940, +939, +262205, +9, +941, +881, +327808, +9, +942, +941, +345, +196670, +881, +942, +131321, +912, +131320, +912, +131321, +897, +131320, +897, +262205, +90, +943, +893, +327808, +90, +944, +943, +345, +196670, +893, +944, +131321, +894, +131320, +896, +131321, +888, +131320, +888, +131321, +885, +131320, +887, +196670, +945, +675, +131321, +946, +131320, +946, +262390, +948, +949, +0, +131321, +950, +131320, +950, +262205, +90, +951, +945, +262205, +90, +952, +674, +327857, +222, +953, +951, +952, +262394, +953, +947, +948, +131320, +947, +262205, +90, +955, +945, +393281, +21, +956, +692, +955, +675, +262205, +6, +957, +956, +196670, +954, +957, +327745, +795, +959, +655, +60, +262205, +6, +960, +959, +393281, +292, +961, +165, +798, +76, +262205, +6, +962, +961, +327813, +6, +963, +960, +962, +327745, +795, +964, +655, +69, +262205, +6, +965, +964, +393281, +292, +966, +165, +798, +83, +262205, +6, +967, +966, +327813, +6, +968, +965, +967, +327811, +6, +969, +150, +968, +262205, +6, +970, +954, +393296, +19, +971, +963, +969, +970, +327822, +19, +972, +971, +144, +393296, +19, +973, +150, +150, +150, +327811, +19, +974, +972, +973, +196670, +958, +974, +262205, +6, +975, +954, +327745, +21, +976, +958, +76, +196670, +976, +975, +327745, +167, +978, +165, +221, +262205, +162, +979, +978, +262205, +19, +980, +958, +327761, +6, +981, +980, +0, +327761, +6, +982, +980, +1, +327761, +6, +983, +980, +2, +458832, +7, +984, +981, +982, +983, +150, +327825, +7, +985, +979, +984, +196670, +977, +985, +327745, +21, +986, +977, +83, +262205, +6, +987, +986, +262205, +7, +988, +977, +458832, +7, +989, +987, +987, +987, +987, +327816, +7, +990, +988, +989, +196670, +977, +990, +262205, +90, +992, +945, +393281, +14, +994, +692, +992, +345, +262205, +9, +995, +994, +196670, +993, +995, +327737, +19, +996, +29, +993, +196670, +991, +996, +262205, +90, +998, +945, +393281, +14, +1000, +692, +998, +345, +262205, +9, +1001, +1000, +196670, +999, +1001, +327737, +6, +1002, +33, +999, +196670, +997, +1002, +262205, +7, +1005, +977, +524367, +19, +1006, +1005, +1005, +0, +1, +2, +196670, +1004, +1006, +327745, +292, +1008, +165, +842, +262205, +6, +1009, +1008, +196670, +1007, +1009, +393273, +6, +1010, +38, +1004, +1007, +196670, +1003, +1010, +262205, +7, +1013, +977, +524367, +19, +1014, +1013, +1013, +0, +1, +2, +196670, +1012, +1014, +262205, +19, +1016, +991, +196670, +1015, +1016, +196670, +1017, +851, +262205, +6, +1019, +1003, +196670, +1018, +1019, +327745, +455, +1021, +165, +454, +262205, +7, +1022, +1021, +524367, +19, +1023, +1022, +1022, +0, +1, +2, +196670, +1020, +1023, +589881, +19, +1024, +50, +1012, +1015, +1017, +1018, +1020, +196670, +1011, +1024, +262205, +7, +1025, +716, +524367, +19, +1026, +1025, +1025, +0, +1, +2, +262205, +6, +1027, +997, +327811, +6, +1028, +150, +1027, +327822, +19, +1029, +1026, +1028, +262205, +6, +1030, +997, +262205, +19, +1031, +1011, +327822, +19, +1032, +1031, +1030, +327809, +19, +1033, +1029, +1032, +262205, +7, +1034, +716, +589903, +7, +1035, +1034, +1033, +4, +5, +6, +3, +196670, +716, +1035, +262205, +6, +1036, +997, +327811, +6, +1037, +150, +1036, +327745, +21, +1038, +716, +83, +262205, +6, +1039, +1038, +327813, +6, +1040, +1039, +1037, +327745, +21, +1041, +716, +83, +196670, +1041, +1040, +131321, +949, +131320, +949, +262205, +90, +1042, +945, +327808, +90, +1043, +1042, +345, +196670, +945, +1043, +131321, +946, +131320, +948, +262205, +7, +1046, +716, +196670, +1045, +1046, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +262203, +14, +59, +7, +262203, +14, +68, +7, +262203, +14, +75, +7, +262203, +14, +82, +7, +327745, +21, +61, +11, +60, +262205, +6, +62, +61, +327813, +6, +64, +62, +63, +262253, +9, +65, +64, +327879, +9, +67, +65, +66, +196670, +59, +67, +327745, +21, +70, +11, +69, +262205, +6, +71, +70, +327813, +6, +72, +71, +63, +262253, +9, +73, +72, +327879, +9, +74, +73, +66, +196670, +68, +74, +327745, +21, +77, +11, +76, +262205, +6, +78, +77, +327813, +6, +79, +78, +63, +262253, +9, +80, +79, +327879, +9, +81, +80, +66, +196670, +75, +81, +327745, +21, +84, +11, +83, +262205, +6, +85, +84, +327813, +6, +86, +85, +63, +262253, +9, +87, +86, +327879, +9, +88, +87, +66, +196670, +82, +88, +262205, +9, +89, +59, +327876, +9, +92, +89, +91, +262205, +9, +93, +68, +327876, +9, +95, +93, +94, +327877, +9, +96, +92, +95, +262205, +9, +97, +75, +327876, +9, +99, +97, +98, +327877, +9, +100, +96, +99, +262205, +9, +101, +82, +327877, +9, +102, +100, +101, +131326, +102, +65592, +327734, +7, +17, +0, +15, +196663, +14, +16, +131320, +18, +262205, +9, +105, +16, +327879, +9, +107, +105, +106, +327874, +9, +108, +107, +91, +262256, +6, +109, +108, +327816, +6, +110, +109, +63, +262205, +9, +111, +16, +327879, +9, +113, +111, +112, +327874, +9, +114, +113, +94, +262256, +6, +115, +114, +327816, +6, +116, +115, +63, +262205, +9, +117, +16, +327879, +9, +119, +117, +118, +327874, +9, +120, +119, +98, +262256, +6, +121, +120, +327816, +6, +122, +121, +63, +262205, +9, +123, +16, +327879, +9, +124, +123, +66, +262256, +6, +125, +124, +327816, +6, +126, +125, +63, +458832, +7, +127, +110, +116, +122, +126, +131326, +127, +65592, +327734, +9, +25, +0, +22, +196663, +20, +23, +196663, +21, +24, +131320, +26, +262203, +8, +140, +7, +262205, +19, +130, +23, +327822, +19, +132, +130, +131, +393296, +19, +133, +131, +131, +131, +327809, +19, +134, +132, +133, +262205, +6, +135, +24, +327761, +6, +136, +134, +0, +327761, +6, +137, +134, +1, +327761, +6, +138, +134, +2, +458832, +7, +139, +136, +137, +138, +135, +196670, +140, +139, +327737, +9, +141, +12, +140, +131326, +141, +65592, +327734, +19, +29, +0, +27, +196663, +14, +28, +131320, +30, +262203, +14, +145, +7, +262205, +9, +146, +28, +196670, +145, +146, +327737, +7, +147, +17, +145, +524367, +19, +148, +147, +147, +0, +1, +2, +327822, +19, +149, +148, +144, +393296, +19, +151, +150, +150, +150, +327811, +19, +152, +149, +151, +131326, +152, +65592, +327734, +6, +33, +0, +31, +196663, +14, +32, +131320, +34, +262203, +14, +155, +7, +262205, +9, +156, +32, +196670, +155, +156, +327737, +7, +157, +17, +155, +327761, +6, +158, +157, +3, +131326, +158, +65592, +327734, +6, +38, +0, +35, +196663, +20, +36, +196663, +21, +37, +131320, +39, +262203, +8, +161, +7, +262203, +185, +186, +7, +262203, +21, +196, +7, +262203, +21, +202, +7, +262203, +21, +206, +7, +262203, +21, +209, +7, +262203, +21, +211, +7, +262203, +212, +213, +7, +262203, +212, +224, +7, +262203, +21, +232, +7, +262203, +21, +234, +7, +262203, +21, +238, +7, +262203, +21, +254, +7, +262203, +21, +265, +7, +262203, +21, +290, +7, +262203, +21, +308, +7, +262203, +21, +313, +7, +262203, +21, +322, +7, +262203, +21, +352, +7, +327745, +167, +168, +165, +166, +262205, +162, +169, +168, +262205, +19, +170, +36, +327761, +6, +171, +170, +0, +327761, +6, +172, +170, +1, +327761, +6, +173, +170, +2, +458832, +7, +174, +171, +172, +173, +150, +327825, +7, +175, +169, +174, +196670, +161, +175, +327745, +21, +176, +161, +83, +262205, +6, +177, +176, +262205, +7, +179, +161, +458831, +178, +180, +179, +179, +0, +1, +327760, +178, +181, +177, +177, +327816, +178, +182, +180, +181, +262205, +7, +183, +161, +589903, +7, +184, +183, +182, +4, +5, +2, +3, +196670, +161, +184, +262205, +7, +187, +161, +458831, +178, +188, +187, +187, +0, +1, +327822, +178, +189, +188, +131, +327760, +178, +190, +131, +131, +327809, +178, +191, +189, +190, +196670, +186, +191, +327745, +21, +192, +186, +69, +262205, +6, +193, +192, +327811, +6, +194, +150, +193, +327745, +21, +195, +186, +69, +196670, +195, +194, +327745, +21, +197, +161, +76, +262205, +6, +198, +197, +327745, +21, +199, +161, +83, +262205, +6, +200, +199, +327816, +6, +201, +198, +200, +196670, +196, +201, +262205, +6, +203, +196, +327813, +6, +205, +203, +204, +196670, +202, +205, +327745, +21, +207, +161, +83, +262205, +6, +208, +207, +196670, +206, +208, +196670, +209, +210, +196670, +211, +210, +196670, +209, +210, +196670, +213, +214, +131321, +215, +131320, +215, +262390, +217, +218, +0, +131321, +219, +131320, +219, +262205, +90, +220, +213, +327859, +222, +223, +220, +221, +262394, +223, +216, +217, +131320, +216, +196670, +224, +214, +131321, +225, +131320, +225, +262390, +227, +228, +0, +131321, +229, +131320, +229, +262205, +90, +230, +224, +327859, +222, +231, +230, +221, +262394, +231, +226, +227, +131320, +226, +196670, +232, +233, +262205, +6, +236, +232, +327816, +6, +237, +235, +236, +196670, +234, +237, +262205, +90, +240, +213, +262205, +90, +241, +213, +327812, +90, +242, +240, +241, +262205, +90, +243, +224, +262205, +90, +244, +224, +327812, +90, +245, +243, +244, +327808, +90, +246, +242, +245, +327812, +90, +247, +239, +246, +262255, +6, +248, +247, +262205, +6, +249, +234, +327813, +6, +250, +144, +249, +262205, +6, +251, +234, +327813, +6, +252, +250, +251, +327816, +6, +253, +248, +252, +196670, +238, +253, +262205, +6, +256, +234, +327813, +6, +257, +255, +256, +262205, +6, +258, +234, +327813, +6, +259, +257, +258, +327816, +6, +260, +150, +259, +262205, +6, +262, +238, +458764, +6, +263, +1, +26, +261, +262, +327813, +6, +264, +260, +263, +196670, +254, +264, +262205, +266, +269, +268, +262205, +270, +273, +272, +327766, +274, +275, +269, +273, +262205, +178, +276, +186, +262205, +90, +277, +213, +262255, +6, +278, +277, +262205, +90, +279, +224, +262255, +6, +280, +279, +327760, +178, +281, +278, +280, +327760, +178, +283, +282, +282, +327816, +178, +284, +281, +283, +327809, +178, +285, +276, +284, +327767, +7, +286, +275, +285, +327761, +6, +287, +286, +0, +327813, +6, +288, +144, +287, +327811, +6, +289, +288, +150, +196670, +265, +289, +327745, +292, +293, +165, +291, +262205, +6, +294, +293, +262205, +6, +295, +265, +327745, +292, +297, +165, +296, +262205, +6, +298, +297, +327745, +292, +299, +165, +291, +262205, +6, +300, +299, +327811, +6, +301, +298, +300, +327813, +6, +302, +295, +301, +327745, +292, +303, +165, +296, +262205, +6, +304, +303, +327816, +6, +305, +302, +304, +327811, +6, +306, +150, +305, +327816, +6, +307, +294, +306, +196670, +290, +307, +262205, +6, +309, +206, +262205, +6, +310, +290, +327811, +6, +311, +309, +310, +458764, +6, +312, +1, +40, +210, +311, +196670, +308, +312, +262205, +6, +314, +308, +327745, +292, +315, +165, +94, +262205, +6, +316, +315, +327745, +292, +318, +165, +317, +262205, +6, +319, +318, +327813, +6, +320, +316, +319, +327816, +6, +321, +314, +320, +196670, +313, +321, +262205, +6, +323, +308, +327866, +222, +325, +323, +324, +196855, +327, +0, +262394, +325, +326, +328, +131320, +326, +196670, +322, +150, +131321, +327, +131320, +328, +196670, +322, +210, +131321, +327, +131320, +327, +262205, +6, +329, +322, +262205, +6, +330, +313, +327809, +6, +331, +330, +329, +196670, +313, +331, +262205, +6, +332, +37, +327811, +6, +333, +150, +332, +393228, +6, +334, +1, +4, +333, +262205, +6, +335, +313, +458764, +6, +336, +1, +26, +334, +335, +262205, +6, +337, +254, +327813, +6, +338, +336, +337, +262205, +6, +339, +211, +327809, +6, +340, +339, +338, +196670, +211, +340, +262205, +6, +341, +254, +262205, +6, +342, +209, +327809, +6, +343, +342, +341, +196670, +209, +343, +131321, +228, +131320, +228, +262205, +90, +344, +224, +327808, +90, +346, +344, +345, +196670, +224, +346, +131321, +225, +131320, +227, +131321, +218, +131320, +218, +262205, +90, +347, +213, +327808, +90, +348, +347, +345, +196670, +213, +348, +131321, +215, +131320, +217, +262205, +6, +349, +209, +262205, +6, +350, +211, +327816, +6, +351, +350, +349, +196670, +211, +351, +196670, +352, +150, +262205, +6, +353, +211, +262205, +6, +354, +352, +327813, +6, +355, +353, +354, +131326, +355, +65592, +327734, +6, +42, +0, +35, +196663, +20, +40, +196663, +21, +41, +131320, +43, +262203, +8, +358, +7, +262203, +185, +375, +7, +262203, +21, +385, +7, +262203, +21, +391, +7, +262203, +21, +394, +7, +262203, +21, +397, +7, +262203, +21, +398, +7, +262203, +21, +407, +7, +262203, +21, +422, +7, +262203, +21, +427, +7, +262203, +21, +435, +7, +262203, +21, +444, +7, +327745, +167, +359, +165, +166, +262205, +162, +360, +359, +262205, +19, +361, +40, +327761, +6, +362, +361, +0, +327761, +6, +363, +361, +1, +327761, +6, +364, +361, +2, +458832, +7, +365, +362, +363, +364, +150, +327825, +7, +366, +360, +365, +196670, +358, +366, +327745, +21, +367, +358, +83, +262205, +6, +368, +367, +262205, +7, +369, +358, +458831, +178, +370, +369, +369, +0, +1, +327760, +178, +371, +368, +368, +327816, +178, +372, +370, +371, +262205, +7, +373, +358, +589903, +7, +374, +373, +372, +4, +5, +2, +3, +196670, +358, +374, +262205, +7, +376, +358, +458831, +178, +377, +376, +376, +0, +1, +327822, +178, +378, +377, +131, +327760, +178, +379, +131, +131, +327809, +178, +380, +378, +379, +196670, +375, +380, +327745, +21, +381, +375, +69, +262205, +6, +382, +381, +327811, +6, +383, +150, +382, +327745, +21, +384, +375, +69, +196670, +384, +383, +327745, +21, +386, +358, +76, +262205, +6, +387, +386, +327745, +21, +388, +358, +83, +262205, +6, +389, +388, +327816, +6, +390, +387, +389, +196670, +385, +390, +262205, +6, +392, +385, +327813, +6, +393, +392, +204, +196670, +391, +393, +327745, +21, +395, +358, +83, +262205, +6, +396, +395, +196670, +394, +396, +196670, +397, +150, +262205, +266, +399, +268, +262205, +270, +400, +272, +327766, +274, +401, +399, +400, +262205, +178, +402, +375, +327767, +7, +403, +401, +402, +327761, +6, +404, +403, +0, +327813, +6, +405, +144, +404, +327811, +6, +406, +405, +150, +196670, +398, +406, +327745, +292, +408, +165, +291, +262205, +6, +409, +408, +262205, +6, +410, +398, +327745, +292, +411, +165, +296, +262205, +6, +412, +411, +327745, +292, +413, +165, +291, +262205, +6, +414, +413, +327811, +6, +415, +412, +414, +327813, +6, +416, +410, +415, +327745, +292, +417, +165, +296, +262205, +6, +418, +417, +327816, +6, +419, +416, +418, +327811, +6, +420, +150, +419, +327816, +6, +421, +409, +420, +196670, +407, +421, +262205, +6, +423, +394, +262205, +6, +424, +407, +327811, +6, +425, +423, +424, +458764, +6, +426, +1, +40, +210, +425, +196670, +422, +426, +262205, +6, +428, +422, +327745, +292, +429, +165, +94, +262205, +6, +430, +429, +327745, +292, +431, +165, +317, +262205, +6, +432, +431, +327813, +6, +433, +430, +432, +327816, +6, +434, +428, +433, +196670, +427, +434, +262205, +6, +436, +422, +327866, +222, +437, +436, +324, +196855, +439, +0, +262394, +437, +438, +440, +131320, +438, +196670, +435, +150, +131321, +439, +131320, +440, +196670, +435, +210, +131321, +439, +131320, +439, +262205, +6, +441, +435, +262205, +6, +442, +427, +327809, +6, +443, +442, +441, +196670, +427, +443, +262205, +6, +445, +41, +327811, +6, +446, +150, +445, +393228, +6, +447, +1, +4, +446, +262205, +6, +448, +427, +458764, +6, +449, +1, +26, +447, +448, +196670, +444, +449, +262205, +6, +450, +444, +131326, +450, +65592, +327734, +19, +50, +0, +44, +196663, +20, +45, +196663, +20, +46, +196663, +8, +47, +196663, +21, +48, +196663, +20, +49, +131320, +51, +262203, +20, +453, +7, +262203, +21, +459, +7, +262203, +21, +460, +7, +262203, +21, +464, +7, +262203, +21, +467, +7, +262203, +21, +470, +7, +262203, +21, +473, +7, +262203, +21, +477, +7, +262203, +20, +481, +7, +262203, +20, +485, +7, +262203, +20, +490, +7, +262203, +20, +498, +7, +262203, +21, +501, +7, +262203, +21, +505, +7, +262203, +21, +511, +7, +262203, +21, +513, +7, +262203, +21, +521, +7, +262203, +21, +524, +7, +262203, +21, +526, +7, +262203, +21, +530, +7, +262203, +21, +536, +7, +262203, +21, +548, +7, +262203, +21, +554, +7, +262203, +21, +563, +7, +262203, +21, +576, +7, +262203, +21, +582, +7, +262203, +20, +591, +7, +327745, +455, +456, +165, +454, +262205, +7, +457, +456, +524367, +19, +458, +457, +457, +0, +1, +2, +196670, +453, +458, +196670, +459, +150, +393281, +292, +462, +165, +461, +60, +262205, +6, +463, +462, +196670, +460, +463, +393281, +292, +465, +165, +461, +69, +262205, +6, +466, +465, +196670, +464, +466, +393281, +292, +468, +165, +461, +76, +262205, +6, +469, +468, +196670, +467, +469, +393281, +292, +471, +165, +461, +83, +262205, +6, +472, +471, +196670, +470, +472, +327745, +292, +475, +165, +474, +262205, +6, +476, +475, +196670, +473, +476, +327745, +292, +479, +165, +478, +262205, +6, +480, +479, +196670, +477, +480, +327745, +455, +482, +165, +98, +262205, +7, +483, +482, +524367, +19, +484, +483, +483, +0, +1, +2, +196670, +481, +484, +262205, +19, +486, +481, +262205, +19, +487, +45, +327811, +19, +488, +486, +487, +393228, +19, +489, +1, +69, +488, +196670, +485, +489, +327745, +492, +493, +165, +491, +262205, +19, +494, +493, +262205, +19, +495, +45, +327811, +19, +496, +494, +495, +393228, +19, +497, +1, +69, +496, +196670, +490, +497, +262205, +19, +499, +46, +393228, +19, +500, +1, +69, +499, +196670, +498, +500, +262205, +19, +502, +498, +262205, +19, +503, +485, +327828, +6, +504, +502, +503, +196670, +501, +504, +262205, +6, +506, +501, +262205, +6, +507, +501, +327813, +6, +508, +506, +507, +327811, +6, +509, +150, +508, +393228, +6, +510, +1, +31, +509, +196670, +505, +510, +262205, +6, +512, +505, +196670, +511, +512, +262205, +6, +514, +459, +327813, +6, +516, +514, +515, +327813, +6, +518, +516, +517, +327816, +6, +520, +518, +519, +196670, +513, +520, +262205, +6, +522, +501, +262271, +6, +523, +522, +196670, +521, +523, +262205, +6, +525, +505, +196670, +524, +525, +262205, +19, +527, +498, +262205, +19, +528, +490, +327828, +6, +529, +527, +528, +196670, +526, +529, +262205, +6, +531, +526, +262205, +6, +532, +526, +327813, +6, +533, +531, +532, +327811, +6, +534, +150, +533, +393228, +6, +535, +1, +31, +534, +196670, +530, +535, +262205, +6, +537, +521, +262205, +6, +538, +513, +327813, +6, +539, +144, +538, +393228, +6, +540, +1, +14, +539, +327813, +6, +541, +537, +540, +262205, +6, +542, +524, +262205, +6, +543, +513, +327813, +6, +544, +144, +543, +393228, +6, +545, +1, +13, +544, +327813, +6, +546, +542, +545, +327811, +6, +547, +541, +546, +196670, +536, +547, +262205, +6, +549, +536, +262205, +6, +550, +536, +327813, +6, +551, +549, +550, +327811, +6, +552, +150, +551, +393228, +6, +553, +1, +31, +552, +196670, +548, +553, +262205, +6, +555, +536, +262205, +6, +556, +526, +327813, +6, +557, +555, +556, +262205, +6, +558, +548, +262205, +6, +559, +530, +327813, +6, +560, +558, +559, +327809, +6, +561, +557, +560, +458764, +6, +562, +1, +40, +210, +561, +196670, +554, +562, +262205, +6, +564, +521, +262205, +6, +566, +513, +327813, +6, +567, +565, +566, +393228, +6, +568, +1, +14, +567, +327813, +6, +569, +564, +568, +262205, +6, +570, +524, +262205, +6, +571, +513, +327813, +6, +572, +565, +571, +393228, +6, +573, +1, +13, +572, +327813, +6, +574, +570, +573, +327811, +6, +575, +569, +574, +196670, +563, +575, +262205, +6, +577, +563, +262205, +6, +578, +563, +327813, +6, +579, +577, +578, +327811, +6, +580, +150, +579, +393228, +6, +581, +1, +31, +580, +196670, +576, +581, +262205, +6, +583, +563, +262205, +6, +584, +526, +327813, +6, +585, +583, +584, +262205, +6, +586, +576, +262205, +6, +587, +530, +327813, +6, +588, +586, +587, +327809, +6, +589, +585, +588, +458764, +6, +590, +1, +40, +210, +589, +196670, +582, +590, +262205, +6, +592, +460, +327745, +455, +594, +165, +593, +262205, +7, +595, +594, +524367, +19, +596, +595, +595, +0, +1, +2, +327822, +19, +597, +596, +592, +262205, +19, +598, +453, +327813, +19, +599, +597, +598, +262205, +6, +600, +48, +327745, +455, +602, +165, +601, +262205, +7, +603, +602, +524367, +19, +604, +603, +603, +0, +1, +2, +327822, +19, +605, +604, +600, +262205, +6, +606, +464, +262205, +6, +607, +511, +327813, +6, +608, +606, +607, +262205, +19, +609, +453, +327822, +19, +610, +609, +608, +262205, +6, +611, +467, +262205, +6, +612, +554, +262205, +6, +613, +470, +458764, +6, +614, +1, +26, +612, +613, +327813, +6, +615, +611, +614, +393296, +19, +616, +615, +615, +615, +327809, +19, +617, +610, +616, +262205, +6, +618, +473, +262205, +6, +619, +582, +262205, +6, +620, +477, +458764, +6, +621, +1, +26, +619, +620, +327813, +6, +622, +618, +621, +262205, +19, +623, +453, +327822, +19, +624, +623, +622, +327809, +19, +625, +617, +624, +327813, +19, +626, +605, +625, +327809, +19, +627, +599, +626, +196670, +591, +627, +262205, +19, +628, +591, +262205, +6, +629, +48, +327822, +19, +630, +628, +629, +131326, +630, +65592, +327734, +19, +57, +0, +52, +196663, +20, +53, +196663, +20, +54, +196663, +8, +55, +196663, +21, +56, +131320, +58, +262203, +20, +633, +7, +262203, +21, +637, +7, +262203, +20, +640, +7, +327745, +455, +634, +165, +454, +262205, +7, +635, +634, +524367, +19, +636, +635, +635, +0, +1, +2, +196670, +633, +636, +393281, +292, +638, +165, +461, +69, +262205, +6, +639, +638, +196670, +637, +639, +262205, +6, +641, +56, +262205, +6, +642, +637, +327813, +6, +643, +641, +642, +262205, +19, +644, +633, +327822, +19, +645, +644, +643, +196670, +640, +645, +262205, +19, +646, +640, +262205, +6, +647, +56, +327822, +19, +648, +646, +647, +131326, +648, +65592, +}; +const std::vector global_constraints = {119734787, +65536, +524289, +511, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +5, +4, +1852399981, +0, +266, +267, +393232, +4, +17, +64, +1, +1, +196611, +2, +450, +262149, +4, +1852399981, +0, +393221, +12, +1867346761, +1818386806, +1719019621, +15156, +327685, +11, +1953653104, +1701602153, +0, +1114117, +28, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1953718605, +1965584997, +829766449, +993097019, +1765486965, +829766449, +993097019, +1966813557, +15153, +327685, +19, +1633906540, +1684627308, +0, +327685, +20, +1970238055, +1684627312, +0, +458757, +21, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +22, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +23, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +24, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +25, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +26, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +27, +1634890867, +2035573870, +25968, +1114117, +39, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +828980017, +993097019, +1966813557, +829766449, +59, +327685, +30, +1633906540, +1684627308, +0, +327685, +31, +1970238055, +1684627312, +0, +458757, +32, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +33, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +34, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +35, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +36, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +37, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +38, +1634890867, +2035573870, +25968, +983045, +48, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +829766449, +993097019, +0, +327685, +42, +1633906540, +1684627308, +0, +327685, +43, +1970238055, +1684627312, +0, +458757, +44, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +45, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +46, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +47, +1634890867, +2035573870, +25968, +983045, +57, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1953718605, +1764258405, +828980017, +993093947, +1765486965, +829766449, +59, +327685, +51, +1633906540, +1684627308, +0, +327685, +52, +1970238055, +1684627312, +0, +458757, +53, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +54, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +55, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +56, +1634890867, +2035573870, +25968, +786437, +69, +1702129225, +1952543335, +1719019621, +1719024436, +1719024436, +1719024436, +829766452, +993097019, +1715155317, +15153, +327685, +61, +1349678435, +1953067887, +7237481, +327685, +62, +1348758639, +1953067887, +7237481, +327685, +63, +1953066601, +1349280105, +29551, +262149, +64, +1668444006, +101, +458757, +65, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +66, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +67, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +393221, +68, +1886216548, +1130851945, +1717986671, +0, +917509, +77, +1633972309, +1766221172, +1449943406, +1702130277, +1936674936, +1869182057, +1982362478, +1983591526, +1966814310, +829766449, +993097019, +0, +327685, +72, +1348758639, +1953067887, +7237481, +327685, +73, +1350002030, +1953067887, +7237481, +458757, +74, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +75, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +76, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +327685, +88, +1936617283, +1953390964, +115, +327686, +88, +0, +1767333735, +25710, +327686, +88, +1, +1767333735, +3236974, +327686, +88, +2, +1767333735, +3302510, +327686, +88, +3, +1767333735, +3368046, +720902, +88, +4, +1968070503, +1852132461, +1130919015, +1953721967, +1852399986, +1702119796, +1769234802, +7564911, +458758, +88, +5, +1130520423, +1768713327, +1852795251, +0, +524294, +88, +6, +1917280103, +1953068641, +1734430073, +1970563438, +25956, +393222, +88, +7, +1767137127, +1951622509, +28773, +393222, +88, +8, +1631870823, +1852403821, +12391, +786438, +88, +9, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +48, +786438, +88, +10, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12391, +851974, +88, +11, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +811951982, +0, +393222, +88, +12, +1631870823, +1852403821, +12647, +786438, +88, +13, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +49, +786438, +88, +14, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12647, +851974, +88, +15, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +828729198, +0, +393222, +88, +16, +1631870823, +1852403821, +12903, +786438, +88, +17, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +50, +786438, +88, +18, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12903, +851974, +88, +19, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +845506414, +0, +393222, +88, +20, +1631870823, +1852403821, +13159, +786438, +88, +21, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +51, +786438, +88, +22, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +13159, +851974, +88, +23, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +862283630, +0, +720902, +88, +24, +1968070503, +1399213933, +1851880052, +1699771236, +1919439986, +1197760869, +1886744434, +0, +720902, +88, +25, +1968070503, +1819231853, +1215786860, +1936877921, +1198679376, +1701079413, +1919508808, +0, +589830, +88, +26, +1767137127, +1885688688, +1952543329, +1181642601, +1869898593, +114, +327686, +88, +27, +1466064743, +7369313, +786438, +88, +28, +1968070503, +1668238445, +1750297697, +1298493537, +1751348321, +1231515241, +1634887028, +1852795252, +115, +196613, +90, +0, +458757, +122, +1632132967, +1951625833, +1684955506, +1701869908, +0, +327685, +204, +1886680431, +1867543669, +115, +524293, +247, +1953067639, +1818386789, +1701990501, +1936674934, +1869182057, +29550, +655366, +247, +0, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +1701990515, +118, +196613, +249, +0, +458757, +257, +1953067639, +1818386789, +1936674917, +1869182057, +29550, +589830, +257, +0, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +196613, +259, +0, +524293, +266, +1281322087, +1818321775, +1870032457, +1769234787, +1145663087, +0, +393221, +267, +1465871463, +1198223983, +1886744434, +17481, +458757, +268, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +269, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +270, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +271, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +272, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +273, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +274, +1634890867, +2035573870, +25968, +262149, +275, +1634886000, +109, +262149, +279, +1634886000, +109, +262149, +282, +1634886000, +109, +262149, +284, +1634886000, +109, +262149, +286, +1634886000, +109, +262149, +288, +1634886000, +109, +262149, +290, +1634886000, +109, +262149, +292, +1634886000, +109, +262149, +294, +1634886000, +109, +327685, +304, +1920103779, +1349807717, +29551, +327685, +306, +1953066601, +1349280105, +29551, +524293, +310, +1850302311, +1634301033, +1767983212, +1936674930, +1869182057, +29550, +393221, +316, +1684104520, +1851880020, +1919903347, +109, +589830, +316, +0, +1867341671, +1416389988, +1936613746, +1836216166, +1215459142, +6578533, +589830, +316, +1, +1867341671, +1382835556, +1952543855, +1919895141, +1684104520, +0, +589830, +316, +2, +1852396386, +1214606439, +1415864677, +1936613746, +1836216166, +0, +327686, +316, +3, +1684300144, +6778473, +196613, +318, +0, +262149, +341, +1349545332, +29551, +393221, +345, +1886216548, +1130851945, +1717986671, +0, +262149, +384, +1348758639, +29551, +262149, +390, +1668444006, +101, +262149, +391, +1634886000, +109, +262149, +398, +1634886000, +109, +262149, +400, +1634886000, +109, +262149, +402, +1634886000, +109, +262149, +404, +1634886000, +109, +262149, +406, +1634886000, +109, +262149, +407, +1634886000, +109, +262149, +409, +1634886000, +109, +262149, +411, +1634886000, +109, +655365, +416, +1718187123, +1936027238, +1919895155, +1651469383, +1750297697, +1298493537, +1751348321, +6778473, +720901, +417, +1651469415, +1750297697, +1298493537, +1751348321, +1164406377, +1667589734, +1702259060, +1735287122, +101, +262149, +468, +1634886000, +109, +262149, +482, +1952670054, +29295, +196613, +485, +7103844, +262149, +500, +1634886000, +109, +262149, +502, +1634886000, +109, +262149, +504, +1634886000, +109, +262149, +505, +1634886000, +109, +262149, +507, +1634886000, +109, +327752, +88, +0, +35, +0, +327752, +88, +1, +35, +16, +327752, +88, +2, +35, +32, +327752, +88, +3, +35, +48, +327752, +88, +4, +35, +64, +327752, +88, +5, +35, +68, +327752, +88, +6, +35, +72, +327752, +88, +7, +35, +76, +327752, +88, +8, +35, +80, +327752, +88, +9, +35, +84, +327752, +88, +10, +35, +88, +327752, +88, +11, +35, +92, +327752, +88, +12, +35, +96, +327752, +88, +13, +35, +100, +327752, +88, +14, +35, +104, +327752, +88, +15, +35, +108, +327752, +88, +16, +35, +112, +327752, +88, +17, +35, +116, +327752, +88, +18, +35, +120, +327752, +88, +19, +35, +124, +327752, +88, +20, +35, +128, +327752, +88, +21, +35, +132, +327752, +88, +22, +35, +136, +327752, +88, +23, +35, +140, +327752, +88, +24, +35, +144, +327752, +88, +25, +35, +148, +327752, +88, +26, +35, +152, +327752, +88, +27, +35, +156, +327752, +88, +28, +35, +160, +196679, +88, +3, +262215, +90, +34, +0, +262215, +90, +33, +16, +262215, +122, +34, +1, +262215, +122, +33, +22, +262215, +246, +6, +16, +327752, +247, +0, +35, +0, +196679, +247, +3, +262215, +249, +34, +1, +262215, +249, +33, +20, +262215, +256, +6, +16, +327752, +257, +0, +35, +0, +196679, +257, +3, +262215, +259, +34, +1, +262215, +259, +33, +7, +262215, +266, +11, +27, +262215, +267, +11, +26, +262215, +310, +34, +1, +262215, +310, +33, +21, +262215, +315, +6, +16, +262216, +316, +0, +5, +327752, +316, +0, +35, +0, +327752, +316, +0, +7, +16, +327752, +316, +1, +35, +64, +327752, +316, +2, +35, +80, +327752, +316, +3, +35, +96, +196679, +316, +3, +262215, +318, +34, +0, +262215, +318, +33, +27, +262215, +510, +11, +25, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +131092, +9, +262177, +10, +9, +8, +262165, +14, +32, +0, +262176, +15, +7, +14, +262165, +16, +32, +1, +262176, +17, +7, +16, +786465, +18, +2, +15, +15, +15, +15, +17, +15, +15, +15, +15, +589857, +41, +2, +15, +15, +15, +15, +15, +15, +589857, +50, +2, +17, +17, +17, +15, +17, +15, +262176, +59, +7, +6, +720929, +60, +7, +8, +8, +8, +8, +15, +15, +15, +59, +524321, +71, +2, +8, +8, +15, +15, +15, +262187, +14, +79, +3, +262187, +6, +82, +0, +262187, +14, +87, +64, +2031646, +88, +7, +7, +7, +7, +16, +16, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +14, +14, +6, +16, +16, +262176, +89, +2, +88, +262203, +89, +90, +2, +262187, +16, +91, +24, +262176, +92, +2, +14, +262187, +16, +106, +25, +262187, +14, +109, +1, +589849, +119, +14, +5, +0, +0, +0, +1, +0, +196635, +120, +119, +262176, +121, +0, +120, +262203, +121, +122, +0, +262167, +126, +14, +4, +262187, +14, +128, +0, +262187, +16, +182, +64, +262187, +16, +206, +6, +262176, +207, +2, +6, +262167, +210, +6, +3, +262187, +6, +211, +3212836864, +393260, +210, +212, +82, +211, +82, +262187, +6, +221, +1065353216, +262187, +16, +233, +7, +196637, +246, +7, +196638, +247, +246, +262176, +248, +2, +247, +262203, +248, +249, +2, +262187, +16, +250, +0, +262176, +254, +2, +7, +196637, +256, +7, +196638, +257, +256, +262176, +258, +2, +257, +262203, +258, +259, +2, +262167, +264, +14, +3, +262176, +265, +1, +264, +262203, +265, +266, +1, +262203, +265, +267, +1, +262176, +276, +1, +14, +458796, +7, +305, +82, +82, +82, +82, +589849, +307, +6, +5, +0, +0, +0, +1, +0, +196635, +308, +307, +262176, +309, +0, +308, +262203, +309, +310, +0, +262168, +314, +7, +4, +262172, +315, +6, +79, +393246, +316, +314, +7, +16, +315, +262176, +317, +2, +316, +262203, +317, +318, +2, +262176, +319, +2, +314, +262187, +16, +332, +27, +262176, +333, +2, +16, +262187, +6, +346, +1022739087, +262187, +16, +351, +8, +262187, +16, +359, +12, +262187, +14, +364, +2, +262187, +16, +368, +16, +262187, +16, +376, +20, +262187, +16, +422, +10, +262187, +16, +425, +11, +262187, +16, +433, +14, +262187, +16, +436, +15, +262187, +16, +444, +18, +262187, +16, +447, +19, +262187, +16, +455, +22, +262187, +16, +458, +23, +262176, +484, +7, +210, +393260, +264, +510, +87, +109, +109, +327734, +2, +4, +0, +3, +131320, +5, +262203, +15, +268, +7, +262203, +15, +269, +7, +262203, +17, +270, +7, +262203, +15, +271, +7, +262203, +15, +272, +7, +262203, +15, +273, +7, +262203, +15, +274, +7, +262203, +15, +275, +7, +262203, +15, +279, +7, +262203, +15, +282, +7, +262203, +15, +284, +7, +262203, +17, +286, +7, +262203, +15, +288, +7, +262203, +15, +290, +7, +262203, +15, +292, +7, +262203, +15, +294, +7, +262203, +8, +304, +7, +262203, +8, +306, +7, +262203, +8, +341, +7, +262203, +59, +345, +7, +262203, +8, +384, +7, +262203, +8, +390, +7, +262203, +8, +391, +7, +262203, +8, +398, +7, +262203, +8, +400, +7, +262203, +8, +402, +7, +262203, +8, +404, +7, +262203, +15, +406, +7, +262203, +15, +407, +7, +262203, +15, +409, +7, +262203, +59, +411, +7, +262203, +59, +416, +7, +262203, +59, +417, +7, +262203, +8, +468, +7, +262203, +59, +482, +7, +262203, +484, +485, +7, +262203, +8, +500, +7, +262203, +8, +502, +7, +262203, +15, +504, +7, +262203, +15, +505, +7, +262203, +15, +507, +7, +327745, +276, +277, +266, +128, +262205, +14, +278, +277, +196670, +275, +278, +327745, +276, +280, +267, +128, +262205, +14, +281, +280, +196670, +279, +281, +262205, +14, +283, +268, +196670, +282, +283, +262205, +14, +285, +269, +196670, +284, +285, +262205, +16, +287, +270, +196670, +286, +287, +262205, +14, +289, +271, +196670, +288, +289, +262205, +14, +291, +272, +196670, +290, +291, +262205, +14, +293, +273, +196670, +292, +293, +262205, +14, +295, +274, +196670, +294, +295, +852025, +2, +296, +28, +275, +279, +282, +284, +286, +288, +290, +292, +294, +262205, +14, +297, +282, +196670, +268, +297, +262205, +14, +298, +284, +196670, +269, +298, +262205, +16, +299, +286, +196670, +270, +299, +262205, +14, +300, +288, +196670, +271, +300, +262205, +14, +301, +290, +196670, +272, +301, +262205, +14, +302, +292, +196670, +273, +302, +262205, +14, +303, +294, +196670, +274, +303, +196670, +304, +305, +196670, +306, +305, +262205, +308, +311, +310, +262205, +16, +312, +270, +327775, +7, +313, +311, +312, +196670, +306, +313, +327745, +319, +320, +318, +250, +262205, +314, +321, +320, +262205, +7, +322, +306, +524367, +210, +323, +322, +322, +0, +1, +2, +327761, +6, +324, +323, +0, +327761, +6, +325, +323, +1, +327761, +6, +326, +323, +2, +458832, +7, +327, +324, +325, +326, +221, +327825, +7, +328, +321, +327, +524367, +210, +329, +328, +328, +0, +1, +2, +262205, +7, +330, +306, +589903, +7, +331, +330, +329, +4, +5, +6, +3, +196670, +306, +331, +327745, +333, +334, +90, +332, +262205, +16, +335, +334, +327851, +9, +336, +335, +250, +196855, +338, +0, +262394, +336, +337, +340, +131320, +337, +262205, +7, +339, +306, +196670, +304, +339, +131321, +338, +131320, +340, +262205, +16, +342, +270, +393281, +254, +343, +259, +250, +342, +262205, +7, +344, +343, +196670, +341, +344, +196670, +304, +344, +131321, +338, +131320, +338, +196670, +345, +346, +262205, +14, +347, +274, +327850, +9, +348, +347, +128, +196855, +350, +0, +262394, +348, +349, +354, +131320, +349, +327745, +207, +352, +90, +351, +262205, +6, +353, +352, +196670, +345, +353, +131321, +350, +131320, +354, +262205, +14, +355, +274, +327850, +9, +356, +355, +109, +196855, +358, +0, +262394, +356, +357, +362, +131320, +357, +327745, +207, +360, +90, +359, +262205, +6, +361, +360, +196670, +345, +361, +131321, +358, +131320, +362, +262205, +14, +363, +274, +327850, +9, +365, +363, +364, +196855, +367, +0, +262394, +365, +366, +371, +131320, +366, +327745, +207, +369, +90, +368, +262205, +6, +370, +369, +196670, +345, +370, +131321, +367, +131320, +371, +262205, +14, +372, +274, +327850, +9, +373, +372, +79, +196855, +375, +0, +262394, +373, +374, +375, +131320, +374, +327745, +207, +377, +90, +376, +262205, +6, +378, +377, +196670, +345, +378, +131321, +375, +131320, +375, +131321, +367, +131320, +367, +131321, +358, +131320, +358, +131321, +350, +131320, +350, +327745, +333, +379, +90, +332, +262205, +16, +380, +379, +327851, +9, +381, +380, +250, +196855, +383, +0, +262394, +381, +382, +386, +131320, +382, +262205, +7, +385, +304, +196670, +384, +385, +131321, +383, +131320, +386, +262205, +16, +387, +270, +393281, +254, +388, +249, +250, +387, +262205, +7, +389, +388, +196670, +384, +389, +131321, +383, +131320, +383, +196670, +390, +305, +262205, +7, +392, +304, +196670, +391, +392, +327737, +9, +393, +12, +391, +196855, +395, +0, +262394, +393, +394, +414, +131320, +394, +262205, +16, +396, +270, +262268, +14, +397, +396, +262205, +7, +399, +304, +196670, +398, +399, +262205, +7, +401, +384, +196670, +400, +401, +262205, +7, +403, +306, +196670, +402, +403, +262205, +7, +405, +390, +196670, +404, +405, +196670, +406, +397, +262205, +14, +408, +271, +196670, +407, +408, +262205, +14, +410, +272, +196670, +409, +410, +262205, +6, +412, +345, +196670, +411, +412, +786489, +7, +413, +69, +398, +400, +402, +404, +406, +407, +409, +411, +196670, +341, +413, +131321, +395, +131320, +414, +262205, +7, +415, +306, +196670, +341, +415, +131321, +395, +131320, +395, +196670, +416, +82, +196670, +417, +82, +262205, +14, +418, +274, +327850, +9, +419, +418, +128, +196855, +421, +0, +262394, +419, +420, +428, +131320, +420, +327745, +207, +423, +90, +422, +262205, +6, +424, +423, +196670, +416, +424, +327745, +207, +426, +90, +425, +262205, +6, +427, +426, +196670, +417, +427, +131321, +421, +131320, +428, +262205, +14, +429, +274, +327850, +9, +430, +429, +109, +196855, +432, +0, +262394, +430, +431, +439, +131320, +431, +327745, +207, +434, +90, +433, +262205, +6, +435, +434, +196670, +416, +435, +327745, +207, +437, +90, +436, +262205, +6, +438, +437, +196670, +417, +438, +131321, +432, +131320, +439, +262205, +14, +440, +274, +327850, +9, +441, +440, +364, +196855, +443, +0, +262394, +441, +442, +450, +131320, +442, +327745, +207, +445, +90, +444, +262205, +6, +446, +445, +196670, +416, +446, +327745, +207, +448, +90, +447, +262205, +6, +449, +448, +196670, +417, +449, +131321, +443, +131320, +450, +262205, +14, +451, +274, +327850, +9, +452, +451, +79, +196855, +454, +0, +262394, +452, +453, +454, +131320, +453, +327745, +207, +456, +90, +455, +262205, +6, +457, +456, +196670, +416, +457, +327745, +207, +459, +90, +458, +262205, +6, +460, +459, +196670, +417, +460, +131321, +454, +131320, +454, +131321, +443, +131320, +443, +131321, +432, +131320, +432, +131321, +421, +131320, +421, +262205, +6, +461, +416, +327866, +9, +462, +461, +82, +262205, +6, +463, +417, +327862, +9, +464, +463, +82, +327847, +9, +465, +462, +464, +196855, +467, +0, +262394, +465, +466, +467, +131320, +466, +262205, +7, +469, +341, +196670, +468, +469, +327737, +9, +470, +12, +468, +196855, +472, +0, +262394, +470, +471, +472, +131320, +471, +262205, +14, +473, +271, +262256, +6, +474, +473, +262205, +6, +475, +417, +262205, +14, +476, +272, +262256, +6, +477, +476, +327813, +6, +478, +475, +477, +327864, +9, +479, +474, +478, +196855, +481, +0, +262394, +479, +480, +481, +131320, +480, +262205, +6, +483, +416, +196670, +482, +483, +262205, +6, +486, +482, +262205, +7, +487, +306, +262205, +7, +488, +341, +327811, +7, +489, +487, +488, +524367, +210, +490, +489, +489, +0, +1, +2, +327822, +210, +491, +490, +486, +196670, +485, +491, +262205, +210, +492, +485, +262205, +7, +493, +341, +524367, +210, +494, +493, +493, +0, +1, +2, +327809, +210, +495, +494, +492, +262205, +7, +496, +341, +589903, +7, +497, +496, +495, +4, +5, +6, +3, +196670, +341, +497, +131321, +481, +131320, +481, +131321, +472, +131320, +472, +131321, +467, +131320, +467, +262205, +16, +498, +270, +262268, +14, +499, +498, +262205, +7, +501, +304, +196670, +500, +501, +262205, +7, +503, +341, +196670, +502, +503, +196670, +504, +499, +262205, +14, +506, +271, +196670, +505, +506, +262205, +14, +508, +272, +196670, +507, +508, +589881, +2, +509, +77, +500, +502, +504, +505, +507, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +327745, +59, +80, +11, +79, +262205, +6, +81, +80, +327866, +9, +83, +81, +82, +131326, +83, +65592, +327734, +2, +28, +0, +18, +196663, +15, +19, +196663, +15, +20, +196663, +15, +21, +196663, +15, +22, +196663, +17, +23, +196663, +15, +24, +196663, +15, +25, +196663, +15, +26, +196663, +15, +27, +131320, +29, +262205, +14, +86, +19, +196670, +26, +86, +327745, +92, +93, +90, +91, +262205, +14, +94, +93, +327814, +14, +95, +87, +94, +196670, +25, +95, +262205, +14, +96, +19, +327745, +92, +97, +90, +91, +262205, +14, +98, +97, +327817, +14, +99, +96, +98, +196670, +22, +99, +262205, +14, +100, +20, +327745, +92, +101, +90, +91, +262205, +14, +102, +101, +327812, +14, +103, +100, +102, +262205, +14, +104, +22, +327808, +14, +105, +103, +104, +196670, +21, +105, +327745, +92, +107, +90, +106, +262205, +14, +108, +107, +327808, +14, +110, +108, +109, +262205, +14, +111, +21, +327812, +14, +112, +111, +110, +196670, +21, +112, +262205, +14, +113, +19, +262205, +14, +114, +22, +327810, +14, +115, +113, +114, +327745, +92, +116, +90, +91, +262205, +14, +117, +116, +327814, +14, +118, +115, +117, +196670, +24, +118, +262205, +120, +123, +122, +262205, +14, +124, +21, +262268, +16, +125, +124, +327775, +126, +127, +123, +125, +327761, +14, +129, +127, +0, +196670, +27, +129, +262205, +14, +130, +21, +262205, +14, +131, +25, +327812, +14, +132, +130, +131, +262205, +14, +133, +24, +327808, +14, +134, +132, +133, +262268, +16, +135, +134, +196670, +23, +135, +65789, +65592, +327734, +2, +39, +0, +18, +196663, +15, +30, +196663, +15, +31, +196663, +15, +32, +196663, +15, +33, +196663, +17, +34, +196663, +15, +35, +196663, +15, +36, +196663, +15, +37, +196663, +15, +38, +131320, +40, +262205, +14, +136, +30, +196670, +37, +136, +327745, +92, +137, +90, +91, +262205, +14, +138, +137, +327814, +14, +139, +87, +138, +196670, +36, +139, +262205, +14, +140, +30, +327745, +92, +141, +90, +91, +262205, +14, +142, +141, +327817, +14, +143, +140, +142, +196670, +33, +143, +262205, +14, +144, +31, +327745, +92, +145, +90, +91, +262205, +14, +146, +145, +327812, +14, +147, +144, +146, +262205, +14, +148, +33, +327808, +14, +149, +147, +148, +196670, +32, +149, +262205, +14, +150, +30, +262205, +14, +151, +33, +327810, +14, +152, +150, +151, +327745, +92, +153, +90, +91, +262205, +14, +154, +153, +327814, +14, +155, +152, +154, +196670, +35, +155, +262205, +120, +156, +122, +262205, +14, +157, +32, +262268, +16, +158, +157, +327775, +126, +159, +156, +158, +327761, +14, +160, +159, +0, +196670, +38, +160, +262205, +14, +161, +32, +262205, +14, +162, +36, +327812, +14, +163, +161, +162, +262205, +14, +164, +35, +327808, +14, +165, +163, +164, +262268, +16, +166, +165, +196670, +34, +166, +65789, +65592, +327734, +2, +48, +0, +41, +196663, +15, +42, +196663, +15, +43, +196663, +15, +44, +196663, +15, +45, +196663, +15, +46, +196663, +15, +47, +131320, +49, +262205, +14, +167, +43, +327812, +14, +168, +87, +167, +262205, +14, +169, +42, +327808, +14, +170, +168, +169, +196670, +44, +170, +327745, +92, +171, +90, +91, +262205, +14, +172, +171, +327814, +14, +173, +87, +172, +196670, +45, +173, +262205, +120, +174, +122, +262205, +14, +175, +44, +262268, +16, +176, +175, +327775, +126, +177, +174, +176, +327761, +14, +178, +177, +0, +196670, +47, +178, +262205, +14, +179, +44, +262205, +14, +180, +45, +327812, +14, +181, +179, +180, +196670, +46, +181, +65789, +65592, +327734, +2, +57, +0, +50, +196663, +17, +51, +196663, +17, +52, +196663, +17, +53, +196663, +15, +54, +196663, +17, +55, +196663, +15, +56, +131320, +58, +262205, +16, +183, +52, +327812, +16, +184, +182, +183, +262205, +16, +185, +51, +327808, +16, +186, +184, +185, +196670, +53, +186, +327745, +92, +187, +90, +106, +262205, +14, +188, +187, +327808, +14, +189, +188, +109, +262268, +16, +190, +189, +262205, +16, +191, +53, +327812, +16, +192, +191, +190, +196670, +53, +192, +327745, +92, +193, +90, +91, +262205, +14, +194, +193, +327814, +14, +195, +87, +194, +196670, +54, +195, +262205, +120, +196, +122, +262205, +16, +197, +53, +327775, +126, +198, +196, +197, +327761, +14, +199, +198, +0, +196670, +56, +199, +262205, +16, +200, +53, +262205, +14, +201, +54, +262268, +16, +202, +201, +327812, +16, +203, +200, +202, +196670, +55, +203, +65789, +65592, +327734, +7, +69, +0, +60, +196663, +8, +61, +196663, +8, +62, +196663, +8, +63, +196663, +8, +64, +196663, +15, +65, +196663, +15, +66, +196663, +15, +67, +196663, +59, +68, +131320, +70, +262203, +8, +204, +7, +262205, +7, +205, +61, +196670, +204, +205, +327745, +207, +208, +90, +206, +262205, +6, +209, +208, +327822, +210, +213, +212, +209, +262205, +7, +214, +64, +524367, +210, +215, +214, +214, +0, +1, +2, +327809, +210, +216, +215, +213, +262205, +7, +217, +64, +589903, +7, +218, +217, +216, +4, +5, +6, +3, +196670, +64, +218, +262205, +7, +219, +61, +524367, +210, +220, +219, +219, +0, +1, +2, +262205, +6, +222, +68, +327811, +6, +223, +221, +222, +262205, +7, +224, +61, +524367, +210, +225, +224, +224, +0, +1, +2, +262205, +7, +226, +62, +524367, +210, +227, +226, +226, +0, +1, +2, +327811, +210, +228, +225, +227, +327822, +210, +229, +228, +223, +327809, +210, +230, +220, +229, +262205, +7, +231, +64, +524367, +210, +232, +231, +231, +0, +1, +2, +327745, +207, +234, +90, +233, +262205, +6, +235, +234, +327822, +210, +236, +232, +235, +327745, +207, +237, +90, +233, +262205, +6, +238, +237, +327822, +210, +239, +236, +238, +327809, +210, +240, +230, +239, +262205, +7, +241, +204, +589903, +7, +242, +241, +240, +4, +5, +6, +3, +196670, +204, +242, +262205, +7, +243, +204, +131326, +243, +65592, +327734, +2, +77, +0, +71, +196663, +8, +72, +196663, +8, +73, +196663, +15, +74, +196663, +15, +75, +196663, +15, +76, +131320, +78, +262205, +14, +251, +74, +262268, +16, +252, +251, +262205, +7, +253, +72, +393281, +254, +255, +249, +250, +252, +196670, +255, +253, +262205, +14, +260, +74, +262268, +16, +261, +260, +262205, +7, +262, +73, +393281, +254, +263, +259, +250, +261, +196670, +263, +262, +65789, +65592, +}; +const std::vector local_constraints = {119734787, +65536, +524289, +701, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +5, +4, +1852399981, +0, +417, +422, +393232, +4, +17, +64, +1, +1, +196611, +2, +450, +262149, +4, +1852399981, +0, +393221, +12, +1867346761, +1818386806, +1719019621, +15156, +327685, +11, +1953653104, +1701602153, +0, +1114117, +28, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1953718605, +1965584997, +829766449, +993097019, +1765486965, +829766449, +993097019, +1966813557, +15153, +327685, +19, +1633906540, +1684627308, +0, +327685, +20, +1970238055, +1684627312, +0, +458757, +21, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +22, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +23, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +24, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +25, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +26, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +27, +1634890867, +2035573870, +25968, +1114117, +39, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +828980017, +993097019, +1966813557, +829766449, +59, +327685, +30, +1633906540, +1684627308, +0, +327685, +31, +1970238055, +1684627312, +0, +458757, +32, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +33, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +34, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +35, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +36, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +37, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +38, +1634890867, +2035573870, +25968, +983045, +48, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +829766449, +993097019, +0, +327685, +42, +1633906540, +1684627308, +0, +327685, +43, +1970238055, +1684627312, +0, +458757, +44, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +45, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +46, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +47, +1634890867, +2035573870, +25968, +983045, +57, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1953718605, +1764258405, +828980017, +993093947, +1765486965, +829766449, +59, +327685, +51, +1633906540, +1684627308, +0, +327685, +52, +1970238055, +1684627312, +0, +458757, +53, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +54, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +55, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +56, +1634890867, +2035573870, +25968, +786437, +62, +1953264973, +1952544081, +1768845925, +1849781871, +1635078500, +1852990836, +678326121, +993289846, +993289846, +0, +196613, +60, +16753, +196613, +61, +17009, +720901, +69, +1953264973, +1952544081, +1768845925, +1849781871, +1667585636, +678588276, +993289846, +993224310, +0, +196613, +67, +113, +196613, +68, +118, +524293, +75, +1701536077, +1952544081, +1768845925, +1713925743, +1719024433, +15155, +393221, +73, +1818717793, +1634885477, +1851877732, +0, +262149, +74, +1936291937, +0, +524293, +79, +1702260297, +1365603186, +1702125941, +1869180530, +1719019630, +15156, +196613, +78, +113, +327685, +90, +1936617283, +1953390964, +115, +327686, +90, +0, +1767333735, +25710, +327686, +90, +1, +1767333735, +3236974, +327686, +90, +2, +1767333735, +3302510, +327686, +90, +3, +1767333735, +3368046, +720902, +90, +4, +1968070503, +1852132461, +1130919015, +1953721967, +1852399986, +1702119796, +1769234802, +7564911, +458758, +90, +5, +1130520423, +1768713327, +1852795251, +0, +524294, +90, +6, +1917280103, +1953068641, +1734430073, +1970563438, +25956, +393222, +90, +7, +1767137127, +1951622509, +28773, +393222, +90, +8, +1631870823, +1852403821, +12391, +786438, +90, +9, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +48, +786438, +90, +10, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12391, +851974, +90, +11, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +811951982, +0, +393222, +90, +12, +1631870823, +1852403821, +12647, +786438, +90, +13, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +49, +786438, +90, +14, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12647, +851974, +90, +15, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +828729198, +0, +393222, +90, +16, +1631870823, +1852403821, +12903, +786438, +90, +17, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +50, +786438, +90, +18, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12903, +851974, +90, +19, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +845506414, +0, +393222, +90, +20, +1631870823, +1852403821, +13159, +786438, +90, +21, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +51, +786438, +90, +22, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +13159, +851974, +90, +23, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +862283630, +0, +720902, +90, +24, +1968070503, +1399213933, +1851880052, +1699771236, +1919439986, +1197760869, +1886744434, +0, +720902, +90, +25, +1968070503, +1819231853, +1215786860, +1936877921, +1198679376, +1701079413, +1919508808, +0, +589830, +90, +26, +1767137127, +1885688688, +1952543329, +1181642601, +1869898593, +114, +327686, +90, +27, +1466064743, +7369313, +786438, +90, +28, +1968070503, +1668238445, +1750297697, +1298493537, +1751348321, +1231515241, +1634887028, +1852795252, +115, +196613, +92, +0, +458757, +124, +1632132967, +1951625833, +1684955506, +1701869908, +0, +196613, +206, +113, +262149, +307, +1667593841, +0, +196613, +315, +30325, +196613, +319, +7763317, +327685, +338, +1718378856, +1818717761, +101, +262149, +342, +1215195507, +6712417, +327685, +345, +1952544113, +1768845925, +28271, +327685, +357, +1735288172, +1901291636, +114, +524293, +417, +1281322087, +1818321775, +1870032457, +1769234787, +1145663087, +0, +393221, +422, +1465871463, +1198223983, +1886744434, +17481, +458757, +426, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +427, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +428, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +429, +1634890867, +2035573870, +25968, +262149, +430, +1634886000, +109, +262149, +431, +1634886000, +109, +262149, +432, +1634886000, +109, +262149, +434, +1634886000, +109, +262149, +436, +1634886000, +109, +262149, +438, +1634886000, +109, +655365, +445, +1718187123, +1936027238, +1919895155, +1633906508, +1634227052, +1632462192, +1768448884, +26478, +458757, +483, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +485, +1633906540, +1919243884, +1232627060, +2019910766, +0, +393221, +501, +1918986355, +1951622245, +1684955506, +7565136, +458757, +504, +1953067639, +1818386789, +1936674917, +1869182057, +29550, +589830, +504, +0, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +196613, +506, +0, +327685, +515, +1919251561, +1869182049, +29550, +196613, +527, +7565168, +327685, +530, +1198813042, +1633841004, +108, +458757, +534, +1816616807, +1818321519, +1635020626, +1852795252, +115, +458757, +538, +1633906540, +1919243884, +1232627060, +2019910766, +0, +393221, +552, +1601400688, +1937075312, +1701736287, +0, +393221, +557, +1198813042, +1633841004, +1919899500, +25708, +393221, +560, +1684104520, +1851880020, +1919903347, +109, +589830, +560, +0, +1867341671, +1416389988, +1936613746, +1836216166, +1215459142, +6578533, +589830, +560, +1, +1867341671, +1382835556, +1952543855, +1919895141, +1684104520, +0, +589830, +560, +2, +1852396386, +1214606439, +1415864677, +1936613746, +1836216166, +0, +327686, +560, +3, +1684300144, +6778473, +196613, +562, +0, +262149, +563, +1634886000, +109, +262149, +566, +1634886000, +109, +655365, +569, +1348956783, +1767863151, +1970040927, +1597071219, +1867279945, +1181507939, +1701667186, +26975, +589829, +570, +1632132967, +1699902057, +1667585638, +1282296179, +1818321775, +1835102790, +101, +655365, +576, +1348956783, +1767863151, +1970040927, +1597071219, +1816620617, +1818321519, +1835102790, +101, +262149, +577, +1634886000, +109, +262149, +579, +1634886000, +109, +196613, +585, +7103844, +262149, +592, +1634886000, +109, +262149, +603, +1634886000, +109, +458757, +614, +1383493225, +1816622191, +1818321519, +1819438935, +100, +262149, +615, +1634886000, +109, +196613, +618, +6514038, +458757, +625, +1600741240, +1937075312, +1717514591, +1701667186, +26975, +262149, +626, +1634886000, +109, +262149, +628, +1634886000, +109, +196613, +632, +101, +262149, +634, +1098149746, +7563640, +393221, +643, +1818717793, +1634885477, +1851877732, +0, +327685, +650, +1633906540, +1953452652, +0, +262149, +651, +1634886000, +109, +262149, +653, +1634886000, +109, +262149, +656, +1634886000, +109, +262149, +658, +1634886000, +109, +458757, +679, +1633906540, +1919243884, +1232627060, +2019910766, +0, +327752, +90, +0, +35, +0, +327752, +90, +1, +35, +16, +327752, +90, +2, +35, +32, +327752, +90, +3, +35, +48, +327752, +90, +4, +35, +64, +327752, +90, +5, +35, +68, +327752, +90, +6, +35, +72, +327752, +90, +7, +35, +76, +327752, +90, +8, +35, +80, +327752, +90, +9, +35, +84, +327752, +90, +10, +35, +88, +327752, +90, +11, +35, +92, +327752, +90, +12, +35, +96, +327752, +90, +13, +35, +100, +327752, +90, +14, +35, +104, +327752, +90, +15, +35, +108, +327752, +90, +16, +35, +112, +327752, +90, +17, +35, +116, +327752, +90, +18, +35, +120, +327752, +90, +19, +35, +124, +327752, +90, +20, +35, +128, +327752, +90, +21, +35, +132, +327752, +90, +22, +35, +136, +327752, +90, +23, +35, +140, +327752, +90, +24, +35, +144, +327752, +90, +25, +35, +148, +327752, +90, +26, +35, +152, +327752, +90, +27, +35, +156, +327752, +90, +28, +35, +160, +196679, +90, +3, +262215, +92, +34, +0, +262215, +92, +33, +16, +262215, +124, +34, +1, +262215, +124, +33, +22, +262215, +417, +11, +27, +262215, +422, +11, +26, +262215, +503, +6, +16, +327752, +504, +0, +35, +0, +196679, +504, +3, +262215, +506, +34, +1, +262215, +506, +33, +7, +262215, +534, +34, +1, +262215, +534, +33, +23, +262215, +559, +6, +16, +262216, +560, +0, +5, +327752, +560, +0, +35, +0, +327752, +560, +0, +7, +16, +327752, +560, +1, +35, +64, +327752, +560, +2, +35, +80, +327752, +560, +3, +35, +96, +196679, +560, +3, +262215, +562, +34, +0, +262215, +562, +33, +27, +262215, +570, +34, +1, +262215, +570, +33, +24, +262215, +700, +11, +25, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +131092, +9, +262177, +10, +9, +8, +262165, +14, +32, +0, +262176, +15, +7, +14, +262165, +16, +32, +1, +262176, +17, +7, +16, +786465, +18, +2, +15, +15, +15, +15, +17, +15, +15, +15, +15, +589857, +41, +2, +15, +15, +15, +15, +15, +15, +589857, +50, +2, +17, +17, +17, +15, +17, +15, +327713, +59, +7, +8, +8, +262167, +64, +6, +3, +262176, +65, +7, +64, +327713, +66, +64, +8, +65, +262176, +71, +7, +6, +327713, +72, +7, +71, +65, +262177, +77, +7, +8, +262187, +14, +81, +3, +262187, +6, +84, +0, +262187, +14, +89, +64, +2031646, +90, +7, +7, +7, +7, +16, +16, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +14, +14, +6, +16, +16, +262176, +91, +2, +90, +262203, +91, +92, +2, +262187, +16, +93, +24, +262176, +94, +2, +14, +262187, +16, +108, +25, +262187, +14, +111, +1, +589849, +121, +14, +5, +0, +0, +0, +1, +0, +196635, +122, +121, +262176, +123, +0, +122, +262203, +123, +124, +0, +262167, +128, +14, +4, +262187, +14, +130, +0, +262187, +16, +184, +64, +262187, +14, +224, +2, +262187, +6, +323, +1073741824, +262187, +6, +339, +1056964608, +262187, +6, +382, +981668463, +262187, +6, +386, +1065353216, +458796, +7, +387, +84, +84, +84, +386, +262167, +415, +14, +3, +262176, +416, +1, +415, +262203, +416, +417, +1, +262176, +418, +1, +14, +262203, +416, +422, +1, +262187, +6, +446, +1053609165, +262187, +16, +451, +17, +262176, +452, +2, +6, +262187, +16, +460, +21, +262187, +16, +468, +13, +262187, +16, +476, +9, +262187, +6, +480, +1064514355, +262187, +16, +484, +0, +262187, +14, +498, +16, +262172, +499, +7, +498, +262176, +500, +7, +499, +196637, +503, +7, +196638, +504, +503, +262176, +505, +2, +504, +262203, +505, +506, +2, +262176, +508, +2, +7, +262187, +16, +513, +1, +262187, +16, +522, +28, +262176, +523, +2, +16, +589849, +531, +6, +5, +0, +0, +0, +1, +0, +196635, +532, +531, +262176, +533, +0, +532, +262203, +533, +534, +0, +262168, +558, +7, +4, +262172, +559, +6, +81, +393246, +560, +558, +7, +16, +559, +262176, +561, +2, +560, +262203, +561, +562, +2, +262203, +533, +570, +0, +393260, +64, +633, +386, +84, +84, +393260, +415, +700, +89, +111, +111, +327734, +2, +4, +0, +3, +131320, +5, +262203, +17, +426, +7, +262203, +15, +427, +7, +262203, +17, +428, +7, +262203, +15, +429, +7, +262203, +17, +430, +7, +262203, +17, +431, +7, +262203, +17, +432, +7, +262203, +15, +434, +7, +262203, +17, +436, +7, +262203, +15, +438, +7, +262203, +71, +445, +7, +262203, +17, +483, +7, +262203, +17, +485, +7, +262203, +500, +501, +7, +262203, +17, +515, +7, +262203, +8, +527, +7, +262203, +8, +530, +7, +262203, +17, +538, +7, +262203, +8, +552, +7, +262203, +8, +557, +7, +262203, +8, +563, +7, +262203, +8, +566, +7, +262203, +65, +569, +7, +262203, +65, +576, +7, +262203, +8, +577, +7, +262203, +65, +579, +7, +262203, +65, +585, +7, +262203, +8, +592, +7, +262203, +8, +603, +7, +262203, +8, +614, +7, +262203, +8, +615, +7, +262203, +65, +618, +7, +262203, +65, +625, +7, +262203, +8, +626, +7, +262203, +65, +628, +7, +262203, +65, +632, +7, +262203, +65, +634, +7, +262203, +71, +643, +7, +262203, +8, +650, +7, +262203, +71, +651, +7, +262203, +65, +653, +7, +262203, +8, +656, +7, +262203, +8, +658, +7, +262203, +17, +679, +7, +327745, +418, +419, +417, +130, +262205, +14, +420, +419, +262268, +16, +421, +420, +327745, +418, +423, +422, +130, +262205, +14, +424, +423, +262268, +16, +425, +424, +196670, +430, +421, +196670, +431, +425, +262205, +16, +433, +426, +196670, +432, +433, +262205, +14, +435, +427, +196670, +434, +435, +262205, +16, +437, +428, +196670, +436, +437, +262205, +14, +439, +429, +196670, +438, +439, +655417, +2, +440, +57, +430, +431, +432, +434, +436, +438, +262205, +16, +441, +432, +196670, +426, +441, +262205, +14, +442, +434, +196670, +427, +442, +262205, +16, +443, +436, +196670, +428, +443, +262205, +14, +444, +438, +196670, +429, +444, +196670, +445, +446, +262205, +14, +447, +429, +327850, +9, +448, +447, +224, +196855, +450, +0, +262394, +448, +449, +455, +131320, +449, +327745, +452, +453, +92, +451, +262205, +6, +454, +453, +196670, +445, +454, +131321, +450, +131320, +455, +262205, +14, +456, +429, +327850, +9, +457, +456, +81, +196855, +459, +0, +262394, +457, +458, +463, +131320, +458, +327745, +452, +461, +92, +460, +262205, +6, +462, +461, +196670, +445, +462, +131321, +459, +131320, +463, +262205, +14, +464, +429, +327850, +9, +465, +464, +111, +196855, +467, +0, +262394, +465, +466, +471, +131320, +466, +327745, +452, +469, +92, +468, +262205, +6, +470, +469, +196670, +445, +470, +131321, +467, +131320, +471, +262205, +14, +472, +429, +327850, +9, +473, +472, +130, +196855, +475, +0, +262394, +473, +474, +475, +131320, +474, +327745, +452, +477, +92, +476, +262205, +6, +478, +477, +196670, +445, +478, +131321, +475, +131320, +475, +131321, +467, +131320, +467, +131321, +459, +131320, +459, +131321, +450, +131320, +450, +262205, +6, +479, +445, +458764, +6, +481, +1, +37, +479, +480, +327813, +6, +482, +339, +481, +196670, +445, +482, +196670, +483, +484, +196670, +485, +484, +131321, +486, +131320, +486, +262390, +488, +489, +0, +131321, +490, +131320, +490, +262205, +16, +491, +485, +262268, +14, +492, +491, +262205, +14, +493, +427, +327856, +9, +494, +492, +493, +262394, +494, +487, +488, +131320, +487, +262205, +16, +495, +428, +262205, +16, +496, +485, +327808, +16, +497, +495, +496, +196670, +483, +497, +262205, +16, +502, +485, +262205, +16, +507, +483, +393281, +508, +509, +506, +484, +507, +262205, +7, +510, +509, +327745, +8, +511, +501, +502, +196670, +511, +510, +131321, +489, +131320, +489, +262205, +16, +512, +485, +327808, +16, +514, +512, +513, +196670, +485, +514, +131321, +486, +131320, +488, +196670, +515, +484, +131321, +516, +131320, +516, +262390, +518, +519, +0, +131321, +520, +131320, +520, +262205, +16, +521, +515, +327745, +523, +524, +92, +522, +262205, +16, +525, +524, +327857, +9, +526, +521, +525, +262394, +526, +517, +518, +131320, +517, +327745, +8, +528, +501, +513, +262205, +7, +529, +528, +196670, +527, +529, +262205, +532, +535, +534, +262205, +16, +536, +428, +327775, +7, +537, +535, +536, +196670, +530, +537, +196670, +538, +513, +131321, +539, +131320, +539, +262390, +541, +542, +0, +131321, +543, +131320, +543, +262205, +16, +544, +538, +262268, +14, +545, +544, +262205, +14, +546, +427, +327810, +14, +547, +546, +111, +327856, +9, +548, +545, +547, +262394, +548, +540, +541, +131320, +540, +262205, +16, +549, +428, +262205, +16, +550, +538, +327808, +16, +551, +549, +550, +196670, +483, +551, +262205, +16, +553, +538, +327808, +16, +554, +553, +513, +327745, +8, +555, +501, +554, +262205, +7, +556, +555, +196670, +552, +556, +327745, +508, +564, +562, +513, +262205, +7, +565, +564, +196670, +563, +565, +262205, +7, +567, +530, +196670, +566, +567, +393273, +7, +568, +62, +563, +566, +196670, +557, +568, +262205, +532, +571, +570, +262205, +16, +572, +483, +327808, +16, +573, +572, +513, +327775, +7, +574, +571, +573, +524367, +64, +575, +574, +574, +0, +1, +2, +196670, +569, +575, +262205, +7, +578, +557, +196670, +577, +578, +262205, +64, +580, +569, +196670, +579, +580, +393273, +64, +581, +69, +577, +579, +262205, +7, +582, +527, +524367, +64, +583, +582, +582, +0, +1, +2, +327809, +64, +584, +581, +583, +196670, +576, +584, +262205, +6, +586, +445, +262205, +64, +587, +576, +262205, +7, +588, +552, +524367, +64, +589, +588, +588, +0, +1, +2, +327811, +64, +590, +587, +589, +327822, +64, +591, +590, +586, +196670, +585, +591, +262205, +7, +593, +527, +196670, +592, +593, +327737, +9, +594, +12, +592, +196855, +596, +0, +262394, +594, +595, +596, +131320, +595, +262205, +64, +597, +585, +262205, +7, +598, +527, +524367, +64, +599, +598, +598, +0, +1, +2, +327811, +64, +600, +599, +597, +262205, +7, +601, +527, +589903, +7, +602, +601, +600, +4, +5, +6, +3, +196670, +527, +602, +131321, +596, +131320, +596, +262205, +7, +604, +552, +196670, +603, +604, +327737, +9, +605, +12, +603, +196855, +607, +0, +262394, +605, +606, +607, +131320, +606, +262205, +64, +608, +585, +262205, +7, +609, +552, +524367, +64, +610, +609, +609, +0, +1, +2, +327809, +64, +611, +610, +608, +262205, +7, +612, +552, +589903, +7, +613, +612, +611, +4, +5, +6, +3, +196670, +552, +613, +131321, +607, +131320, +607, +262205, +7, +616, +557, +196670, +615, +616, +327737, +7, +617, +79, +615, +196670, +614, +617, +262205, +7, +619, +552, +524367, +64, +620, +619, +619, +0, +1, +2, +262205, +7, +621, +527, +524367, +64, +622, +621, +621, +0, +1, +2, +327811, +64, +623, +620, +622, +393228, +64, +624, +1, +69, +623, +196670, +618, +624, +262205, +7, +627, +614, +196670, +626, +627, +262205, +64, +629, +618, +196670, +628, +629, +393273, +64, +630, +69, +626, +628, +393228, +64, +631, +1, +69, +630, +196670, +625, +631, +196670, +632, +633, +262205, +64, +635, +632, +262205, +64, +636, +625, +458764, +64, +637, +1, +68, +635, +636, +196670, +634, +637, +262205, +64, +638, +634, +393228, +6, +639, +1, +66, +638, +327866, +9, +640, +639, +382, +196855, +642, +0, +262394, +640, +641, +642, +131320, +641, +262205, +64, +644, +632, +262205, +64, +645, +625, +327828, +6, +646, +644, +645, +393228, +6, +647, +1, +17, +646, +196670, +643, +647, +262205, +64, +648, +634, +393228, +64, +649, +1, +69, +648, +196670, +634, +649, +262205, +6, +652, +643, +196670, +651, +652, +262205, +64, +654, +634, +196670, +653, +654, +393273, +7, +655, +75, +651, +653, +196670, +650, +655, +262205, +7, +657, +530, +196670, +656, +657, +262205, +7, +659, +650, +196670, +658, +659, +393273, +7, +660, +62, +656, +658, +196670, +530, +660, +131321, +642, +131320, +642, +262205, +16, +661, +538, +262205, +7, +662, +527, +524367, +64, +663, +662, +662, +0, +1, +2, +327745, +8, +664, +501, +661, +262205, +7, +665, +664, +589903, +7, +666, +665, +663, +4, +5, +6, +3, +196670, +664, +666, +262205, +16, +667, +538, +327808, +16, +668, +667, +513, +262205, +7, +669, +552, +524367, +64, +670, +669, +669, +0, +1, +2, +327745, +8, +671, +501, +668, +262205, +7, +672, +671, +589903, +7, +673, +672, +670, +4, +5, +6, +3, +196670, +671, +673, +262205, +7, +674, +552, +196670, +527, +674, +131321, +542, +131320, +542, +262205, +16, +675, +538, +327808, +16, +676, +675, +513, +196670, +538, +676, +131321, +539, +131320, +541, +131321, +519, +131320, +519, +262205, +16, +677, +515, +327808, +16, +678, +677, +513, +196670, +515, +678, +131321, +516, +131320, +518, +196670, +679, +484, +131321, +680, +131320, +680, +262390, +682, +683, +0, +131321, +684, +131320, +684, +262205, +16, +685, +679, +262268, +14, +686, +685, +262205, +14, +687, +427, +327856, +9, +688, +686, +687, +262394, +688, +681, +682, +131320, +681, +262205, +16, +689, +428, +262205, +16, +690, +679, +327808, +16, +691, +689, +690, +196670, +483, +691, +262205, +16, +692, +483, +262205, +16, +693, +679, +327745, +8, +694, +501, +693, +262205, +7, +695, +694, +393281, +508, +696, +506, +484, +692, +196670, +696, +695, +131321, +683, +131320, +683, +262205, +16, +697, +679, +327808, +16, +698, +697, +513, +196670, +679, +698, +131321, +680, +131320, +682, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +327745, +71, +82, +11, +81, +262205, +6, +83, +82, +327866, +9, +85, +83, +84, +131326, +85, +65592, +327734, +2, +28, +0, +18, +196663, +15, +19, +196663, +15, +20, +196663, +15, +21, +196663, +15, +22, +196663, +17, +23, +196663, +15, +24, +196663, +15, +25, +196663, +15, +26, +196663, +15, +27, +131320, +29, +262205, +14, +88, +19, +196670, +26, +88, +327745, +94, +95, +92, +93, +262205, +14, +96, +95, +327814, +14, +97, +89, +96, +196670, +25, +97, +262205, +14, +98, +19, +327745, +94, +99, +92, +93, +262205, +14, +100, +99, +327817, +14, +101, +98, +100, +196670, +22, +101, +262205, +14, +102, +20, +327745, +94, +103, +92, +93, +262205, +14, +104, +103, +327812, +14, +105, +102, +104, +262205, +14, +106, +22, +327808, +14, +107, +105, +106, +196670, +21, +107, +327745, +94, +109, +92, +108, +262205, +14, +110, +109, +327808, +14, +112, +110, +111, +262205, +14, +113, +21, +327812, +14, +114, +113, +112, +196670, +21, +114, +262205, +14, +115, +19, +262205, +14, +116, +22, +327810, +14, +117, +115, +116, +327745, +94, +118, +92, +93, +262205, +14, +119, +118, +327814, +14, +120, +117, +119, +196670, +24, +120, +262205, +122, +125, +124, +262205, +14, +126, +21, +262268, +16, +127, +126, +327775, +128, +129, +125, +127, +327761, +14, +131, +129, +0, +196670, +27, +131, +262205, +14, +132, +21, +262205, +14, +133, +25, +327812, +14, +134, +132, +133, +262205, +14, +135, +24, +327808, +14, +136, +134, +135, +262268, +16, +137, +136, +196670, +23, +137, +65789, +65592, +327734, +2, +39, +0, +18, +196663, +15, +30, +196663, +15, +31, +196663, +15, +32, +196663, +15, +33, +196663, +17, +34, +196663, +15, +35, +196663, +15, +36, +196663, +15, +37, +196663, +15, +38, +131320, +40, +262205, +14, +138, +30, +196670, +37, +138, +327745, +94, +139, +92, +93, +262205, +14, +140, +139, +327814, +14, +141, +89, +140, +196670, +36, +141, +262205, +14, +142, +30, +327745, +94, +143, +92, +93, +262205, +14, +144, +143, +327817, +14, +145, +142, +144, +196670, +33, +145, +262205, +14, +146, +31, +327745, +94, +147, +92, +93, +262205, +14, +148, +147, +327812, +14, +149, +146, +148, +262205, +14, +150, +33, +327808, +14, +151, +149, +150, +196670, +32, +151, +262205, +14, +152, +30, +262205, +14, +153, +33, +327810, +14, +154, +152, +153, +327745, +94, +155, +92, +93, +262205, +14, +156, +155, +327814, +14, +157, +154, +156, +196670, +35, +157, +262205, +122, +158, +124, +262205, +14, +159, +32, +262268, +16, +160, +159, +327775, +128, +161, +158, +160, +327761, +14, +162, +161, +0, +196670, +38, +162, +262205, +14, +163, +32, +262205, +14, +164, +36, +327812, +14, +165, +163, +164, +262205, +14, +166, +35, +327808, +14, +167, +165, +166, +262268, +16, +168, +167, +196670, +34, +168, +65789, +65592, +327734, +2, +48, +0, +41, +196663, +15, +42, +196663, +15, +43, +196663, +15, +44, +196663, +15, +45, +196663, +15, +46, +196663, +15, +47, +131320, +49, +262205, +14, +169, +43, +327812, +14, +170, +89, +169, +262205, +14, +171, +42, +327808, +14, +172, +170, +171, +196670, +44, +172, +327745, +94, +173, +92, +93, +262205, +14, +174, +173, +327814, +14, +175, +89, +174, +196670, +45, +175, +262205, +122, +176, +124, +262205, +14, +177, +44, +262268, +16, +178, +177, +327775, +128, +179, +176, +178, +327761, +14, +180, +179, +0, +196670, +47, +180, +262205, +14, +181, +44, +262205, +14, +182, +45, +327812, +14, +183, +181, +182, +196670, +46, +183, +65789, +65592, +327734, +2, +57, +0, +50, +196663, +17, +51, +196663, +17, +52, +196663, +17, +53, +196663, +15, +54, +196663, +17, +55, +196663, +15, +56, +131320, +58, +262205, +16, +185, +52, +327812, +16, +186, +184, +185, +262205, +16, +187, +51, +327808, +16, +188, +186, +187, +196670, +53, +188, +327745, +94, +189, +92, +108, +262205, +14, +190, +189, +327808, +14, +191, +190, +111, +262268, +16, +192, +191, +262205, +16, +193, +53, +327812, +16, +194, +193, +192, +196670, +53, +194, +327745, +94, +195, +92, +93, +262205, +14, +196, +195, +327814, +14, +197, +89, +196, +196670, +54, +197, +262205, +122, +198, +124, +262205, +16, +199, +53, +327775, +128, +200, +198, +199, +327761, +14, +201, +200, +0, +196670, +56, +201, +262205, +16, +202, +53, +262205, +14, +203, +54, +262268, +16, +204, +203, +327812, +16, +205, +202, +204, +196670, +55, +205, +65789, +65592, +327734, +7, +62, +0, +59, +196663, +8, +60, +196663, +8, +61, +131320, +63, +262203, +8, +206, +7, +327745, +71, +207, +60, +81, +262205, +6, +208, +207, +327745, +71, +209, +61, +81, +262205, +6, +210, +209, +327813, +6, +211, +208, +210, +327745, +71, +212, +60, +130, +262205, +6, +213, +212, +327745, +71, +214, +61, +130, +262205, +6, +215, +214, +327813, +6, +216, +213, +215, +327811, +6, +217, +211, +216, +327745, +71, +218, +60, +111, +262205, +6, +219, +218, +327745, +71, +220, +61, +111, +262205, +6, +221, +220, +327813, +6, +222, +219, +221, +327811, +6, +223, +217, +222, +327745, +71, +225, +60, +224, +262205, +6, +226, +225, +327745, +71, +227, +61, +224, +262205, +6, +228, +227, +327813, +6, +229, +226, +228, +327811, +6, +230, +223, +229, +327745, +71, +231, +206, +81, +196670, +231, +230, +327745, +71, +232, +60, +81, +262205, +6, +233, +232, +327745, +71, +234, +61, +130, +262205, +6, +235, +234, +327813, +6, +236, +233, +235, +327745, +71, +237, +60, +130, +262205, +6, +238, +237, +327745, +71, +239, +61, +81, +262205, +6, +240, +239, +327813, +6, +241, +238, +240, +327809, +6, +242, +236, +241, +327745, +71, +243, +60, +111, +262205, +6, +244, +243, +327745, +71, +245, +61, +224, +262205, +6, +246, +245, +327813, +6, +247, +244, +246, +327809, +6, +248, +242, +247, +327745, +71, +249, +60, +224, +262205, +6, +250, +249, +327745, +71, +251, +61, +111, +262205, +6, +252, +251, +327813, +6, +253, +250, +252, +327811, +6, +254, +248, +253, +327745, +71, +255, +206, +130, +196670, +255, +254, +327745, +71, +256, +60, +81, +262205, +6, +257, +256, +327745, +71, +258, +61, +111, +262205, +6, +259, +258, +327813, +6, +260, +257, +259, +327745, +71, +261, +60, +111, +262205, +6, +262, +261, +327745, +71, +263, +61, +81, +262205, +6, +264, +263, +327813, +6, +265, +262, +264, +327809, +6, +266, +260, +265, +327745, +71, +267, +60, +224, +262205, +6, +268, +267, +327745, +71, +269, +61, +130, +262205, +6, +270, +269, +327813, +6, +271, +268, +270, +327809, +6, +272, +266, +271, +327745, +71, +273, +60, +130, +262205, +6, +274, +273, +327745, +71, +275, +61, +224, +262205, +6, +276, +275, +327813, +6, +277, +274, +276, +327811, +6, +278, +272, +277, +327745, +71, +279, +206, +111, +196670, +279, +278, +327745, +71, +280, +60, +81, +262205, +6, +281, +280, +327745, +71, +282, +61, +224, +262205, +6, +283, +282, +327813, +6, +284, +281, +283, +327745, +71, +285, +60, +224, +262205, +6, +286, +285, +327745, +71, +287, +61, +81, +262205, +6, +288, +287, +327813, +6, +289, +286, +288, +327809, +6, +290, +284, +289, +327745, +71, +291, +60, +130, +262205, +6, +292, +291, +327745, +71, +293, +61, +111, +262205, +6, +294, +293, +327813, +6, +295, +292, +294, +327809, +6, +296, +290, +295, +327745, +71, +297, +60, +111, +262205, +6, +298, +297, +327745, +71, +299, +61, +130, +262205, +6, +300, +299, +327813, +6, +301, +298, +300, +327811, +6, +302, +296, +301, +327745, +71, +303, +206, +224, +196670, +303, +302, +262205, +7, +304, +206, +131326, +304, +65592, +327734, +64, +69, +0, +66, +196663, +8, +67, +196663, +65, +68, +131320, +70, +262203, +65, +307, +7, +262203, +65, +315, +7, +262203, +65, +319, +7, +327745, +71, +308, +67, +130, +262205, +6, +309, +308, +327745, +71, +310, +67, +111, +262205, +6, +311, +310, +327745, +71, +312, +67, +224, +262205, +6, +313, +312, +393296, +64, +314, +309, +311, +313, +196670, +307, +314, +262205, +64, +316, +307, +262205, +64, +317, +68, +458764, +64, +318, +1, +68, +316, +317, +196670, +315, +318, +262205, +64, +320, +307, +262205, +64, +321, +315, +458764, +64, +322, +1, +68, +320, +321, +196670, +319, +322, +327745, +71, +324, +67, +81, +262205, +6, +325, +324, +327813, +6, +326, +323, +325, +262205, +64, +327, +315, +327822, +64, +328, +327, +326, +196670, +315, +328, +262205, +64, +329, +319, +327822, +64, +330, +329, +323, +196670, +319, +330, +262205, +64, +331, +68, +262205, +64, +332, +315, +327809, +64, +333, +331, +332, +262205, +64, +334, +319, +327809, +64, +335, +333, +334, +131326, +335, +65592, +327734, +7, +75, +0, +72, +196663, +71, +73, +196663, +65, +74, +131320, +76, +262203, +71, +338, +7, +262203, +71, +342, +7, +262203, +8, +345, +7, +262205, +6, +340, +73, +327813, +6, +341, +339, +340, +196670, +338, +341, +262205, +6, +343, +338, +393228, +6, +344, +1, +13, +343, +196670, +342, +344, +262205, +6, +346, +338, +393228, +6, +347, +1, +14, +346, +327745, +71, +348, +345, +81, +196670, +348, +347, +262205, +6, +349, +342, +262205, +64, +350, +74, +327822, +64, +351, +350, +349, +262205, +7, +352, +345, +589903, +7, +353, +352, +351, +4, +5, +6, +3, +196670, +345, +353, +262205, +7, +354, +345, +131326, +354, +65592, +327734, +7, +79, +0, +77, +196663, +8, +78, +131320, +80, +262203, +71, +357, +7, +327745, +71, +358, +78, +130, +262205, +6, +359, +358, +327745, +71, +360, +78, +130, +262205, +6, +361, +360, +327813, +6, +362, +359, +361, +327745, +71, +363, +78, +111, +262205, +6, +364, +363, +327745, +71, +365, +78, +111, +262205, +6, +366, +365, +327813, +6, +367, +364, +366, +327809, +6, +368, +362, +367, +327745, +71, +369, +78, +224, +262205, +6, +370, +369, +327745, +71, +371, +78, +224, +262205, +6, +372, +371, +327813, +6, +373, +370, +372, +327809, +6, +374, +368, +373, +327745, +71, +375, +78, +81, +262205, +6, +376, +375, +327745, +71, +377, +78, +81, +262205, +6, +378, +377, +327813, +6, +379, +376, +378, +327809, +6, +380, +374, +379, +196670, +357, +380, +262205, +6, +381, +357, +327864, +9, +383, +381, +382, +196855, +385, +0, +262394, +383, +384, +385, +131320, +384, +131326, +387, +131320, +385, +327745, +71, +389, +78, +130, +262205, +6, +390, +389, +262271, +6, +391, +390, +262205, +6, +392, +357, +327816, +6, +393, +391, +392, +327745, +71, +394, +78, +130, +196670, +394, +393, +327745, +71, +395, +78, +111, +262205, +6, +396, +395, +262271, +6, +397, +396, +262205, +6, +398, +357, +327816, +6, +399, +397, +398, +327745, +71, +400, +78, +111, +196670, +400, +399, +327745, +71, +401, +78, +224, +262205, +6, +402, +401, +262271, +6, +403, +402, +262205, +6, +404, +357, +327816, +6, +405, +403, +404, +327745, +71, +406, +78, +224, +196670, +406, +405, +327745, +71, +407, +78, +81, +262205, +6, +408, +407, +262205, +6, +409, +357, +327816, +6, +410, +408, +409, +327745, +71, +411, +78, +81, +196670, +411, +410, +262205, +7, +412, +78, +131326, +412, +65592, +}; +const std::vector length_wind_collision = {119734787, +65536, +524289, +582, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +5, +4, +1852399981, +0, +279, +280, +393232, +4, +17, +64, +1, +1, +196611, +2, +450, +262149, +4, +1852399981, +0, +393221, +12, +1867346761, +1818386806, +1719019621, +15156, +327685, +11, +1953653104, +1701602153, +0, +1114117, +28, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1953718605, +1965584997, +829766449, +993097019, +1765486965, +829766449, +993097019, +1966813557, +15153, +327685, +19, +1633906540, +1684627308, +0, +327685, +20, +1970238055, +1684627312, +0, +458757, +21, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +22, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +23, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +24, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +25, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +26, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +27, +1634890867, +2035573870, +25968, +1114117, +39, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +828980017, +993097019, +1966813557, +829766449, +59, +327685, +30, +1633906540, +1684627308, +0, +327685, +31, +1970238055, +1684627312, +0, +458757, +32, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +33, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +34, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +35, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +36, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +37, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +38, +1634890867, +2035573870, +25968, +983045, +48, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +829766449, +993097019, +0, +327685, +42, +1633906540, +1684627308, +0, +327685, +43, +1970238055, +1684627312, +0, +458757, +44, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +45, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +46, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +47, +1634890867, +2035573870, +25968, +983045, +57, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1953718605, +1764258405, +828980017, +993093947, +1765486965, +829766449, +59, +327685, +51, +1633906540, +1684627308, +0, +327685, +52, +1970238055, +1684627312, +0, +458757, +53, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +54, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +55, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +56, +1634890867, +2035573870, +25968, +655365, +63, +1936617283, +1767993972, +1968010350, +1885959276, +1919248748, +879130152, +879130171, +59, +327685, +61, +1953653104, +1701602153, +48, +327685, +62, +1953653104, +1701602153, +49, +786437, +71, +1819308097, +1936278649, +1668178292, +1852785509, +1634890867, +678719081, +993289846, +993289846, +1715155302, +15153, +262149, +67, +812871536, +0, +262149, +68, +829648752, +0, +393221, +69, +1735549300, +1766093925, +1851880563, +25955, +327685, +70, +1718187123, +1936027238, +115, +327685, +82, +1936617283, +1953390964, +115, +327686, +82, +0, +1767333735, +25710, +327686, +82, +1, +1767333735, +3236974, +327686, +82, +2, +1767333735, +3302510, +327686, +82, +3, +1767333735, +3368046, +720902, +82, +4, +1968070503, +1852132461, +1130919015, +1953721967, +1852399986, +1702119796, +1769234802, +7564911, +458758, +82, +5, +1130520423, +1768713327, +1852795251, +0, +524294, +82, +6, +1917280103, +1953068641, +1734430073, +1970563438, +25956, +393222, +82, +7, +1767137127, +1951622509, +28773, +393222, +82, +8, +1631870823, +1852403821, +12391, +786438, +82, +9, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +48, +786438, +82, +10, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12391, +851974, +82, +11, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +811951982, +0, +393222, +82, +12, +1631870823, +1852403821, +12647, +786438, +82, +13, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +49, +786438, +82, +14, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12647, +851974, +82, +15, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +828729198, +0, +393222, +82, +16, +1631870823, +1852403821, +12903, +786438, +82, +17, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +50, +786438, +82, +18, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12903, +851974, +82, +19, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +845506414, +0, +393222, +82, +20, +1631870823, +1852403821, +13159, +786438, +82, +21, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +51, +786438, +82, +22, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +13159, +851974, +82, +23, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +862283630, +0, +720902, +82, +24, +1968070503, +1399213933, +1851880052, +1699771236, +1919439986, +1197760869, +1886744434, +0, +720902, +82, +25, +1968070503, +1819231853, +1215786860, +1936877921, +1198679376, +1701079413, +1919508808, +0, +589830, +82, +26, +1767137127, +1885688688, +1952543329, +1181642601, +1869898593, +114, +327686, +82, +27, +1466064743, +7369313, +786438, +82, +28, +1968070503, +1668238445, +1750297697, +1298493537, +1751348321, +1231515241, +1634887028, +1852795252, +115, +196613, +84, +0, +458757, +116, +1632132967, +1951625833, +1684955506, +1701869908, +0, +262149, +198, +1634886000, +109, +262149, +203, +1634886000, +109, +262149, +216, +1634886000, +109, +262149, +229, +1953260900, +97, +327685, +235, +1953720676, +1701015137, +0, +327685, +240, +1701999731, +1768448884, +26478, +327685, +249, +1953265005, +1768714345, +29285, +262149, +250, +1634886000, +109, +262149, +252, +1634886000, +109, +524293, +279, +1281322087, +1818321775, +1870032457, +1769234787, +1145663087, +0, +393221, +280, +1465871463, +1198223983, +1886744434, +17481, +458757, +281, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +282, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +283, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +284, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +285, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +286, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +287, +1634890867, +2035573870, +25968, +262149, +288, +1634886000, +109, +262149, +292, +1634886000, +109, +262149, +295, +1634886000, +109, +262149, +297, +1634886000, +109, +262149, +299, +1634886000, +109, +262149, +301, +1634886000, +109, +262149, +303, +1634886000, +109, +262149, +305, +1634886000, +109, +262149, +307, +1634886000, +109, +589829, +317, +1332573550, +1920226150, +1935961697, +1416783184, +1634038376, +1869760356, +28789, +327685, +322, +1918986355, +1867539557, +115, +458757, +325, +1953067639, +1818386789, +1936674917, +1869182057, +29550, +589830, +325, +0, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +196613, +327, +0, +393221, +337, +1918986355, +1699505253, +1752459118, +0, +458757, +342, +1632132967, +1699902057, +1699509363, +1752459118, +5657171, +262149, +371, +1668444006, +101, +262149, +373, +1835102822, +101, +196613, +387, +97, +196613, +394, +119, +327685, +423, +1918986355, +1850303589, +7890276, +196613, +432, +118, +262149, +445, +1668444006, +101, +196613, +468, +97, +196613, +475, +98, +327685, +482, +1919251561, +1869182049, +17774, +327685, +494, +1918986355, +1850303589, +7890276, +262149, +516, +1634886000, +109, +262149, +519, +1634886000, +109, +262149, +522, +1634886000, +109, +262149, +525, +1634886000, +109, +262149, +550, +1634886000, +109, +262149, +553, +1634886000, +109, +262149, +556, +1634886000, +109, +262149, +559, +1634886000, +109, +393221, +568, +1819231074, +1702126916, +1684370531, +0, +393221, +578, +1684104520, +1851880020, +1919903347, +109, +589830, +578, +0, +1867341671, +1416389988, +1936613746, +1836216166, +1215459142, +6578533, +589830, +578, +1, +1867341671, +1382835556, +1952543855, +1919895141, +1684104520, +0, +589830, +578, +2, +1852396386, +1214606439, +1415864677, +1936613746, +1836216166, +0, +327686, +578, +3, +1684300144, +6778473, +196613, +580, +0, +327752, +82, +0, +35, +0, +327752, +82, +1, +35, +16, +327752, +82, +2, +35, +32, +327752, +82, +3, +35, +48, +327752, +82, +4, +35, +64, +327752, +82, +5, +35, +68, +327752, +82, +6, +35, +72, +327752, +82, +7, +35, +76, +327752, +82, +8, +35, +80, +327752, +82, +9, +35, +84, +327752, +82, +10, +35, +88, +327752, +82, +11, +35, +92, +327752, +82, +12, +35, +96, +327752, +82, +13, +35, +100, +327752, +82, +14, +35, +104, +327752, +82, +15, +35, +108, +327752, +82, +16, +35, +112, +327752, +82, +17, +35, +116, +327752, +82, +18, +35, +120, +327752, +82, +19, +35, +124, +327752, +82, +20, +35, +128, +327752, +82, +21, +35, +132, +327752, +82, +22, +35, +136, +327752, +82, +23, +35, +140, +327752, +82, +24, +35, +144, +327752, +82, +25, +35, +148, +327752, +82, +26, +35, +152, +327752, +82, +27, +35, +156, +327752, +82, +28, +35, +160, +196679, +82, +3, +262215, +84, +34, +0, +262215, +84, +33, +16, +262215, +116, +34, +1, +262215, +116, +33, +22, +262215, +279, +11, +27, +262215, +280, +11, +26, +262215, +324, +6, +16, +327752, +325, +0, +35, +0, +196679, +325, +3, +262215, +327, +34, +1, +262215, +327, +33, +7, +262215, +342, +34, +1, +262215, +342, +33, +26, +262215, +577, +6, +16, +262216, +578, +0, +5, +327752, +578, +0, +35, +0, +327752, +578, +0, +7, +16, +327752, +578, +1, +35, +64, +327752, +578, +2, +35, +80, +327752, +578, +3, +35, +96, +196679, +578, +3, +262215, +580, +34, +0, +262215, +580, +33, +27, +262215, +581, +11, +25, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +131092, +9, +262177, +10, +9, +8, +262165, +14, +32, +0, +262176, +15, +7, +14, +262165, +16, +32, +1, +262176, +17, +7, +16, +786465, +18, +2, +15, +15, +15, +15, +17, +15, +15, +15, +15, +589857, +41, +2, +15, +15, +15, +15, +15, +15, +589857, +50, +2, +17, +17, +17, +15, +17, +15, +262167, +59, +6, +2, +327713, +60, +59, +8, +8, +262176, +65, +7, +6, +458785, +66, +2, +8, +8, +65, +65, +262187, +14, +73, +3, +262187, +6, +76, +0, +262187, +14, +81, +64, +2031646, +82, +7, +7, +7, +7, +16, +16, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +14, +14, +6, +16, +16, +262176, +83, +2, +82, +262203, +83, +84, +2, +262187, +16, +85, +24, +262176, +86, +2, +14, +262187, +16, +100, +25, +262187, +14, +103, +1, +589849, +113, +14, +5, +0, +0, +0, +1, +0, +196635, +114, +113, +262176, +115, +0, +114, +262203, +115, +116, +0, +262167, +120, +14, +4, +262187, +14, +122, +0, +262187, +16, +176, +64, +262187, +6, +208, +1056964608, +327724, +59, +209, +208, +208, +262187, +6, +212, +1065353216, +327724, +59, +213, +212, +76, +327724, +59, +221, +76, +212, +327724, +59, +224, +76, +76, +262167, +227, +6, +3, +262176, +228, +7, +227, +262187, +6, +238, +869711765, +262176, +248, +7, +59, +262167, +277, +14, +3, +262176, +278, +1, +277, +262203, +278, +279, +1, +262203, +278, +280, +1, +262176, +289, +1, +14, +262172, +320, +7, +81, +262176, +321, +4, +320, +262203, +321, +322, +4, +196637, +324, +7, +196638, +325, +324, +262176, +326, +2, +325, +262203, +326, +327, +2, +262187, +16, +328, +0, +262176, +330, +2, +7, +262176, +333, +4, +7, +262172, +335, +6, +81, +262176, +336, +4, +335, +262203, +336, +337, +4, +589849, +339, +6, +5, +0, +0, +0, +1, +0, +196635, +340, +339, +262176, +341, +0, +340, +262203, +341, +342, +0, +262176, +347, +4, +6, +262187, +14, +349, +4062, +262176, +350, +2, +6, +262187, +14, +364, +2, +458796, +7, +372, +76, +76, +76, +76, +262187, +14, +389, +20, +262187, +6, +392, +1101004800, +262187, +16, +402, +1, +262187, +16, +409, +2, +262187, +16, +417, +3, +262187, +16, +454, +7, +262187, +6, +471, +1073741824, +262187, +16, +489, +4, +262176, +490, +2, +16, +262176, +567, +7, +9, +196650, +9, +569, +262168, +576, +7, +4, +262172, +577, +6, +73, +393246, +578, +576, +7, +16, +577, +262176, +579, +2, +578, +262203, +579, +580, +2, +393260, +277, +581, +81, +103, +103, +327734, +2, +4, +0, +3, +131320, +5, +262203, +15, +281, +7, +262203, +15, +282, +7, +262203, +17, +283, +7, +262203, +15, +284, +7, +262203, +15, +285, +7, +262203, +15, +286, +7, +262203, +15, +287, +7, +262203, +15, +288, +7, +262203, +15, +292, +7, +262203, +15, +295, +7, +262203, +15, +297, +7, +262203, +17, +299, +7, +262203, +15, +301, +7, +262203, +15, +303, +7, +262203, +15, +305, +7, +262203, +15, +307, +7, +262203, +15, +317, +7, +262203, +8, +371, +7, +262203, +65, +373, +7, +262203, +65, +387, +7, +262203, +228, +394, +7, +262203, +17, +423, +7, +262203, +228, +432, +7, +262203, +228, +445, +7, +262203, +17, +468, +7, +262203, +17, +475, +7, +262203, +17, +482, +7, +262203, +17, +494, +7, +262203, +8, +516, +7, +262203, +8, +519, +7, +262203, +65, +522, +7, +262203, +65, +525, +7, +262203, +8, +550, +7, +262203, +8, +553, +7, +262203, +65, +556, +7, +262203, +65, +559, +7, +262203, +567, +568, +7, +327745, +289, +290, +279, +122, +262205, +14, +291, +290, +196670, +288, +291, +327745, +289, +293, +280, +122, +262205, +14, +294, +293, +196670, +292, +294, +262205, +14, +296, +281, +196670, +295, +296, +262205, +14, +298, +282, +196670, +297, +298, +262205, +16, +300, +283, +196670, +299, +300, +262205, +14, +302, +284, +196670, +301, +302, +262205, +14, +304, +285, +196670, +303, +304, +262205, +14, +306, +286, +196670, +305, +306, +262205, +14, +308, +287, +196670, +307, +308, +852025, +2, +309, +28, +288, +292, +295, +297, +299, +301, +303, +305, +307, +262205, +14, +310, +295, +196670, +281, +310, +262205, +14, +311, +297, +196670, +282, +311, +262205, +16, +312, +299, +196670, +283, +312, +262205, +14, +313, +301, +196670, +284, +313, +262205, +14, +314, +303, +196670, +285, +314, +262205, +14, +315, +305, +196670, +286, +315, +262205, +14, +316, +307, +196670, +287, +316, +327745, +86, +318, +84, +85, +262205, +14, +319, +318, +196670, +317, +319, +262205, +14, +323, +286, +262205, +16, +329, +283, +393281, +330, +331, +327, +328, +329, +262205, +7, +332, +331, +327745, +333, +334, +322, +323, +196670, +334, +332, +262205, +14, +338, +286, +262205, +340, +343, +342, +262205, +16, +344, +283, +327775, +7, +345, +343, +344, +327761, +6, +346, +345, +0, +327745, +347, +348, +337, +338, +196670, +348, +346, +196833, +103, +349, +262368, +103, +103, +122, +393281, +350, +351, +84, +328, +122, +262205, +6, +352, +351, +327862, +9, +353, +352, +76, +262312, +9, +354, +353, +196855, +356, +0, +262394, +354, +355, +356, +131320, +355, +393281, +350, +357, +84, +328, +103, +262205, +6, +358, +357, +327862, +9, +359, +358, +76, +131321, +356, +131320, +356, +458997, +9, +360, +353, +5, +359, +355, +262312, +9, +361, +360, +196855, +363, +0, +262394, +361, +362, +363, +131320, +362, +393281, +350, +365, +84, +328, +364, +262205, +6, +366, +365, +327862, +9, +367, +366, +76, +131321, +363, +131320, +363, +458997, +9, +368, +360, +356, +367, +362, +196855, +370, +0, +262394, +368, +369, +370, +131320, +369, +196670, +371, +372, +393281, +350, +374, +84, +328, +73, +262205, +6, +375, +374, +196670, +373, +375, +262205, +14, +376, +284, +327854, +9, +377, +376, +364, +196855, +379, +0, +262394, +377, +378, +379, +131320, +378, +262205, +14, +380, +284, +262205, +14, +381, +285, +327810, +14, +382, +381, +103, +327856, +9, +383, +380, +382, +131321, +379, +131320, +379, +458997, +9, +384, +377, +369, +383, +378, +196855, +386, +0, +262394, +384, +385, +386, +131320, +385, +262205, +14, +388, +281, +327817, +14, +390, +388, +389, +262256, +6, +391, +390, +327816, +6, +393, +391, +392, +196670, +387, +393, +262205, +6, +395, +387, +327745, +330, +396, +84, +328, +262205, +7, +397, +396, +524367, +227, +398, +397, +397, +0, +1, +2, +327822, +227, +399, +398, +395, +262205, +6, +400, +387, +327811, +6, +401, +212, +400, +327745, +330, +403, +84, +402, +262205, +7, +404, +403, +524367, +227, +405, +404, +404, +0, +1, +2, +327822, +227, +406, +405, +401, +327809, +227, +407, +399, +406, +262205, +6, +408, +387, +327745, +330, +410, +84, +409, +262205, +7, +411, +410, +524367, +227, +412, +411, +411, +0, +1, +2, +327822, +227, +413, +412, +408, +327809, +227, +414, +407, +413, +262205, +6, +415, +387, +327811, +6, +416, +212, +415, +327745, +330, +418, +84, +417, +262205, +7, +419, +418, +524367, +227, +420, +419, +419, +0, +1, +2, +327822, +227, +421, +420, +416, +327809, +227, +422, +414, +421, +196670, +394, +422, +262205, +14, +424, +284, +262268, +16, +425, +424, +262205, +14, +426, +317, +262268, +16, +427, +426, +327812, +16, +428, +425, +427, +262205, +14, +429, +282, +262268, +16, +430, +429, +327808, +16, +431, +428, +430, +196670, +423, +431, +262205, +16, +433, +423, +327745, +333, +434, +322, +433, +262205, +7, +435, +434, +524367, +227, +436, +435, +435, +0, +1, +2, +262205, +16, +437, +423, +262268, +14, +438, +437, +262205, +14, +439, +317, +327808, +14, +440, +438, +439, +327745, +333, +441, +322, +440, +262205, +7, +442, +441, +524367, +227, +443, +442, +442, +0, +1, +2, +327811, +227, +444, +436, +443, +196670, +432, +444, +262205, +227, +446, +432, +262205, +227, +447, +394, +458764, +227, +448, +1, +68, +446, +447, +262205, +227, +449, +432, +458764, +227, +450, +1, +68, +448, +449, +262271, +227, +451, +450, +196670, +445, +451, +262205, +16, +452, +423, +262205, +227, +453, +445, +327745, +350, +455, +84, +454, +262205, +6, +456, +455, +327822, +227, +457, +453, +456, +327745, +350, +458, +84, +454, +262205, +6, +459, +458, +327822, +227, +460, +457, +459, +327745, +333, +461, +322, +452, +262205, +7, +462, +461, +524367, +227, +463, +462, +462, +0, +1, +2, +327809, +227, +464, +463, +460, +327745, +333, +465, +322, +452, +262205, +7, +466, +465, +589903, +7, +467, +466, +464, +4, +5, +6, +3, +196670, +465, +467, +131321, +386, +131320, +386, +131321, +370, +131320, +370, +196833, +103, +349, +262368, +103, +103, +122, +262205, +14, +469, +285, +262256, +6, +470, +469, +327816, +6, +472, +470, +471, +393228, +6, +473, +1, +8, +472, +262254, +16, +474, +473, +196670, +468, +474, +262205, +14, +476, +285, +262256, +6, +477, +476, +327811, +6, +478, +477, +212, +327816, +6, +479, +478, +471, +393228, +6, +480, +1, +8, +479, +262254, +16, +481, +480, +196670, +475, +481, +196670, +482, +328, +131321, +483, +131320, +483, +262390, +485, +486, +0, +131321, +487, +131320, +487, +262205, +16, +488, +482, +327745, +490, +491, +84, +489, +262205, +16, +492, +491, +327857, +9, +493, +488, +492, +262394, +493, +484, +485, +131320, +484, +262205, +14, +495, +284, +262268, +16, +496, +495, +327812, +16, +497, +409, +496, +262205, +14, +498, +317, +262268, +16, +499, +498, +327812, +16, +500, +497, +499, +262205, +14, +501, +282, +262268, +16, +502, +501, +327808, +16, +503, +500, +502, +196670, +494, +503, +262205, +14, +504, +284, +262205, +16, +505, +468, +262268, +14, +506, +505, +327856, +9, +507, +504, +506, +196855, +509, +0, +262394, +507, +508, +509, +131320, +508, +262205, +16, +510, +494, +262205, +16, +511, +494, +262268, +14, +512, +511, +262205, +14, +513, +317, +327808, +14, +514, +512, +513, +262205, +16, +515, +494, +327745, +333, +517, +322, +510, +262205, +7, +518, +517, +196670, +516, +518, +327745, +333, +520, +322, +514, +262205, +7, +521, +520, +196670, +519, +521, +327745, +347, +523, +337, +515, +262205, +6, +524, +523, +196670, +522, +524, +196670, +525, +212, +524345, +2, +526, +71, +516, +519, +522, +525, +262205, +7, +527, +516, +327745, +333, +528, +322, +510, +196670, +528, +527, +262205, +7, +529, +519, +327745, +333, +530, +322, +514, +196670, +530, +529, +131321, +509, +131320, +509, +196833, +103, +349, +262368, +103, +103, +122, +262205, +14, +531, +284, +262205, +16, +532, +475, +262268, +14, +533, +532, +327856, +9, +534, +531, +533, +196855, +536, +0, +262394, +534, +535, +536, +131320, +535, +262205, +16, +537, +494, +262268, +14, +538, +537, +262205, +14, +539, +317, +327808, +14, +540, +538, +539, +262205, +16, +541, +494, +262268, +14, +542, +541, +262205, +14, +543, +317, +327812, +14, +544, +543, +364, +327808, +14, +545, +542, +544, +262205, +16, +546, +494, +262268, +14, +547, +546, +262205, +14, +548, +317, +327808, +14, +549, +547, +548, +327745, +333, +551, +322, +540, +262205, +7, +552, +551, +196670, +550, +552, +327745, +333, +554, +322, +545, +262205, +7, +555, +554, +196670, +553, +555, +327745, +347, +557, +337, +549, +262205, +6, +558, +557, +196670, +556, +558, +196670, +559, +212, +524345, +2, +560, +71, +550, +553, +556, +559, +262205, +7, +561, +550, +327745, +333, +562, +322, +540, +196670, +562, +561, +262205, +7, +563, +553, +327745, +333, +564, +322, +545, +196670, +564, +563, +131321, +536, +131320, +536, +196833, +103, +349, +262368, +103, +103, +122, +131321, +486, +131320, +486, +262205, +16, +565, +482, +327808, +16, +566, +565, +402, +196670, +482, +566, +131321, +483, +131320, +485, +196670, +568, +569, +262205, +16, +570, +283, +262205, +14, +571, +286, +327745, +333, +572, +322, +571, +262205, +7, +573, +572, +393281, +330, +574, +327, +328, +570, +196670, +574, +573, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +327745, +65, +74, +11, +73, +262205, +6, +75, +74, +327866, +9, +77, +75, +76, +131326, +77, +65592, +327734, +2, +28, +0, +18, +196663, +15, +19, +196663, +15, +20, +196663, +15, +21, +196663, +15, +22, +196663, +17, +23, +196663, +15, +24, +196663, +15, +25, +196663, +15, +26, +196663, +15, +27, +131320, +29, +262205, +14, +80, +19, +196670, +26, +80, +327745, +86, +87, +84, +85, +262205, +14, +88, +87, +327814, +14, +89, +81, +88, +196670, +25, +89, +262205, +14, +90, +19, +327745, +86, +91, +84, +85, +262205, +14, +92, +91, +327817, +14, +93, +90, +92, +196670, +22, +93, +262205, +14, +94, +20, +327745, +86, +95, +84, +85, +262205, +14, +96, +95, +327812, +14, +97, +94, +96, +262205, +14, +98, +22, +327808, +14, +99, +97, +98, +196670, +21, +99, +327745, +86, +101, +84, +100, +262205, +14, +102, +101, +327808, +14, +104, +102, +103, +262205, +14, +105, +21, +327812, +14, +106, +105, +104, +196670, +21, +106, +262205, +14, +107, +19, +262205, +14, +108, +22, +327810, +14, +109, +107, +108, +327745, +86, +110, +84, +85, +262205, +14, +111, +110, +327814, +14, +112, +109, +111, +196670, +24, +112, +262205, +114, +117, +116, +262205, +14, +118, +21, +262268, +16, +119, +118, +327775, +120, +121, +117, +119, +327761, +14, +123, +121, +0, +196670, +27, +123, +262205, +14, +124, +21, +262205, +14, +125, +25, +327812, +14, +126, +124, +125, +262205, +14, +127, +24, +327808, +14, +128, +126, +127, +262268, +16, +129, +128, +196670, +23, +129, +65789, +65592, +327734, +2, +39, +0, +18, +196663, +15, +30, +196663, +15, +31, +196663, +15, +32, +196663, +15, +33, +196663, +17, +34, +196663, +15, +35, +196663, +15, +36, +196663, +15, +37, +196663, +15, +38, +131320, +40, +262205, +14, +130, +30, +196670, +37, +130, +327745, +86, +131, +84, +85, +262205, +14, +132, +131, +327814, +14, +133, +81, +132, +196670, +36, +133, +262205, +14, +134, +30, +327745, +86, +135, +84, +85, +262205, +14, +136, +135, +327817, +14, +137, +134, +136, +196670, +33, +137, +262205, +14, +138, +31, +327745, +86, +139, +84, +85, +262205, +14, +140, +139, +327812, +14, +141, +138, +140, +262205, +14, +142, +33, +327808, +14, +143, +141, +142, +196670, +32, +143, +262205, +14, +144, +30, +262205, +14, +145, +33, +327810, +14, +146, +144, +145, +327745, +86, +147, +84, +85, +262205, +14, +148, +147, +327814, +14, +149, +146, +148, +196670, +35, +149, +262205, +114, +150, +116, +262205, +14, +151, +32, +262268, +16, +152, +151, +327775, +120, +153, +150, +152, +327761, +14, +154, +153, +0, +196670, +38, +154, +262205, +14, +155, +32, +262205, +14, +156, +36, +327812, +14, +157, +155, +156, +262205, +14, +158, +35, +327808, +14, +159, +157, +158, +262268, +16, +160, +159, +196670, +34, +160, +65789, +65592, +327734, +2, +48, +0, +41, +196663, +15, +42, +196663, +15, +43, +196663, +15, +44, +196663, +15, +45, +196663, +15, +46, +196663, +15, +47, +131320, +49, +262205, +14, +161, +43, +327812, +14, +162, +81, +161, +262205, +14, +163, +42, +327808, +14, +164, +162, +163, +196670, +44, +164, +327745, +86, +165, +84, +85, +262205, +14, +166, +165, +327814, +14, +167, +81, +166, +196670, +45, +167, +262205, +114, +168, +116, +262205, +14, +169, +44, +262268, +16, +170, +169, +327775, +120, +171, +168, +170, +327761, +14, +172, +171, +0, +196670, +47, +172, +262205, +14, +173, +44, +262205, +14, +174, +45, +327812, +14, +175, +173, +174, +196670, +46, +175, +65789, +65592, +327734, +2, +57, +0, +50, +196663, +17, +51, +196663, +17, +52, +196663, +17, +53, +196663, +15, +54, +196663, +17, +55, +196663, +15, +56, +131320, +58, +262205, +16, +177, +52, +327812, +16, +178, +176, +177, +262205, +16, +179, +51, +327808, +16, +180, +178, +179, +196670, +53, +180, +327745, +86, +181, +84, +100, +262205, +14, +182, +181, +327808, +14, +183, +182, +103, +262268, +16, +184, +183, +262205, +16, +185, +53, +327812, +16, +186, +185, +184, +196670, +53, +186, +327745, +86, +187, +84, +85, +262205, +14, +188, +187, +327814, +14, +189, +81, +188, +196670, +54, +189, +262205, +114, +190, +116, +262205, +16, +191, +53, +327775, +120, +192, +190, +191, +327761, +14, +193, +192, +0, +196670, +56, +193, +262205, +16, +194, +53, +262205, +14, +195, +54, +262268, +16, +196, +195, +327812, +16, +197, +194, +196, +196670, +55, +197, +65789, +65592, +327734, +59, +63, +0, +60, +196663, +8, +61, +196663, +8, +62, +131320, +64, +262203, +8, +198, +7, +262203, +8, +203, +7, +262203, +8, +216, +7, +262205, +7, +199, +61, +196670, +198, +199, +327737, +9, +200, +12, +198, +196855, +202, +0, +262394, +200, +201, +215, +131320, +201, +262205, +7, +204, +62, +196670, +203, +204, +327737, +9, +205, +12, +203, +196855, +207, +0, +262394, +205, +206, +211, +131320, +206, +131326, +209, +131320, +211, +131326, +213, +131320, +207, +131321, +202, +131320, +215, +262205, +7, +217, +62, +196670, +216, +217, +327737, +9, +218, +12, +216, +196855, +220, +0, +262394, +218, +219, +223, +131320, +219, +131326, +221, +131320, +223, +131326, +224, +131320, +220, +131321, +202, +131320, +202, +196609, +59, +226, +131326, +226, +65592, +327734, +2, +71, +0, +66, +196663, +8, +67, +196663, +8, +68, +196663, +65, +69, +196663, +65, +70, +131320, +72, +262203, +228, +229, +7, +262203, +65, +235, +7, +262203, +65, +240, +7, +262203, +248, +249, +7, +262203, +8, +250, +7, +262203, +8, +252, +7, +262205, +7, +230, +68, +524367, +227, +231, +230, +230, +0, +1, +2, +262205, +7, +232, +67, +524367, +227, +233, +232, +232, +0, +1, +2, +327811, +227, +234, +231, +233, +196670, +229, +234, +262205, +227, +236, +229, +393228, +6, +237, +1, +66, +236, +458764, +6, +239, +1, +40, +237, +238, +196670, +235, +239, +262205, +6, +241, +69, +262205, +6, +242, +235, +327816, +6, +243, +241, +242, +327811, +6, +244, +212, +243, +196670, +240, +244, +262205, +6, +245, +240, +262205, +227, +246, +229, +327822, +227, +247, +246, +245, +196670, +229, +247, +262205, +7, +251, +67, +196670, +250, +251, +262205, +7, +253, +68, +196670, +252, +253, +393273, +59, +254, +63, +250, +252, +196670, +249, +254, +327745, +65, +255, +249, +122, +262205, +6, +256, +255, +262205, +227, +257, +229, +327822, +227, +258, +257, +256, +262205, +6, +259, +70, +327822, +227, +260, +258, +259, +262205, +7, +261, +67, +524367, +227, +262, +261, +261, +0, +1, +2, +327809, +227, +263, +262, +260, +262205, +7, +264, +67, +589903, +7, +265, +264, +263, +4, +5, +6, +3, +196670, +67, +265, +327745, +65, +266, +249, +103, +262205, +6, +267, +266, +262205, +227, +268, +229, +327822, +227, +269, +268, +267, +262205, +6, +270, +70, +327822, +227, +271, +269, +270, +262205, +7, +272, +68, +524367, +227, +273, +272, +272, +0, +1, +2, +327811, +227, +274, +273, +271, +262205, +7, +275, +68, +589903, +7, +276, +275, +274, +4, +5, +6, +3, +196670, +68, +276, +65789, +65592, +}; +const std::vector compute_tangents = {119734787, +65536, +524289, +297, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +5, +4, +1852399981, +0, +187, +188, +393232, +4, +17, +64, +1, +1, +196611, +2, +450, +262149, +4, +1852399981, +0, +393221, +12, +1867346761, +1818386806, +1719019621, +15156, +327685, +11, +1953653104, +1701602153, +0, +1114117, +28, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1953718605, +1965584997, +829766449, +993097019, +1765486965, +829766449, +993097019, +1966813557, +15153, +327685, +19, +1633906540, +1684627308, +0, +327685, +20, +1970238055, +1684627312, +0, +458757, +21, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +22, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +23, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +24, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +25, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +26, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +27, +1634890867, +2035573870, +25968, +1114117, +39, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +828980017, +993097019, +1966813557, +829766449, +59, +327685, +30, +1633906540, +1684627308, +0, +327685, +31, +1970238055, +1684627312, +0, +458757, +32, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +33, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +34, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +35, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +36, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +37, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +38, +1634890867, +2035573870, +25968, +983045, +48, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +829766449, +993097019, +0, +327685, +42, +1633906540, +1684627308, +0, +327685, +43, +1970238055, +1684627312, +0, +458757, +44, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +45, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +46, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +47, +1634890867, +2035573870, +25968, +983045, +57, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1953718605, +1764258405, +828980017, +993093947, +1765486965, +829766449, +59, +327685, +51, +1633906540, +1684627308, +0, +327685, +52, +1970238055, +1684627312, +0, +458757, +53, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +54, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +55, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +56, +1634890867, +2035573870, +25968, +327685, +69, +1936617283, +1953390964, +115, +327686, +69, +0, +1767333735, +25710, +327686, +69, +1, +1767333735, +3236974, +327686, +69, +2, +1767333735, +3302510, +327686, +69, +3, +1767333735, +3368046, +720902, +69, +4, +1968070503, +1852132461, +1130919015, +1953721967, +1852399986, +1702119796, +1769234802, +7564911, +458758, +69, +5, +1130520423, +1768713327, +1852795251, +0, +524294, +69, +6, +1917280103, +1953068641, +1734430073, +1970563438, +25956, +393222, +69, +7, +1767137127, +1951622509, +28773, +393222, +69, +8, +1631870823, +1852403821, +12391, +786438, +69, +9, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +48, +786438, +69, +10, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12391, +851974, +69, +11, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +811951982, +0, +393222, +69, +12, +1631870823, +1852403821, +12647, +786438, +69, +13, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +49, +786438, +69, +14, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12647, +851974, +69, +15, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +828729198, +0, +393222, +69, +16, +1631870823, +1852403821, +12903, +786438, +69, +17, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +50, +786438, +69, +18, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12903, +851974, +69, +19, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +845506414, +0, +393222, +69, +20, +1631870823, +1852403821, +13159, +786438, +69, +21, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +51, +786438, +69, +22, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +13159, +851974, +69, +23, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +862283630, +0, +720902, +69, +24, +1968070503, +1399213933, +1851880052, +1699771236, +1919439986, +1197760869, +1886744434, +0, +720902, +69, +25, +1968070503, +1819231853, +1215786860, +1936877921, +1198679376, +1701079413, +1919508808, +0, +589830, +69, +26, +1767137127, +1885688688, +1952543329, +1181642601, +1869898593, +114, +327686, +69, +27, +1466064743, +7369313, +786438, +69, +28, +1968070503, +1668238445, +1750297697, +1298493537, +1751348321, +1231515241, +1634887028, +1852795252, +115, +196613, +71, +0, +458757, +103, +1632132967, +1951625833, +1684955506, +1701869908, +0, +524293, +187, +1281322087, +1818321775, +1870032457, +1769234787, +1145663087, +0, +393221, +188, +1465871463, +1198223983, +1886744434, +17481, +458757, +189, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +190, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +191, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +192, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +193, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +194, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +195, +1634890867, +2035573870, +25968, +262149, +196, +1634886000, +109, +262149, +200, +1634886000, +109, +262149, +203, +1634886000, +109, +262149, +205, +1634886000, +109, +262149, +207, +1634886000, +109, +262149, +209, +1634886000, +109, +262149, +211, +1634886000, +109, +262149, +213, +1634886000, +109, +262149, +215, +1634886000, +109, +327685, +227, +1918986355, +1867539557, +115, +524293, +229, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +589829, +237, +1332573550, +1920226150, +1935961697, +1416783184, +1634038376, +1869760356, +28789, +262149, +246, +1735287156, +7630437, +458757, +259, +1953067639, +1818386789, +1936674917, +1869182057, +29550, +589830, +259, +0, +1632132967, +1700164201, +2019914866, +1735287124, +1937010277, +0, +196613, +261, +0, +393221, +271, +1953654134, +1834969439, +1937075817, +12639, +262149, +278, +1953654134, +26975, +393221, +293, +1684104520, +1851880020, +1919903347, +109, +589830, +293, +0, +1867341671, +1416389988, +1936613746, +1836216166, +1215459142, +6578533, +589830, +293, +1, +1867341671, +1382835556, +1952543855, +1919895141, +1684104520, +0, +589830, +293, +2, +1852396386, +1214606439, +1415864677, +1936613746, +1836216166, +0, +327686, +293, +3, +1684300144, +6778473, +196613, +295, +0, +327752, +69, +0, +35, +0, +327752, +69, +1, +35, +16, +327752, +69, +2, +35, +32, +327752, +69, +3, +35, +48, +327752, +69, +4, +35, +64, +327752, +69, +5, +35, +68, +327752, +69, +6, +35, +72, +327752, +69, +7, +35, +76, +327752, +69, +8, +35, +80, +327752, +69, +9, +35, +84, +327752, +69, +10, +35, +88, +327752, +69, +11, +35, +92, +327752, +69, +12, +35, +96, +327752, +69, +13, +35, +100, +327752, +69, +14, +35, +104, +327752, +69, +15, +35, +108, +327752, +69, +16, +35, +112, +327752, +69, +17, +35, +116, +327752, +69, +18, +35, +120, +327752, +69, +19, +35, +124, +327752, +69, +20, +35, +128, +327752, +69, +21, +35, +132, +327752, +69, +22, +35, +136, +327752, +69, +23, +35, +140, +327752, +69, +24, +35, +144, +327752, +69, +25, +35, +148, +327752, +69, +26, +35, +152, +327752, +69, +27, +35, +156, +327752, +69, +28, +35, +160, +196679, +69, +3, +262215, +71, +34, +0, +262215, +71, +33, +16, +262215, +103, +34, +1, +262215, +103, +33, +22, +262215, +187, +11, +27, +262215, +188, +11, +26, +262215, +229, +34, +1, +262215, +229, +33, +7, +262215, +258, +6, +16, +327752, +259, +0, +35, +0, +196679, +259, +3, +262215, +261, +34, +1, +262215, +261, +33, +8, +262215, +292, +6, +16, +262216, +293, +0, +5, +327752, +293, +0, +35, +0, +327752, +293, +0, +7, +16, +327752, +293, +1, +35, +64, +327752, +293, +2, +35, +80, +327752, +293, +3, +35, +96, +196679, +293, +3, +262215, +295, +34, +0, +262215, +295, +33, +27, +262215, +296, +11, +25, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +131092, +9, +262177, +10, +9, +8, +262165, +14, +32, +0, +262176, +15, +7, +14, +262165, +16, +32, +1, +262176, +17, +7, +16, +786465, +18, +2, +15, +15, +15, +15, +17, +15, +15, +15, +15, +589857, +41, +2, +15, +15, +15, +15, +15, +15, +589857, +50, +2, +17, +17, +17, +15, +17, +15, +262187, +14, +59, +3, +262176, +60, +7, +6, +262187, +6, +63, +0, +262187, +14, +68, +64, +2031646, +69, +7, +7, +7, +7, +16, +16, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +14, +14, +6, +16, +16, +262176, +70, +2, +69, +262203, +70, +71, +2, +262187, +16, +72, +24, +262176, +73, +2, +14, +262187, +16, +87, +25, +262187, +14, +90, +1, +589849, +100, +14, +5, +0, +0, +0, +1, +0, +196635, +101, +100, +262176, +102, +0, +101, +262203, +102, +103, +0, +262167, +107, +14, +4, +262187, +14, +109, +0, +262187, +16, +163, +64, +262167, +185, +14, +3, +262176, +186, +1, +185, +262203, +186, +187, +1, +262203, +186, +188, +1, +262176, +197, +1, +14, +262172, +225, +7, +68, +262176, +226, +4, +225, +262203, +226, +227, +4, +262203, +102, +229, +0, +262176, +234, +4, +7, +262187, +14, +236, +4062, +262167, +244, +6, +3, +262176, +245, +7, +244, +196637, +258, +7, +196638, +259, +258, +262176, +260, +2, +259, +262203, +260, +261, +2, +262187, +16, +262, +0, +262176, +266, +2, +7, +262168, +291, +7, +4, +262172, +292, +6, +59, +393246, +293, +291, +7, +16, +292, +262176, +294, +2, +293, +262203, +294, +295, +2, +393260, +185, +296, +68, +90, +90, +327734, +2, +4, +0, +3, +131320, +5, +262203, +15, +189, +7, +262203, +15, +190, +7, +262203, +17, +191, +7, +262203, +15, +192, +7, +262203, +15, +193, +7, +262203, +15, +194, +7, +262203, +15, +195, +7, +262203, +15, +196, +7, +262203, +15, +200, +7, +262203, +15, +203, +7, +262203, +15, +205, +7, +262203, +17, +207, +7, +262203, +15, +209, +7, +262203, +15, +211, +7, +262203, +15, +213, +7, +262203, +15, +215, +7, +262203, +15, +237, +7, +262203, +245, +246, +7, +262203, +245, +271, +7, +262203, +245, +278, +7, +327745, +197, +198, +187, +109, +262205, +14, +199, +198, +196670, +196, +199, +327745, +197, +201, +188, +109, +262205, +14, +202, +201, +196670, +200, +202, +262205, +14, +204, +189, +196670, +203, +204, +262205, +14, +206, +190, +196670, +205, +206, +262205, +16, +208, +191, +196670, +207, +208, +262205, +14, +210, +192, +196670, +209, +210, +262205, +14, +212, +193, +196670, +211, +212, +262205, +14, +214, +194, +196670, +213, +214, +262205, +14, +216, +195, +196670, +215, +216, +852025, +2, +217, +39, +196, +200, +203, +205, +207, +209, +211, +213, +215, +262205, +14, +218, +203, +196670, +189, +218, +262205, +14, +219, +205, +196670, +190, +219, +262205, +16, +220, +207, +196670, +191, +220, +262205, +14, +221, +209, +196670, +192, +221, +262205, +14, +222, +211, +196670, +193, +222, +262205, +14, +223, +213, +196670, +194, +223, +262205, +14, +224, +215, +196670, +195, +224, +262205, +14, +228, +194, +262205, +101, +230, +229, +262205, +16, +231, +191, +327775, +107, +232, +230, +231, +262256, +7, +233, +232, +327745, +234, +235, +227, +228, +196670, +235, +233, +196833, +90, +236, +262368, +90, +90, +109, +327745, +73, +238, +71, +72, +262205, +14, +239, +238, +196670, +237, +239, +262205, +14, +240, +192, +327850, +9, +241, +240, +109, +196855, +243, +0, +262394, +241, +242, +270, +131320, +242, +262205, +14, +247, +194, +262205, +14, +248, +237, +327808, +14, +249, +247, +248, +327745, +234, +250, +227, +249, +262205, +7, +251, +250, +524367, +244, +252, +251, +251, +0, +1, +2, +262205, +14, +253, +194, +327745, +234, +254, +227, +253, +262205, +7, +255, +254, +524367, +244, +256, +255, +255, +0, +1, +2, +327811, +244, +257, +252, +256, +196670, +246, +257, +262205, +16, +263, +191, +262205, +244, +264, +246, +393228, +244, +265, +1, +69, +264, +393281, +266, +267, +261, +262, +263, +262205, +7, +268, +267, +589903, +7, +269, +268, +265, +4, +5, +6, +3, +196670, +267, +269, +131321, +243, +131320, +270, +262205, +14, +272, +194, +262205, +14, +273, +237, +327810, +14, +274, +272, +273, +327745, +234, +275, +227, +274, +262205, +7, +276, +275, +524367, +244, +277, +276, +276, +0, +1, +2, +196670, +271, +277, +262205, +14, +279, +194, +327745, +234, +280, +227, +279, +262205, +7, +281, +280, +524367, +244, +282, +281, +281, +0, +1, +2, +196670, +278, +282, +262205, +16, +283, +191, +262205, +244, +284, +278, +262205, +244, +285, +271, +327811, +244, +286, +284, +285, +393228, +244, +287, +1, +69, +286, +393281, +266, +288, +261, +262, +283, +262205, +7, +289, +288, +589903, +7, +290, +289, +287, +4, +5, +6, +3, +196670, +288, +290, +131321, +243, +131320, +243, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +327745, +60, +61, +11, +59, +262205, +6, +62, +61, +327866, +9, +64, +62, +63, +131326, +64, +65592, +327734, +2, +28, +0, +18, +196663, +15, +19, +196663, +15, +20, +196663, +15, +21, +196663, +15, +22, +196663, +17, +23, +196663, +15, +24, +196663, +15, +25, +196663, +15, +26, +196663, +15, +27, +131320, +29, +262205, +14, +67, +19, +196670, +26, +67, +327745, +73, +74, +71, +72, +262205, +14, +75, +74, +327814, +14, +76, +68, +75, +196670, +25, +76, +262205, +14, +77, +19, +327745, +73, +78, +71, +72, +262205, +14, +79, +78, +327817, +14, +80, +77, +79, +196670, +22, +80, +262205, +14, +81, +20, +327745, +73, +82, +71, +72, +262205, +14, +83, +82, +327812, +14, +84, +81, +83, +262205, +14, +85, +22, +327808, +14, +86, +84, +85, +196670, +21, +86, +327745, +73, +88, +71, +87, +262205, +14, +89, +88, +327808, +14, +91, +89, +90, +262205, +14, +92, +21, +327812, +14, +93, +92, +91, +196670, +21, +93, +262205, +14, +94, +19, +262205, +14, +95, +22, +327810, +14, +96, +94, +95, +327745, +73, +97, +71, +72, +262205, +14, +98, +97, +327814, +14, +99, +96, +98, +196670, +24, +99, +262205, +101, +104, +103, +262205, +14, +105, +21, +262268, +16, +106, +105, +327775, +107, +108, +104, +106, +327761, +14, +110, +108, +0, +196670, +27, +110, +262205, +14, +111, +21, +262205, +14, +112, +25, +327812, +14, +113, +111, +112, +262205, +14, +114, +24, +327808, +14, +115, +113, +114, +262268, +16, +116, +115, +196670, +23, +116, +65789, +65592, +327734, +2, +39, +0, +18, +196663, +15, +30, +196663, +15, +31, +196663, +15, +32, +196663, +15, +33, +196663, +17, +34, +196663, +15, +35, +196663, +15, +36, +196663, +15, +37, +196663, +15, +38, +131320, +40, +262205, +14, +117, +30, +196670, +37, +117, +327745, +73, +118, +71, +72, +262205, +14, +119, +118, +327814, +14, +120, +68, +119, +196670, +36, +120, +262205, +14, +121, +30, +327745, +73, +122, +71, +72, +262205, +14, +123, +122, +327817, +14, +124, +121, +123, +196670, +33, +124, +262205, +14, +125, +31, +327745, +73, +126, +71, +72, +262205, +14, +127, +126, +327812, +14, +128, +125, +127, +262205, +14, +129, +33, +327808, +14, +130, +128, +129, +196670, +32, +130, +262205, +14, +131, +30, +262205, +14, +132, +33, +327810, +14, +133, +131, +132, +327745, +73, +134, +71, +72, +262205, +14, +135, +134, +327814, +14, +136, +133, +135, +196670, +35, +136, +262205, +101, +137, +103, +262205, +14, +138, +32, +262268, +16, +139, +138, +327775, +107, +140, +137, +139, +327761, +14, +141, +140, +0, +196670, +38, +141, +262205, +14, +142, +32, +262205, +14, +143, +36, +327812, +14, +144, +142, +143, +262205, +14, +145, +35, +327808, +14, +146, +144, +145, +262268, +16, +147, +146, +196670, +34, +147, +65789, +65592, +327734, +2, +48, +0, +41, +196663, +15, +42, +196663, +15, +43, +196663, +15, +44, +196663, +15, +45, +196663, +15, +46, +196663, +15, +47, +131320, +49, +262205, +14, +148, +43, +327812, +14, +149, +68, +148, +262205, +14, +150, +42, +327808, +14, +151, +149, +150, +196670, +44, +151, +327745, +73, +152, +71, +72, +262205, +14, +153, +152, +327814, +14, +154, +68, +153, +196670, +45, +154, +262205, +101, +155, +103, +262205, +14, +156, +44, +262268, +16, +157, +156, +327775, +107, +158, +155, +157, +327761, +14, +159, +158, +0, +196670, +47, +159, +262205, +14, +160, +44, +262205, +14, +161, +45, +327812, +14, +162, +160, +161, +196670, +46, +162, +65789, +65592, +327734, +2, +57, +0, +50, +196663, +17, +51, +196663, +17, +52, +196663, +17, +53, +196663, +15, +54, +196663, +17, +55, +196663, +15, +56, +131320, +58, +262205, +16, +164, +52, +327812, +16, +165, +163, +164, +262205, +16, +166, +51, +327808, +16, +167, +165, +166, +196670, +53, +167, +327745, +73, +168, +71, +87, +262205, +14, +169, +168, +327808, +14, +170, +169, +90, +262268, +16, +171, +170, +262205, +16, +172, +53, +327812, +16, +173, +172, +171, +196670, +53, +173, +327745, +73, +174, +71, +72, +262205, +14, +175, +174, +327814, +14, +176, +68, +175, +196670, +54, +176, +262205, +101, +177, +103, +262205, +16, +178, +53, +327775, +107, +179, +177, +178, +327761, +14, +180, +179, +0, +196670, +56, +180, +262205, +16, +181, +53, +262205, +14, +182, +54, +262268, +16, +183, +182, +327812, +16, +184, +181, +183, +196670, +55, +184, +65789, +65592, +}; +const std::vector prepare_follow_hair = {119734787, +65536, +524289, +271, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +5, +4, +1852399981, +0, +187, +188, +393232, +4, +17, +64, +1, +1, +196611, +2, +450, +262149, +4, +1852399981, +0, +393221, +12, +1867346761, +1818386806, +1719019621, +15156, +327685, +11, +1953653104, +1701602153, +0, +1114117, +28, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1953718605, +1965584997, +829766449, +993097019, +1765486965, +829766449, +993097019, +1966813557, +15153, +327685, +19, +1633906540, +1684627308, +0, +327685, +20, +1970238055, +1684627312, +0, +458757, +21, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +22, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +23, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +24, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +25, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +26, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +27, +1634890867, +2035573870, +25968, +1114117, +39, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +828980017, +993097019, +1966813557, +829766449, +59, +327685, +30, +1633906540, +1684627308, +0, +327685, +31, +1970238055, +1684627312, +0, +458757, +32, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +33, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +34, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +35, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +36, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +37, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +38, +1634890867, +2035573870, +25968, +983045, +48, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +829766449, +993097019, +0, +327685, +42, +1633906540, +1684627308, +0, +327685, +43, +1970238055, +1684627312, +0, +458757, +44, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +45, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +46, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +47, +1634890867, +2035573870, +25968, +983045, +57, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1953718605, +1764258405, +828980017, +993093947, +1765486965, +829766449, +59, +327685, +51, +1633906540, +1684627308, +0, +327685, +52, +1970238055, +1684627312, +0, +458757, +53, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +54, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +55, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +56, +1634890867, +2035573870, +25968, +327685, +69, +1936617283, +1953390964, +115, +327686, +69, +0, +1767333735, +25710, +327686, +69, +1, +1767333735, +3236974, +327686, +69, +2, +1767333735, +3302510, +327686, +69, +3, +1767333735, +3368046, +720902, +69, +4, +1968070503, +1852132461, +1130919015, +1953721967, +1852399986, +1702119796, +1769234802, +7564911, +458758, +69, +5, +1130520423, +1768713327, +1852795251, +0, +524294, +69, +6, +1917280103, +1953068641, +1734430073, +1970563438, +25956, +393222, +69, +7, +1767137127, +1951622509, +28773, +393222, +69, +8, +1631870823, +1852403821, +12391, +786438, +69, +9, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +48, +786438, +69, +10, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12391, +851974, +69, +11, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +811951982, +0, +393222, +69, +12, +1631870823, +1852403821, +12647, +786438, +69, +13, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +49, +786438, +69, +14, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12647, +851974, +69, +15, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +828729198, +0, +393222, +69, +16, +1631870823, +1852403821, +12903, +786438, +69, +17, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +50, +786438, +69, +18, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12903, +851974, +69, +19, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +845506414, +0, +393222, +69, +20, +1631870823, +1852403821, +13159, +786438, +69, +21, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +51, +786438, +69, +22, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +13159, +851974, +69, +23, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +862283630, +0, +720902, +69, +24, +1968070503, +1399213933, +1851880052, +1699771236, +1919439986, +1197760869, +1886744434, +0, +720902, +69, +25, +1968070503, +1819231853, +1215786860, +1936877921, +1198679376, +1701079413, +1919508808, +0, +589830, +69, +26, +1767137127, +1885688688, +1952543329, +1181642601, +1869898593, +114, +327686, +69, +27, +1466064743, +7369313, +786438, +69, +28, +1968070503, +1668238445, +1750297697, +1298493537, +1751348321, +1231515241, +1634887028, +1852795252, +115, +196613, +71, +0, +458757, +103, +1632132967, +1951625833, +1684955506, +1701869908, +0, +524293, +187, +1281322087, +1818321775, +1870032457, +1769234787, +1145663087, +0, +393221, +188, +1465871463, +1198223983, +1886744434, +17481, +458757, +189, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +190, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +191, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +192, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +193, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +194, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +195, +1634890867, +2035573870, +25968, +262149, +196, +1634886000, +109, +262149, +200, +1634886000, +109, +262149, +203, +1634886000, +109, +262149, +205, +1634886000, +109, +262149, +207, +1634886000, +109, +262149, +209, +1634886000, +109, +262149, +211, +1634886000, +109, +262149, +213, +1634886000, +109, +262149, +215, +1634886000, +109, +196613, +225, +105, +524293, +237, +1651469415, +1866886241, +2003790956, +1953654102, +1850308709, +7890276, +262149, +246, +1919508840, +7565136, +524293, +250, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +524293, +255, +1953067639, +1818386789, +1936674917, +1869182057, +1701990510, +118, +655366, +255, +0, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +1701990515, +118, +196613, +257, +0, +393221, +267, +1684104520, +1851880020, +1919903347, +109, +589830, +267, +0, +1867341671, +1416389988, +1936613746, +1836216166, +1215459142, +6578533, +589830, +267, +1, +1867341671, +1382835556, +1952543855, +1919895141, +1684104520, +0, +589830, +267, +2, +1852396386, +1214606439, +1415864677, +1936613746, +1836216166, +0, +327686, +267, +3, +1684300144, +6778473, +196613, +269, +0, +327752, +69, +0, +35, +0, +327752, +69, +1, +35, +16, +327752, +69, +2, +35, +32, +327752, +69, +3, +35, +48, +327752, +69, +4, +35, +64, +327752, +69, +5, +35, +68, +327752, +69, +6, +35, +72, +327752, +69, +7, +35, +76, +327752, +69, +8, +35, +80, +327752, +69, +9, +35, +84, +327752, +69, +10, +35, +88, +327752, +69, +11, +35, +92, +327752, +69, +12, +35, +96, +327752, +69, +13, +35, +100, +327752, +69, +14, +35, +104, +327752, +69, +15, +35, +108, +327752, +69, +16, +35, +112, +327752, +69, +17, +35, +116, +327752, +69, +18, +35, +120, +327752, +69, +19, +35, +124, +327752, +69, +20, +35, +128, +327752, +69, +21, +35, +132, +327752, +69, +22, +35, +136, +327752, +69, +23, +35, +140, +327752, +69, +24, +35, +144, +327752, +69, +25, +35, +148, +327752, +69, +26, +35, +152, +327752, +69, +27, +35, +156, +327752, +69, +28, +35, +160, +196679, +69, +3, +262215, +71, +34, +0, +262215, +71, +33, +16, +262215, +103, +34, +1, +262215, +103, +33, +22, +262215, +187, +11, +27, +262215, +188, +11, +26, +262215, +250, +34, +1, +262215, +250, +33, +7, +262215, +254, +6, +16, +327752, +255, +0, +35, +0, +196679, +255, +3, +262215, +257, +34, +1, +262215, +257, +33, +20, +262215, +266, +6, +16, +262216, +267, +0, +5, +327752, +267, +0, +35, +0, +327752, +267, +0, +7, +16, +327752, +267, +1, +35, +64, +327752, +267, +2, +35, +80, +327752, +267, +3, +35, +96, +196679, +267, +3, +262215, +269, +34, +0, +262215, +269, +33, +27, +262215, +270, +11, +25, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +131092, +9, +262177, +10, +9, +8, +262165, +14, +32, +0, +262176, +15, +7, +14, +262165, +16, +32, +1, +262176, +17, +7, +16, +786465, +18, +2, +15, +15, +15, +15, +17, +15, +15, +15, +15, +589857, +41, +2, +15, +15, +15, +15, +15, +15, +589857, +50, +2, +17, +17, +17, +15, +17, +15, +262187, +14, +59, +3, +262176, +60, +7, +6, +262187, +6, +63, +0, +262187, +14, +68, +64, +2031646, +69, +7, +7, +7, +7, +16, +16, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +14, +14, +6, +16, +16, +262176, +70, +2, +69, +262203, +70, +71, +2, +262187, +16, +72, +24, +262176, +73, +2, +14, +262187, +16, +87, +25, +262187, +14, +90, +1, +589849, +100, +14, +5, +0, +0, +0, +1, +0, +196635, +101, +100, +262176, +102, +0, +101, +262203, +102, +103, +0, +262167, +107, +14, +4, +262187, +14, +109, +0, +262187, +16, +163, +64, +262167, +185, +14, +3, +262176, +186, +1, +185, +262203, +186, +187, +1, +262203, +186, +188, +1, +262176, +197, +1, +14, +262187, +16, +226, +0, +262187, +16, +242, +1, +589849, +247, +6, +5, +0, +0, +0, +1, +0, +196635, +248, +247, +262176, +249, +0, +248, +262203, +249, +250, +0, +196637, +254, +7, +196638, +255, +254, +262176, +256, +2, +255, +262203, +256, +257, +2, +262176, +260, +2, +7, +262168, +265, +7, +4, +262172, +266, +6, +59, +393246, +267, +265, +7, +16, +266, +262176, +268, +2, +267, +262203, +268, +269, +2, +393260, +185, +270, +68, +90, +90, +327734, +2, +4, +0, +3, +131320, +5, +262203, +15, +189, +7, +262203, +15, +190, +7, +262203, +17, +191, +7, +262203, +15, +192, +7, +262203, +15, +193, +7, +262203, +15, +194, +7, +262203, +15, +195, +7, +262203, +15, +196, +7, +262203, +15, +200, +7, +262203, +15, +203, +7, +262203, +15, +205, +7, +262203, +17, +207, +7, +262203, +15, +209, +7, +262203, +15, +211, +7, +262203, +15, +213, +7, +262203, +15, +215, +7, +262203, +17, +225, +7, +262203, +17, +237, +7, +262203, +8, +246, +7, +327745, +197, +198, +187, +109, +262205, +14, +199, +198, +196670, +196, +199, +327745, +197, +201, +188, +109, +262205, +14, +202, +201, +196670, +200, +202, +262205, +14, +204, +189, +196670, +203, +204, +262205, +14, +206, +190, +196670, +205, +206, +262205, +16, +208, +191, +196670, +207, +208, +262205, +14, +210, +192, +196670, +209, +210, +262205, +14, +212, +193, +196670, +211, +212, +262205, +14, +214, +194, +196670, +213, +214, +262205, +14, +216, +195, +196670, +215, +216, +852025, +2, +217, +28, +196, +200, +203, +205, +207, +209, +211, +213, +215, +262205, +14, +218, +203, +196670, +189, +218, +262205, +14, +219, +205, +196670, +190, +219, +262205, +16, +220, +207, +196670, +191, +220, +262205, +14, +221, +209, +196670, +192, +221, +262205, +14, +222, +211, +196670, +193, +222, +262205, +14, +223, +213, +196670, +194, +223, +262205, +14, +224, +215, +196670, +195, +224, +196670, +225, +226, +131321, +227, +131320, +227, +262390, +229, +230, +0, +131321, +231, +131320, +231, +262205, +16, +232, +225, +262268, +14, +233, +232, +327745, +73, +234, +71, +87, +262205, +14, +235, +234, +327856, +9, +236, +233, +235, +262394, +236, +228, +229, +131320, +228, +262205, +16, +238, +191, +262205, +14, +239, +193, +262268, +16, +240, +239, +262205, +16, +241, +225, +327808, +16, +243, +241, +242, +327812, +16, +244, +240, +243, +327808, +16, +245, +238, +244, +196670, +237, +245, +262205, +248, +251, +250, +262205, +16, +252, +237, +327775, +7, +253, +251, +252, +196670, +246, +253, +262205, +16, +258, +237, +262205, +7, +259, +246, +393281, +260, +261, +257, +226, +258, +196670, +261, +259, +131321, +230, +131320, +230, +262205, +16, +262, +225, +327808, +16, +263, +262, +242, +196670, +225, +263, +131321, +227, +131320, +229, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +327745, +60, +61, +11, +59, +262205, +6, +62, +61, +327866, +9, +64, +62, +63, +131326, +64, +65592, +327734, +2, +28, +0, +18, +196663, +15, +19, +196663, +15, +20, +196663, +15, +21, +196663, +15, +22, +196663, +17, +23, +196663, +15, +24, +196663, +15, +25, +196663, +15, +26, +196663, +15, +27, +131320, +29, +262205, +14, +67, +19, +196670, +26, +67, +327745, +73, +74, +71, +72, +262205, +14, +75, +74, +327814, +14, +76, +68, +75, +196670, +25, +76, +262205, +14, +77, +19, +327745, +73, +78, +71, +72, +262205, +14, +79, +78, +327817, +14, +80, +77, +79, +196670, +22, +80, +262205, +14, +81, +20, +327745, +73, +82, +71, +72, +262205, +14, +83, +82, +327812, +14, +84, +81, +83, +262205, +14, +85, +22, +327808, +14, +86, +84, +85, +196670, +21, +86, +327745, +73, +88, +71, +87, +262205, +14, +89, +88, +327808, +14, +91, +89, +90, +262205, +14, +92, +21, +327812, +14, +93, +92, +91, +196670, +21, +93, +262205, +14, +94, +19, +262205, +14, +95, +22, +327810, +14, +96, +94, +95, +327745, +73, +97, +71, +72, +262205, +14, +98, +97, +327814, +14, +99, +96, +98, +196670, +24, +99, +262205, +101, +104, +103, +262205, +14, +105, +21, +262268, +16, +106, +105, +327775, +107, +108, +104, +106, +327761, +14, +110, +108, +0, +196670, +27, +110, +262205, +14, +111, +21, +262205, +14, +112, +25, +327812, +14, +113, +111, +112, +262205, +14, +114, +24, +327808, +14, +115, +113, +114, +262268, +16, +116, +115, +196670, +23, +116, +65789, +65592, +327734, +2, +39, +0, +18, +196663, +15, +30, +196663, +15, +31, +196663, +15, +32, +196663, +15, +33, +196663, +17, +34, +196663, +15, +35, +196663, +15, +36, +196663, +15, +37, +196663, +15, +38, +131320, +40, +262205, +14, +117, +30, +196670, +37, +117, +327745, +73, +118, +71, +72, +262205, +14, +119, +118, +327814, +14, +120, +68, +119, +196670, +36, +120, +262205, +14, +121, +30, +327745, +73, +122, +71, +72, +262205, +14, +123, +122, +327817, +14, +124, +121, +123, +196670, +33, +124, +262205, +14, +125, +31, +327745, +73, +126, +71, +72, +262205, +14, +127, +126, +327812, +14, +128, +125, +127, +262205, +14, +129, +33, +327808, +14, +130, +128, +129, +196670, +32, +130, +262205, +14, +131, +30, +262205, +14, +132, +33, +327810, +14, +133, +131, +132, +327745, +73, +134, +71, +72, +262205, +14, +135, +134, +327814, +14, +136, +133, +135, +196670, +35, +136, +262205, +101, +137, +103, +262205, +14, +138, +32, +262268, +16, +139, +138, +327775, +107, +140, +137, +139, +327761, +14, +141, +140, +0, +196670, +38, +141, +262205, +14, +142, +32, +262205, +14, +143, +36, +327812, +14, +144, +142, +143, +262205, +14, +145, +35, +327808, +14, +146, +144, +145, +262268, +16, +147, +146, +196670, +34, +147, +65789, +65592, +327734, +2, +48, +0, +41, +196663, +15, +42, +196663, +15, +43, +196663, +15, +44, +196663, +15, +45, +196663, +15, +46, +196663, +15, +47, +131320, +49, +262205, +14, +148, +43, +327812, +14, +149, +68, +148, +262205, +14, +150, +42, +327808, +14, +151, +149, +150, +196670, +44, +151, +327745, +73, +152, +71, +72, +262205, +14, +153, +152, +327814, +14, +154, +68, +153, +196670, +45, +154, +262205, +101, +155, +103, +262205, +14, +156, +44, +262268, +16, +157, +156, +327775, +107, +158, +155, +157, +327761, +14, +159, +158, +0, +196670, +47, +159, +262205, +14, +160, +44, +262205, +14, +161, +45, +327812, +14, +162, +160, +161, +196670, +46, +162, +65789, +65592, +327734, +2, +57, +0, +50, +196663, +17, +51, +196663, +17, +52, +196663, +17, +53, +196663, +15, +54, +196663, +17, +55, +196663, +15, +56, +131320, +58, +262205, +16, +164, +52, +327812, +16, +165, +163, +164, +262205, +16, +166, +51, +327808, +16, +167, +165, +166, +196670, +53, +167, +327745, +73, +168, +71, +87, +262205, +14, +169, +168, +327808, +14, +170, +169, +90, +262268, +16, +171, +170, +262205, +16, +172, +53, +327812, +16, +173, +172, +171, +196670, +53, +173, +327745, +73, +174, +71, +72, +262205, +14, +175, +174, +327814, +14, +176, +68, +175, +196670, +54, +176, +262205, +101, +177, +103, +262205, +16, +178, +53, +327775, +107, +179, +177, +178, +327761, +14, +180, +179, +0, +196670, +56, +180, +262205, +16, +181, +53, +262205, +14, +182, +54, +262268, +16, +183, +182, +327812, +16, +184, +181, +183, +196670, +55, +184, +65789, +65592, +}; +const std::vector update_follow_hair = {119734787, +65536, +524289, +312, +0, +131089, +1, +131089, +46, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +5, +4, +1852399981, +0, +187, +188, +393232, +4, +17, +64, +1, +1, +196611, +2, +450, +262149, +4, +1852399981, +0, +393221, +12, +1867346761, +1818386806, +1719019621, +15156, +327685, +11, +1953653104, +1701602153, +0, +1114117, +28, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1953718605, +1965584997, +829766449, +993097019, +1765486965, +829766449, +993097019, +1966813557, +15153, +327685, +19, +1633906540, +1684627308, +0, +327685, +20, +1970238055, +1684627312, +0, +458757, +21, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +22, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +23, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +24, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +25, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +26, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +27, +1634890867, +2035573870, +25968, +1114117, +39, +1668047171, +1768189513, +1232299363, +1919243886, +1282958708, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +828980017, +993097019, +1966813557, +829766449, +59, +327685, +30, +1633906540, +1684627308, +0, +327685, +31, +1970238055, +1684627312, +0, +458757, +32, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +33, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +34, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +35, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +36, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +37, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +38, +1634890867, +2035573870, +25968, +983045, +48, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1635020628, +829761644, +993097019, +1966813557, +829766449, +993097019, +0, +327685, +42, +1633906540, +1684627308, +0, +327685, +43, +1970238055, +1684627312, +0, +458757, +44, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +45, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +46, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +47, +1634890867, +2035573870, +25968, +983045, +57, +1668047171, +1768189513, +1232299363, +1920226158, +1281650273, +1818588773, +1953718605, +1764258405, +828980017, +993093947, +1765486965, +829766449, +59, +327685, +51, +1633906540, +1684627308, +0, +327685, +52, +1970238055, +1684627312, +0, +458757, +53, +1651469415, +1951624289, +1684955506, +1701080649, +120, +524293, +54, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +524293, +55, +1651469415, +1867672673, +1700164719, +2019914866, +1701080649, +120, +327685, +56, +1634890867, +2035573870, +25968, +327685, +69, +1936617283, +1953390964, +115, +327686, +69, +0, +1767333735, +25710, +327686, +69, +1, +1767333735, +3236974, +327686, +69, +2, +1767333735, +3302510, +327686, +69, +3, +1767333735, +3368046, +720902, +69, +4, +1968070503, +1852132461, +1130919015, +1953721967, +1852399986, +1702119796, +1769234802, +7564911, +458758, +69, +5, +1130520423, +1768713327, +1852795251, +0, +524294, +69, +6, +1917280103, +1953068641, +1734430073, +1970563438, +25956, +393222, +69, +7, +1767137127, +1951622509, +28773, +393222, +69, +8, +1631870823, +1852403821, +12391, +786438, +69, +9, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +48, +786438, +69, +10, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12391, +851974, +69, +11, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +811951982, +0, +393222, +69, +12, +1631870823, +1852403821, +12647, +786438, +69, +13, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +49, +786438, +69, +14, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12647, +851974, +69, +15, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +828729198, +0, +393222, +69, +16, +1631870823, +1852403821, +12903, +786438, +69, +17, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +50, +786438, +69, +18, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +12903, +851974, +69, +19, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +845506414, +0, +393222, +69, +20, +1631870823, +1852403821, +13159, +786438, +69, +21, +1951620967, +1852204649, +1181971301, +1867281007, +1399611747, +1701863784, +1668571469, +1735289192, +51, +786438, +69, +22, +1951620967, +1852204649, +1181971301, +1816621679, +1818321519, +1885431891, +1952533861, +1852401763, +13159, +851974, +69, +23, +1816616807, +1818321519, +1885431891, +1952533861, +1852401763, +1717978471, +1769235301, +1632789878, +862283630, +0, +720902, +69, +24, +1968070503, +1399213933, +1851880052, +1699771236, +1919439986, +1197760869, +1886744434, +0, +720902, +69, +25, +1968070503, +1819231853, +1215786860, +1936877921, +1198679376, +1701079413, +1919508808, +0, +589830, +69, +26, +1767137127, +1885688688, +1952543329, +1181642601, +1869898593, +114, +327686, +69, +27, +1466064743, +7369313, +786438, +69, +28, +1968070503, +1668238445, +1750297697, +1298493537, +1751348321, +1231515241, +1634887028, +1852795252, +115, +196613, +71, +0, +458757, +103, +1632132967, +1951625833, +1684955506, +1701869908, +0, +524293, +187, +1281322087, +1818321775, +1870032457, +1769234787, +1145663087, +0, +393221, +188, +1465871463, +1198223983, +1886744434, +17481, +458757, +189, +1651469415, +1951624289, +1684955506, +1701080649, +120, +458757, +190, +1633906540, +1920226156, +1231318625, +2019910766, +0, +458757, +191, +1651469415, +1700162657, +2019914866, +1701080649, +120, +458757, +192, +1633906540, +1919243884, +1232627060, +2019910766, +0, +524293, +193, +1450014062, +1769239141, +1232299363, +1701336174, +1634890835, +25710, +458757, +194, +1701080681, +1919895160, +1918986323, +1699570789, +109, +327685, +195, +1634890867, +2035573870, +25968, +262149, +196, +1634886000, +109, +262149, +200, +1634886000, +109, +262149, +203, +1634886000, +109, +262149, +205, +1634886000, +109, +262149, +207, +1634886000, +109, +262149, +209, +1634886000, +109, +262149, +211, +1634886000, +109, +262149, +213, +1634886000, +109, +262149, +215, +1634886000, +109, +327685, +227, +1918986355, +1867539557, +115, +458757, +230, +1953067639, +1818386789, +1936674917, +1869182057, +29550, +589830, +230, +0, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, +196613, +232, +0, +196613, +241, +105, +524293, +252, +1651469415, +1866886241, +2003790956, +1953654102, +1850308709, +7890276, +524293, +261, +1651469415, +1866886241, +2003790956, +1634890835, +1850303598, +7890276, +262149, +267, +1952670054, +29295, +327685, +282, +1819045734, +1867544431, +115, +524293, +291, +1866882919, +2003790956, +1919508808, +1953460050, +1936090703, +29797, +393221, +308, +1684104520, +1851880020, +1919903347, +109, +589830, +308, +0, +1867341671, +1416389988, +1936613746, +1836216166, +1215459142, +6578533, +589830, +308, +1, +1867341671, +1382835556, +1952543855, +1919895141, +1684104520, +0, +589830, +308, +2, +1852396386, +1214606439, +1415864677, +1936613746, +1836216166, +0, +327686, +308, +3, +1684300144, +6778473, +196613, +310, +0, +327752, +69, +0, +35, +0, +327752, +69, +1, +35, +16, +327752, +69, +2, +35, +32, +327752, +69, +3, +35, +48, +327752, +69, +4, +35, +64, +327752, +69, +5, +35, +68, +327752, +69, +6, +35, +72, +327752, +69, +7, +35, +76, +327752, +69, +8, +35, +80, +327752, +69, +9, +35, +84, +327752, +69, +10, +35, +88, +327752, +69, +11, +35, +92, +327752, +69, +12, +35, +96, +327752, +69, +13, +35, +100, +327752, +69, +14, +35, +104, +327752, +69, +15, +35, +108, +327752, +69, +16, +35, +112, +327752, +69, +17, +35, +116, +327752, +69, +18, +35, +120, +327752, +69, +19, +35, +124, +327752, +69, +20, +35, +128, +327752, +69, +21, +35, +132, +327752, +69, +22, +35, +136, +327752, +69, +23, +35, +140, +327752, +69, +24, +35, +144, +327752, +69, +25, +35, +148, +327752, +69, +26, +35, +152, +327752, +69, +27, +35, +156, +327752, +69, +28, +35, +160, +196679, +69, +3, +262215, +71, +34, +0, +262215, +71, +33, +16, +262215, +103, +34, +1, +262215, +103, +33, +22, +262215, +187, +11, +27, +262215, +188, +11, +26, +262215, +229, +6, +16, +327752, +230, +0, +35, +0, +196679, +230, +3, +262215, +232, +34, +1, +262215, +232, +33, +7, +262215, +291, +34, +1, +262215, +291, +33, +25, +262215, +307, +6, +16, +262216, +308, +0, +5, +327752, +308, +0, +35, +0, +327752, +308, +0, +7, +16, +327752, +308, +1, +35, +64, +327752, +308, +2, +35, +80, +327752, +308, +3, +35, +96, +196679, +308, +3, +262215, +310, +34, +0, +262215, +310, +33, +27, +262215, +311, +11, +25, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +131092, +9, +262177, +10, +9, +8, +262165, +14, +32, +0, +262176, +15, +7, +14, +262165, +16, +32, +1, +262176, +17, +7, +16, +786465, +18, +2, +15, +15, +15, +15, +17, +15, +15, +15, +15, +589857, +41, +2, +15, +15, +15, +15, +15, +15, +589857, +50, +2, +17, +17, +17, +15, +17, +15, +262187, +14, +59, +3, +262176, +60, +7, +6, +262187, +6, +63, +0, +262187, +14, +68, +64, +2031646, +69, +7, +7, +7, +7, +16, +16, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +14, +14, +6, +16, +16, +262176, +70, +2, +69, +262203, +70, +71, +2, +262187, +16, +72, +24, +262176, +73, +2, +14, +262187, +16, +87, +25, +262187, +14, +90, +1, +589849, +100, +14, +5, +0, +0, +0, +1, +0, +196635, +101, +100, +262176, +102, +0, +101, +262203, +102, +103, +0, +262167, +107, +14, +4, +262187, +14, +109, +0, +262187, +16, +163, +64, +262167, +185, +14, +3, +262176, +186, +1, +185, +262203, +186, +187, +1, +262203, +186, +188, +1, +262176, +197, +1, +14, +262172, +225, +7, +68, +262176, +226, +4, +225, +262203, +226, +227, +4, +196637, +229, +7, +196638, +230, +229, +262176, +231, +2, +230, +262203, +231, +232, +2, +262187, +16, +233, +0, +262176, +235, +2, +7, +262176, +238, +4, +7, +262187, +14, +240, +4062, +262187, +16, +257, +1, +262187, +16, +268, +26, +262176, +269, +2, +6, +262187, +6, +278, +1065353216, +262167, +280, +6, +3, +262176, +281, +7, +280, +589849, +288, +6, +5, +0, +0, +0, +1, +0, +196635, +289, +288, +262176, +290, +0, +289, +262203, +290, +291, +0, +262168, +306, +7, +4, +262172, +307, +6, +59, +393246, +308, +306, +7, +16, +307, +262176, +309, +2, +308, +262203, +309, +310, +2, +393260, +185, +311, +68, +90, +90, +327734, +2, +4, +0, +3, +131320, +5, +262203, +15, +189, +7, +262203, +15, +190, +7, +262203, +17, +191, +7, +262203, +15, +192, +7, +262203, +15, +193, +7, +262203, +15, +194, +7, +262203, +15, +195, +7, +262203, +15, +196, +7, +262203, +15, +200, +7, +262203, +15, +203, +7, +262203, +15, +205, +7, +262203, +17, +207, +7, +262203, +15, +209, +7, +262203, +15, +211, +7, +262203, +15, +213, +7, +262203, +15, +215, +7, +262203, +17, +241, +7, +262203, +17, +252, +7, +262203, +17, +261, +7, +262203, +60, +267, +7, +262203, +281, +282, +7, +327745, +197, +198, +187, +109, +262205, +14, +199, +198, +196670, +196, +199, +327745, +197, +201, +188, +109, +262205, +14, +202, +201, +196670, +200, +202, +262205, +14, +204, +189, +196670, +203, +204, +262205, +14, +206, +190, +196670, +205, +206, +262205, +16, +208, +191, +196670, +207, +208, +262205, +14, +210, +192, +196670, +209, +210, +262205, +14, +212, +193, +196670, +211, +212, +262205, +14, +214, +194, +196670, +213, +214, +262205, +14, +216, +195, +196670, +215, +216, +852025, +2, +217, +28, +196, +200, +203, +205, +207, +209, +211, +213, +215, +262205, +14, +218, +203, +196670, +189, +218, +262205, +14, +219, +205, +196670, +190, +219, +262205, +16, +220, +207, +196670, +191, +220, +262205, +14, +221, +209, +196670, +192, +221, +262205, +14, +222, +211, +196670, +193, +222, +262205, +14, +223, +213, +196670, +194, +223, +262205, +14, +224, +215, +196670, +195, +224, +262205, +14, +228, +194, +262205, +16, +234, +191, +393281, +235, +236, +232, +233, +234, +262205, +7, +237, +236, +327745, +238, +239, +227, +228, +196670, +239, +237, +196833, +90, +240, +262368, +90, +90, +109, +196670, +241, +233, +131321, +242, +131320, +242, +262390, +244, +245, +0, +131321, +246, +131320, +246, +262205, +16, +247, +241, +262268, +14, +248, +247, +327745, +73, +249, +71, +87, +262205, +14, +250, +249, +327856, +9, +251, +248, +250, +262394, +251, +243, +244, +131320, +243, +262205, +16, +253, +191, +262205, +14, +254, +193, +262268, +16, +255, +254, +262205, +16, +256, +241, +327808, +16, +258, +256, +257, +327812, +16, +259, +255, +258, +327808, +16, +260, +253, +259, +196670, +252, +260, +262205, +14, +262, +189, +262268, +16, +263, +262, +262205, +16, +264, +241, +327808, +16, +265, +263, +264, +327808, +16, +266, +265, +257, +196670, +261, +266, +327745, +269, +270, +71, +268, +262205, +6, +271, +270, +262205, +14, +272, +192, +262256, +6, +273, +272, +262205, +14, +274, +193, +262256, +6, +275, +274, +327816, +6, +276, +273, +275, +327813, +6, +277, +271, +276, +327809, +6, +279, +277, +278, +196670, +267, +279, +262205, +14, +283, +194, +327745, +238, +284, +227, +283, +262205, +7, +285, +284, +524367, +280, +286, +285, +285, +0, +1, +2, +262205, +6, +287, +267, +262205, +289, +292, +291, +262205, +16, +293, +261, +327775, +7, +294, +292, +293, +524367, +280, +295, +294, +294, +0, +1, +2, +327822, +280, +296, +295, +287, +327809, +280, +297, +286, +296, +196670, +282, +297, +262205, +16, +298, +252, +262205, +280, +299, +282, +393281, +235, +300, +232, +233, +298, +262205, +7, +301, +300, +589903, +7, +302, +301, +299, +4, +5, +6, +3, +196670, +300, +302, +131321, +245, +131320, +245, +262205, +16, +303, +241, +327808, +16, +304, +303, +257, +196670, +241, +304, +131321, +242, +131320, +244, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +327745, +60, +61, +11, +59, +262205, +6, +62, +61, +327866, +9, +64, +62, +63, +131326, +64, +65592, +327734, +2, +28, +0, +18, +196663, +15, +19, +196663, +15, +20, +196663, +15, +21, +196663, +15, +22, +196663, +17, +23, +196663, +15, +24, +196663, +15, +25, +196663, +15, +26, +196663, +15, +27, +131320, +29, +262205, +14, +67, +19, +196670, +26, +67, +327745, +73, +74, +71, +72, +262205, +14, +75, +74, +327814, +14, +76, +68, +75, +196670, +25, +76, +262205, +14, +77, +19, +327745, +73, +78, +71, +72, +262205, +14, +79, +78, +327817, +14, +80, +77, +79, +196670, +22, +80, +262205, +14, +81, +20, +327745, +73, +82, +71, +72, +262205, +14, +83, +82, +327812, +14, +84, +81, +83, +262205, +14, +85, +22, +327808, +14, +86, +84, +85, +196670, +21, +86, +327745, +73, +88, +71, +87, +262205, +14, +89, +88, +327808, +14, +91, +89, +90, +262205, +14, +92, +21, +327812, +14, +93, +92, +91, +196670, +21, +93, +262205, +14, +94, +19, +262205, +14, +95, +22, +327810, +14, +96, +94, +95, +327745, +73, +97, +71, +72, +262205, +14, +98, +97, +327814, +14, +99, +96, +98, +196670, +24, +99, +262205, +101, +104, +103, +262205, +14, +105, +21, +262268, +16, +106, +105, +327775, +107, +108, +104, +106, +327761, +14, +110, +108, +0, +196670, +27, +110, +262205, +14, +111, +21, +262205, +14, +112, +25, +327812, +14, +113, +111, +112, +262205, +14, +114, +24, +327808, +14, +115, +113, +114, +262268, +16, +116, +115, +196670, +23, +116, +65789, +65592, +327734, +2, +39, +0, +18, +196663, +15, +30, +196663, +15, +31, +196663, +15, +32, +196663, +15, +33, +196663, +17, +34, +196663, +15, +35, +196663, +15, +36, +196663, +15, +37, +196663, +15, +38, +131320, +40, +262205, +14, +117, +30, +196670, +37, +117, +327745, +73, +118, +71, +72, +262205, +14, +119, +118, +327814, +14, +120, +68, +119, +196670, +36, +120, +262205, +14, +121, +30, +327745, +73, +122, +71, +72, +262205, +14, +123, +122, +327817, +14, +124, +121, +123, +196670, +33, +124, +262205, +14, +125, +31, +327745, +73, +126, +71, +72, +262205, +14, +127, +126, +327812, +14, +128, +125, +127, +262205, +14, +129, +33, +327808, +14, +130, +128, +129, +196670, +32, +130, +262205, +14, +131, +30, +262205, +14, +132, +33, +327810, +14, +133, +131, +132, +327745, +73, +134, +71, +72, +262205, +14, +135, +134, +327814, +14, +136, +133, +135, +196670, +35, +136, +262205, +101, +137, +103, +262205, +14, +138, +32, +262268, +16, +139, +138, +327775, +107, +140, +137, +139, +327761, +14, +141, +140, +0, +196670, +38, +141, +262205, +14, +142, +32, +262205, +14, +143, +36, +327812, +14, +144, +142, +143, +262205, +14, +145, +35, +327808, +14, +146, +144, +145, +262268, +16, +147, +146, +196670, +34, +147, +65789, +65592, +327734, +2, +48, +0, +41, +196663, +15, +42, +196663, +15, +43, +196663, +15, +44, +196663, +15, +45, +196663, +15, +46, +196663, +15, +47, +131320, +49, +262205, +14, +148, +43, +327812, +14, +149, +68, +148, +262205, +14, +150, +42, +327808, +14, +151, +149, +150, +196670, +44, +151, +327745, +73, +152, +71, +72, +262205, +14, +153, +152, +327814, +14, +154, +68, +153, +196670, +45, +154, +262205, +101, +155, +103, +262205, +14, +156, +44, +262268, +16, +157, +156, +327775, +107, +158, +155, +157, +327761, +14, +159, +158, +0, +196670, +47, +159, +262205, +14, +160, +44, +262205, +14, +161, +45, +327812, +14, +162, +160, +161, +196670, +46, +162, +65789, +65592, +327734, +2, +57, +0, +50, +196663, +17, +51, +196663, +17, +52, +196663, +17, +53, +196663, +15, +54, +196663, +17, +55, +196663, +15, +56, +131320, +58, +262205, +16, +164, +52, +327812, +16, +165, +163, +164, +262205, +16, +166, +51, +327808, +16, +167, +165, +166, +196670, +53, +167, +327745, +73, +168, +71, +87, +262205, +14, +169, +168, +327808, +14, +170, +169, +90, +262268, +16, +171, +170, +262205, +16, +172, +53, +327812, +16, +173, +172, +171, +196670, +53, +173, +327745, +73, +174, +71, +72, +262205, +14, +175, +174, +327814, +14, +176, +68, +175, +196670, +54, +176, +262205, +101, +177, +103, +262205, +16, +178, +53, +327775, +107, +179, +177, +178, +327761, +14, +180, +179, +0, +196670, +56, +180, +262205, +16, +181, +53, +262205, +14, +182, +54, +262268, +16, +183, +182, +327812, +16, +184, +181, +183, +196670, +55, +184, +65789, +65592, +}; +const std::vector depth_hair_data = {119734787, +65536, +524289, +364, +0, +131089, +1, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +655375, +4, +4, +1852399981, +0, +222, +249, +267, +291, +363, +196624, +4, +7, +196624, +4, +9, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +524293, +12, +1801675088, +1634692166, +1850291316, +1767206772, +1982362734, +3880038, +262149, +11, +1818318454, +25973, +589829, +17, +1634758229, +1767205731, +1850307694, +1816555380, +880042351, +993097000, +0, +262149, +16, +1818318453, +25973, +655365, +25, +1801675088, +1735287124, +1098149477, +1866687598, +1634887030, +1982358887, +1715155814, +15153, +262149, +23, +1735287156, +7630437, +327685, +24, +1702260579, +1701273970, +0, +393221, +29, +1416914247, +1701277281, +1965585518, +15153, +393221, +28, +1801675120, +1632920677, +1852139374, +116, +393221, +33, +1131701575, +1919252079, +677734241, +3879285, +393221, +32, +1801675120, +1866687589, +1634887030, +25959, +655365, +41, +1886220099, +1130722421, +1919252079, +677734241, +993158774, +993158774, +993158774, +0, +196613, +38, +12400, +196613, +39, +12656, +327685, +40, +1702390128, +1668238444, +0, +262149, +43, +1702132066, +51, +262149, +52, +1702132066, +50, +262149, +59, +1702132066, +49, +262149, +66, +1702132066, +48, +262149, +124, +1634886000, +109, +262149, +129, +1634886000, +109, +262149, +139, +1634886000, +109, +327685, +146, +1936617283, +1953390964, +115, +393222, +146, +0, +1466785639, +1684828783, +0, +393222, +146, +1, +1450008423, +1350002025, +6975346, +458758, +146, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +146, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +146, +4, +1165385575, +25977, +327686, +146, +5, +1986420583, +7761734, +524294, +146, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +146, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +146, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +146, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +146, +10, +1632460647, +1633045364, +6649196, +458758, +146, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +146, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +146, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +146, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +146, +15, +1767333735, +2053722990, +101, +458758, +146, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +146, +17, +1415733095, +1416522088, +28777, +458758, +146, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +146, +19, +1181114215, +1766617697, +7628903, +393222, +146, +20, +1416191847, +1399350117, +77, +458758, +146, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +146, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +146, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +146, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +146, +25, +1214668647, +1265789281, +12915, +393222, +146, +26, +1214668647, +1165125985, +12920, +589830, +146, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +148, +0, +262149, +171, +1768173680, +29811, +262149, +176, +1768173936, +29811, +327685, +181, +1919508840, +1952737623, +104, +262149, +188, +1937012079, +6644841, +262149, +201, +1852270963, +0, +262149, +208, +1147954546, +7631721, +327685, +220, +1785688688, +1936683103, +0, +393221, +222, +1180658791, +1130848626, +1685221231, +0, +327685, +242, +1987212643, +1668505445, +6646881, +262149, +249, +1735287156, +7630437, +393221, +252, +1700948326, +1634885490, +1937074532, +0, +327685, +258, +1702260579, +1701273970, +0, +262149, +267, +829436016, +0, +262149, +268, +1634886000, +109, +262149, +271, +1634886000, +109, +262149, +274, +1634886000, +109, +262149, +278, +1752198241, +97, +327685, +291, +1734439494, +1869377347, +114, +393221, +295, +1919112054, +1097753957, +1701995620, +29555, +262149, +299, +1885684853, +26740, +327685, +303, +1885684853, +1345349748, +7759218, +524293, +306, +1917212498, +1701668705, +1698985070, +1936225392, +1954047316, +6648437, +327685, +330, +1885684853, +1345415284, +7759218, +327685, +351, +1885684853, +1345480820, +7759218, +262149, +363, +1953523044, +104, +262216, +146, +0, +5, +327752, +146, +0, +35, +0, +327752, +146, +0, +7, +16, +262216, +146, +1, +5, +327752, +146, +1, +35, +64, +327752, +146, +1, +7, +16, +262216, +146, +2, +5, +327752, +146, +2, +35, +128, +327752, +146, +2, +7, +16, +262216, +146, +3, +5, +327752, +146, +3, +35, +192, +327752, +146, +3, +7, +16, +327752, +146, +4, +35, +256, +327752, +146, +5, +35, +268, +327752, +146, +6, +35, +272, +327752, +146, +7, +35, +288, +327752, +146, +8, +35, +304, +327752, +146, +9, +35, +320, +327752, +146, +10, +35, +336, +327752, +146, +11, +35, +352, +327752, +146, +12, +35, +356, +327752, +146, +13, +35, +360, +327752, +146, +14, +35, +364, +327752, +146, +15, +35, +368, +327752, +146, +16, +35, +384, +327752, +146, +17, +35, +388, +327752, +146, +18, +35, +392, +327752, +146, +19, +35, +396, +327752, +146, +20, +35, +400, +327752, +146, +21, +35, +404, +327752, +146, +22, +35, +408, +327752, +146, +23, +35, +412, +327752, +146, +24, +35, +416, +327752, +146, +25, +35, +420, +327752, +146, +26, +35, +424, +262216, +146, +27, +5, +327752, +146, +27, +35, +432, +327752, +146, +27, +7, +16, +196679, +146, +2, +262215, +148, +34, +0, +262215, +148, +33, +16, +262215, +222, +11, +15, +262215, +249, +30, +2, +262215, +267, +30, +1, +262215, +291, +30, +0, +262215, +306, +34, +0, +262215, +306, +33, +13, +262215, +363, +30, +0, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +262165, +9, +32, +0, +262177, +10, +9, +8, +262176, +14, +7, +9, +262177, +15, +7, +14, +262167, +19, +6, +3, +262176, +20, +7, +19, +262176, +21, +7, +6, +327713, +22, +9, +20, +21, +262177, +27, +19, +14, +262177, +31, +6, +14, +262167, +35, +6, +2, +262176, +36, +7, +35, +393249, +37, +6, +36, +36, +36, +262187, +9, +44, +0, +262187, +6, +47, +1132396544, +262187, +9, +50, +255, +262187, +9, +53, +1, +262187, +9, +60, +2, +262187, +9, +67, +3, +262165, +74, +32, +1, +262187, +74, +75, +24, +262187, +74, +78, +16, +262187, +74, +82, +8, +262187, +9, +90, +4278190080, +262187, +9, +96, +16711680, +262187, +9, +102, +65280, +262187, +6, +115, +1056964608, +262187, +6, +128, +1073741824, +262187, +6, +134, +1065353216, +262168, +145, +7, +4, +1966110, +146, +145, +145, +145, +145, +19, +6, +7, +7, +7, +7, +7, +6, +6, +6, +6, +7, +6, +6, +6, +6, +74, +74, +74, +74, +6, +6, +6, +145, +262176, +147, +2, +146, +262203, +147, +148, +2, +262187, +74, +149, +15, +262176, +150, +2, +7, +262187, +6, +161, +3212836864, +131092, +186, +262176, +187, +7, +186, +262187, +6, +192, +0, +262167, +198, +186, +2, +262176, +221, +1, +7, +262203, +221, +222, +1, +262176, +223, +1, +6, +262176, +227, +2, +6, +262187, +74, +243, +17, +262203, +221, +249, +1, +262187, +74, +254, +14, +262187, +74, +259, +21, +262176, +260, +2, +74, +262187, +74, +263, +0, +262203, +221, +267, +1, +262187, +74, +280, +11, +262176, +290, +3, +6, +262203, +290, +291, +3, +262167, +293, +9, +2, +262176, +294, +7, +293, +589849, +304, +9, +1, +0, +1, +0, +2, +33, +262176, +305, +0, +304, +262203, +305, +306, +0, +262167, +308, +74, +2, +262167, +310, +74, +3, +262176, +315, +11, +9, +262187, +6, +320, +1065017672, +262187, +74, +333, +1, +262187, +74, +354, +2, +262203, +223, +363, +1, +327734, +2, +4, +0, +3, +131320, +5, +262203, +8, +220, +7, +262203, +21, +242, +7, +262203, +21, +252, +7, +262203, +21, +258, +7, +262203, +36, +268, +7, +262203, +36, +271, +7, +262203, +36, +274, +7, +262203, +21, +278, +7, +262203, +294, +295, +7, +262203, +14, +299, +7, +262203, +14, +303, +7, +262203, +14, +318, +7, +262203, +14, +330, +7, +262203, +14, +340, +7, +262203, +14, +351, +7, +327745, +223, +224, +222, +44, +262205, +6, +225, +224, +327813, +6, +226, +128, +225, +393281, +227, +228, +148, +149, +60, +262205, +6, +229, +228, +327813, +6, +230, +226, +229, +327811, +6, +231, +230, +134, +327745, +223, +232, +222, +53, +262205, +6, +233, +232, +327813, +6, +234, +128, +233, +393281, +227, +235, +148, +149, +67, +262205, +6, +236, +235, +327813, +6, +237, +234, +236, +327811, +6, +238, +134, +237, +327745, +223, +239, +222, +60, +262205, +6, +240, +239, +458832, +7, +241, +231, +238, +240, +134, +196670, +220, +241, +196670, +242, +134, +327745, +227, +244, +148, +243, +262205, +6, +245, +244, +327866, +186, +246, +245, +192, +196855, +248, +0, +262394, +246, +247, +248, +131320, +247, +327745, +223, +250, +249, +67, +262205, +6, +251, +250, +196670, +242, +251, +131321, +248, +131320, +248, +262205, +6, +253, +242, +327745, +227, +255, +148, +254, +262205, +6, +256, +255, +327813, +6, +257, +253, +256, +196670, +252, +257, +196670, +258, +134, +327745, +260, +261, +148, +259, +262205, +74, +262, +261, +327851, +186, +264, +262, +263, +196855, +266, +0, +262394, +264, +265, +266, +131320, +265, +262205, +7, +269, +267, +458831, +35, +270, +269, +269, +0, +1, +196670, +268, +270, +262205, +7, +272, +267, +458831, +35, +273, +272, +272, +2, +3, +196670, +271, +273, +262205, +7, +275, +220, +458831, +35, +276, +275, +275, +0, +1, +196670, +274, +276, +458809, +6, +277, +41, +268, +271, +274, +196670, +258, +277, +131321, +266, +131320, +266, +262205, +6, +279, +258, +327745, +227, +281, +148, +280, +262205, +6, +282, +281, +327813, +6, +283, +279, +282, +196670, +278, +283, +262205, +6, +284, +278, +327745, +227, +285, +148, +75, +262205, +6, +286, +285, +327864, +186, +287, +284, +286, +196855, +289, +0, +262394, +287, +288, +289, +131320, +288, +196670, +291, +134, +65789, +131320, +289, +262205, +7, +296, +222, +458831, +35, +297, +296, +296, +0, +1, +262253, +293, +298, +297, +196670, +295, +298, +327745, +223, +300, +222, +60, +262205, +6, +301, +300, +262268, +9, +302, +301, +196670, +299, +302, +262205, +293, +307, +295, +262268, +308, +309, +307, +327761, +74, +311, +309, +0, +327761, +74, +312, +309, +1, +393296, +310, +313, +311, +312, +263, +262205, +9, +314, +299, +393276, +315, +316, +306, +313, +44, +458989, +9, +317, +316, +53, +44, +314, +196670, +303, +317, +262205, +6, +319, +278, +327866, +186, +321, +319, +320, +196855, +323, +0, +262394, +321, +322, +325, +131320, +322, +262205, +9, +324, +299, +196670, +318, +324, +131321, +323, +131320, +325, +262205, +9, +326, +299, +262205, +9, +327, +303, +458764, +9, +328, +1, +41, +326, +327, +196670, +318, +328, +131321, +323, +131320, +323, +262205, +9, +329, +318, +196670, +299, +329, +262205, +293, +331, +295, +262268, +308, +332, +331, +327761, +74, +334, +332, +0, +327761, +74, +335, +332, +1, +393296, +310, +336, +334, +335, +333, +262205, +9, +337, +299, +393276, +315, +338, +306, +336, +44, +458989, +9, +339, +338, +53, +44, +337, +196670, +330, +339, +262205, +6, +341, +278, +327866, +186, +342, +341, +320, +196855, +344, +0, +262394, +342, +343, +346, +131320, +343, +262205, +9, +345, +299, +196670, +340, +345, +131321, +344, +131320, +346, +262205, +9, +347, +299, +262205, +9, +348, +330, +458764, +9, +349, +1, +41, +347, +348, +196670, +340, +349, +131321, +344, +131320, +344, +262205, +9, +350, +340, +196670, +299, +350, +262205, +293, +352, +295, +262268, +308, +353, +352, +327761, +74, +355, +353, +0, +327761, +74, +356, +353, +1, +393296, +310, +357, +355, +356, +354, +262205, +9, +358, +299, +393276, +315, +359, +306, +357, +44, +458989, +9, +360, +359, +53, +44, +358, +196670, +351, +360, +262205, +6, +361, +278, +327811, +6, +362, +134, +361, +196670, +291, +362, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +262203, +14, +43, +7, +262203, +14, +52, +7, +262203, +14, +59, +7, +262203, +14, +66, +7, +327745, +21, +45, +11, +44, +262205, +6, +46, +45, +327813, +6, +48, +46, +47, +262253, +9, +49, +48, +327879, +9, +51, +49, +50, +196670, +43, +51, +327745, +21, +54, +11, +53, +262205, +6, +55, +54, +327813, +6, +56, +55, +47, +262253, +9, +57, +56, +327879, +9, +58, +57, +50, +196670, +52, +58, +327745, +21, +61, +11, +60, +262205, +6, +62, +61, +327813, +6, +63, +62, +47, +262253, +9, +64, +63, +327879, +9, +65, +64, +50, +196670, +59, +65, +327745, +21, +68, +11, +67, +262205, +6, +69, +68, +327813, +6, +70, +69, +47, +262253, +9, +71, +70, +327879, +9, +72, +71, +50, +196670, +66, +72, +262205, +9, +73, +43, +327876, +9, +76, +73, +75, +262205, +9, +77, +52, +327876, +9, +79, +77, +78, +327877, +9, +80, +76, +79, +262205, +9, +81, +59, +327876, +9, +83, +81, +82, +327877, +9, +84, +80, +83, +262205, +9, +85, +66, +327877, +9, +86, +84, +85, +131326, +86, +65592, +327734, +7, +17, +0, +15, +196663, +14, +16, +131320, +18, +262205, +9, +89, +16, +327879, +9, +91, +89, +90, +327874, +9, +92, +91, +75, +262256, +6, +93, +92, +327816, +6, +94, +93, +47, +262205, +9, +95, +16, +327879, +9, +97, +95, +96, +327874, +9, +98, +97, +78, +262256, +6, +99, +98, +327816, +6, +100, +99, +47, +262205, +9, +101, +16, +327879, +9, +103, +101, +102, +327874, +9, +104, +103, +82, +262256, +6, +105, +104, +327816, +6, +106, +105, +47, +262205, +9, +107, +16, +327879, +9, +108, +107, +50, +262256, +6, +109, +108, +327816, +6, +110, +109, +47, +458832, +7, +111, +94, +100, +106, +110, +131326, +111, +65592, +327734, +9, +25, +0, +22, +196663, +20, +23, +196663, +21, +24, +131320, +26, +262203, +8, +124, +7, +262205, +19, +114, +23, +327822, +19, +116, +114, +115, +393296, +19, +117, +115, +115, +115, +327809, +19, +118, +116, +117, +262205, +6, +119, +24, +327761, +6, +120, +118, +0, +327761, +6, +121, +118, +1, +327761, +6, +122, +118, +2, +458832, +7, +123, +120, +121, +122, +119, +196670, +124, +123, +327737, +9, +125, +12, +124, +131326, +125, +65592, +327734, +19, +29, +0, +27, +196663, +14, +28, +131320, +30, +262203, +14, +129, +7, +262205, +9, +130, +28, +196670, +129, +130, +327737, +7, +131, +17, +129, +524367, +19, +132, +131, +131, +0, +1, +2, +327822, +19, +133, +132, +128, +393296, +19, +135, +134, +134, +134, +327811, +19, +136, +133, +135, +131326, +136, +65592, +327734, +6, +33, +0, +31, +196663, +14, +32, +131320, +34, +262203, +14, +139, +7, +262205, +9, +140, +32, +196670, +139, +140, +327737, +7, +141, +17, +139, +327761, +6, +142, +141, +3, +131326, +142, +65592, +327734, +6, +41, +0, +37, +196663, +36, +38, +196663, +36, +39, +196663, +36, +40, +131320, +42, +262203, +21, +171, +7, +262203, +21, +176, +7, +262203, +21, +181, +7, +262203, +187, +188, +7, +262203, +21, +201, +7, +262203, +21, +202, +7, +262203, +21, +208, +7, +327745, +150, +151, +148, +149, +262205, +7, +152, +151, +458831, +35, +153, +152, +152, +0, +1, +262205, +35, +154, +38, +327813, +35, +155, +154, +153, +196670, +38, +155, +327745, +150, +156, +148, +149, +262205, +7, +157, +156, +458831, +35, +158, +157, +157, +0, +1, +262205, +35, +159, +39, +327813, +35, +160, +159, +158, +196670, +39, +160, +327745, +21, +162, +40, +53, +262205, +6, +163, +162, +327813, +6, +164, +163, +161, +327745, +21, +165, +40, +53, +196670, +165, +164, +327745, +150, +166, +148, +149, +262205, +7, +167, +166, +458831, +35, +168, +167, +167, +0, +1, +262205, +35, +169, +40, +327813, +35, +170, +169, +168, +196670, +40, +170, +262205, +35, +172, +38, +262205, +35, +173, +40, +327811, +35, +174, +172, +173, +393228, +6, +175, +1, +66, +174, +196670, +171, +175, +262205, +35, +177, +39, +262205, +35, +178, +40, +327811, +35, +179, +177, +178, +393228, +6, +180, +1, +66, +179, +196670, +176, +180, +262205, +35, +182, +38, +262205, +35, +183, +39, +327811, +35, +184, +182, +183, +393228, +6, +185, +1, +66, +184, +196670, +181, +185, +262205, +6, +189, +181, +262205, +6, +190, +171, +458764, +6, +191, +1, +48, +189, +190, +327866, +186, +193, +191, +192, +262205, +6, +194, +181, +262205, +6, +195, +176, +458764, +6, +196, +1, +48, +194, +195, +327866, +186, +197, +196, +192, +327760, +198, +199, +193, +197, +262298, +186, +200, +199, +196670, +188, +200, +262205, +186, +203, +188, +196855, +205, +0, +262394, +203, +204, +206, +131320, +204, +196670, +202, +161, +131321, +205, +131320, +206, +196670, +202, +134, +131321, +205, +131320, +205, +262205, +6, +207, +202, +196670, +201, +207, +262205, +6, +209, +201, +262205, +6, +210, +171, +262205, +6, +211, +176, +458764, +6, +212, +1, +37, +210, +211, +524300, +6, +213, +1, +43, +212, +192, +134, +327813, +6, +214, +209, +213, +196670, +208, +214, +262205, +6, +215, +208, +327809, +6, +216, +215, +134, +327813, +6, +217, +216, +115, +131326, +217, +65592, +}; +const std::vector resolve_depth = {119734787, +65536, +524289, +44, +0, +131089, +1, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +4, +4, +1852399981, +0, +13, +36, +196624, +4, +7, +196624, +4, +12, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +393221, +9, +1919112054, +1097753957, +1701995620, +29555, +393221, +13, +1180658791, +1130848626, +1685221231, +0, +262149, +20, +1885684853, +26740, +524293, +24, +1734439494, +1953391981, +1953523012, +1700033384, +1920300152, +101, +393221, +36, +1180658791, +1147625842, +1752461413, +0, +327685, +41, +1936617283, +1953390964, +115, +393222, +41, +0, +1466785639, +1684828783, +0, +393222, +41, +1, +1450008423, +1350002025, +6975346, +458758, +41, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +41, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +41, +4, +1165385575, +25977, +327686, +41, +5, +1986420583, +7761734, +524294, +41, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +41, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +41, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +41, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +41, +10, +1632460647, +1633045364, +6649196, +458758, +41, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +41, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +41, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +41, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +41, +15, +1767333735, +2053722990, +101, +458758, +41, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +41, +17, +1415733095, +1416522088, +28777, +458758, +41, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +41, +19, +1181114215, +1766617697, +7628903, +393222, +41, +20, +1416191847, +1399350117, +77, +458758, +41, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +41, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +41, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +41, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +41, +25, +1214668647, +1265789281, +12915, +393222, +41, +26, +1214668647, +1165125985, +12920, +589830, +41, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +43, +0, +262215, +13, +11, +15, +262215, +24, +34, +0, +262215, +24, +33, +13, +262215, +36, +11, +22, +262216, +41, +0, +5, +327752, +41, +0, +35, +0, +327752, +41, +0, +7, +16, +262216, +41, +1, +5, +327752, +41, +1, +35, +64, +327752, +41, +1, +7, +16, +262216, +41, +2, +5, +327752, +41, +2, +35, +128, +327752, +41, +2, +7, +16, +262216, +41, +3, +5, +327752, +41, +3, +35, +192, +327752, +41, +3, +7, +16, +327752, +41, +4, +35, +256, +327752, +41, +5, +35, +268, +327752, +41, +6, +35, +272, +327752, +41, +7, +35, +288, +327752, +41, +8, +35, +304, +327752, +41, +9, +35, +320, +327752, +41, +10, +35, +336, +327752, +41, +11, +35, +352, +327752, +41, +12, +35, +356, +327752, +41, +13, +35, +360, +327752, +41, +14, +35, +364, +327752, +41, +15, +35, +368, +327752, +41, +16, +35, +384, +327752, +41, +17, +35, +388, +327752, +41, +18, +35, +392, +327752, +41, +19, +35, +396, +327752, +41, +20, +35, +400, +327752, +41, +21, +35, +404, +327752, +41, +22, +35, +408, +327752, +41, +23, +35, +412, +327752, +41, +24, +35, +416, +327752, +41, +25, +35, +420, +327752, +41, +26, +35, +424, +262216, +41, +27, +5, +327752, +41, +27, +35, +432, +327752, +41, +27, +7, +16, +196679, +41, +2, +262215, +43, +34, +0, +262215, +43, +33, +16, +131091, +2, +196641, +3, +2, +262165, +6, +32, +1, +262167, +7, +6, +2, +262176, +8, +7, +7, +196630, +10, +32, +262167, +11, +10, +4, +262176, +12, +1, +11, +262203, +12, +13, +1, +262167, +14, +10, +2, +262165, +18, +32, +0, +262176, +19, +7, +18, +262187, +18, +21, +0, +589849, +22, +18, +1, +0, +1, +0, +2, +33, +262176, +23, +0, +22, +262203, +23, +24, +0, +262187, +6, +27, +2, +262167, +28, +6, +3, +262167, +32, +18, +4, +262176, +35, +3, +10, +262203, +35, +36, +3, +262168, +39, +11, +4, +262167, +40, +10, +3, +1966110, +41, +39, +39, +39, +39, +40, +10, +11, +11, +11, +11, +11, +10, +10, +10, +10, +11, +10, +10, +10, +10, +6, +6, +6, +6, +10, +10, +10, +39, +262176, +42, +2, +41, +262203, +42, +43, +2, +327734, +2, +4, +0, +3, +131320, +5, +262203, +8, +9, +7, +262203, +19, +20, +7, +262205, +11, +15, +13, +458831, +14, +16, +15, +15, +0, +1, +262254, +7, +17, +16, +196670, +9, +17, +196670, +20, +21, +262205, +22, +25, +24, +262205, +7, +26, +9, +327761, +6, +29, +26, +0, +327761, +6, +30, +26, +1, +393296, +28, +31, +29, +30, +27, +327778, +32, +33, +25, +31, +327761, +18, +34, +33, +0, +196670, +20, +34, +262205, +18, +37, +20, +262268, +10, +38, +37, +196670, +36, +38, +65789, +65592, +}; +const std::vector fillcolors_hair_data = {119734787, +65536, +524289, +914, +0, +131089, +1, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +720911, +4, +4, +1852399981, +0, +746, +786, +803, +827, +881, +913, +196624, +4, +7, +196624, +4, +9, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +524293, +12, +1801675088, +1634692166, +1850291316, +1767206772, +1982362734, +3880038, +262149, +11, +1818318454, +25973, +589829, +17, +1634758229, +1767205731, +1850307694, +1816555380, +880042351, +993097000, +0, +262149, +16, +1818318453, +25973, +655365, +25, +1801675088, +1735287124, +1098149477, +1866687598, +1634887030, +1982358887, +1715155814, +15153, +262149, +23, +1735287156, +7630437, +327685, +24, +1702260579, +1701273970, +0, +393221, +29, +1416914247, +1701277281, +1965585518, +15153, +393221, +28, +1801675120, +1632920677, +1852139374, +116, +393221, +33, +1131701575, +1919252079, +677734241, +3879285, +393221, +32, +1801675120, +1866687589, +1634887030, +25959, +655365, +41, +1886220099, +1130722421, +1919252079, +677734241, +993158774, +993158774, +993158774, +0, +196613, +38, +12400, +196613, +39, +12656, +327685, +40, +1702390128, +1668238444, +0, +524293, +46, +1886220099, +1399157877, +1868849512, +1719019639, +828783411, +59, +327685, +44, +1819438967, +1936674916, +0, +262149, +45, +1752198241, +97, +589829, +50, +1886220099, +1399157877, +1819307369, +1634227045, +678915940, +993224310, +3879270, +327685, +48, +1819438967, +1936674916, +0, +262149, +49, +1752198241, +97, +786437, +58, +1886220099, +1214608501, +1400007009, +1768186216, +1982359406, +1983591270, +1983591270, +1715156070, +1719024433, +15155, +262149, +53, +1936674921, +0, +327685, +54, +1851872361, +1953391975, +0, +262149, +55, +2019906665, +0, +327685, +56, +1970236769, +1766618222, +7628903, +262149, +57, +1869377379, +114, +720901, +65, +1886218579, +1632134508, +1750299241, +1852400737, +1719019623, +1719024435, +1719024435, +828783412, +59, +262149, +61, +1936674921, +0, +327685, +62, +1851872361, +1953391975, +0, +262149, +63, +2019906665, +0, +327685, +64, +1970236769, +1766618222, +7628903, +393221, +72, +1098147143, +1701995620, +1982362483, +3879529, +327685, +71, +1684291958, +1936942450, +0, +262149, +74, +1702132066, +51, +262149, +83, +1702132066, +50, +262149, +90, +1702132066, +49, +262149, +97, +1702132066, +48, +262149, +154, +1634886000, +109, +262149, +159, +1634886000, +109, +262149, +169, +1634886000, +109, +327685, +176, +1936617283, +1953390964, +115, +393222, +176, +0, +1466785639, +1684828783, +0, +393222, +176, +1, +1450008423, +1350002025, +6975346, +458758, +176, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +176, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +176, +4, +1165385575, +25977, +327686, +176, +5, +1986420583, +7761734, +524294, +176, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +176, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +176, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +176, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +176, +10, +1632460647, +1633045364, +6649196, +458758, +176, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +176, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +176, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +176, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +176, +15, +1767333735, +2053722990, +101, +458758, +176, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +176, +17, +1415733095, +1416522088, +28777, +458758, +176, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +176, +19, +1181114215, +1766617697, +7628903, +393222, +176, +20, +1416191847, +1399350117, +77, +458758, +176, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +176, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +176, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +176, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +176, +25, +1214668647, +1265789281, +12915, +393222, +176, +26, +1214668647, +1165125985, +12920, +589830, +176, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +178, +0, +262149, +201, +1768173680, +29811, +262149, +206, +1768173936, +29811, +327685, +211, +1919508840, +1952737623, +104, +262149, +218, +1937012079, +6644841, +262149, +231, +1852270963, +0, +262149, +238, +1147954546, +7631721, +393221, +250, +1785688688, +1282633552, +1952999273, +0, +262149, +269, +1400399220, +77, +262149, +279, +1953523044, +104, +262149, +285, +1769173093, +7237484, +393221, +289, +1953523044, +1919311720, +1701668705, +29806, +393221, +292, +1635020660, +1702322028, +1952999273, +0, +458757, +293, +1970236769, +1766618222, +1601464423, +1919508840, +0, +196613, +295, +30820, +196613, +305, +31076, +262149, +313, +1702521203, +0, +262149, +315, +1835493747, +97, +196613, +319, +7370853, +262149, +335, +1734960503, +29800, +327685, +346, +1953523044, +1213027176, +7498081, +393221, +349, +1919508808, +1684105299, +1632466799, +112, +393221, +353, +1634951015, +1768902765, +1816360046, +7368033, +393221, +371, +1953523044, +1836277608, +1852403536, +116, +327685, +389, +1953523044, +1634885480, +6645614, +327685, +394, +1181578606, +1919246953, +115, +458757, +433, +1970236769, +1766618222, +1601464423, +1852138355, +101, +393221, +439, +1785688688, +1282633552, +1952999273, +0, +262149, +456, +1400399220, +77, +262149, +466, +1953523044, +104, +262149, +472, +1769173093, +7237484, +393221, +475, +1953523044, +1919311720, +1701668705, +29806, +458757, +478, +1970236769, +1766618222, +1601464423, +1852138355, +101, +327685, +479, +1953523044, +1213027176, +7498081, +393221, +488, +1953523044, +1836277608, +1852403536, +116, +327685, +503, +1953523044, +1634885480, +6645614, +327685, +508, +1181578606, +1919246953, +115, +458757, +525, +1970236769, +1766618222, +1601464423, +1919508840, +0, +327685, +534, +1702060386, +1869377347, +114, +327685, +539, +1684955506, +1818326623, +25973, +196613, +540, +24907, +196613, +544, +25675, +196613, +547, +3240779, +196613, +550, +3242053, +196613, +553, +3306315, +196613, +557, +3307589, +327685, +561, +1751607660, +1936674932, +0, +327685, +565, +1734954102, +1766093928, +114, +262149, +570, +1702446454, +7498052, +262149, +578, +1735287156, +7630437, +262149, +581, +1416851299, +76, +262149, +585, +1416522099, +76, +262149, +591, +1717987684, +6648693, +262149, +593, +1752198241, +97, +262149, +601, +1416851299, +19538, +262149, +604, +1416522099, +19538, +262149, +606, +1416851299, +69, +262149, +610, +1416522099, +69, +327685, +616, +1416851299, +1918848082, +7630703, +327685, +628, +1416522099, +1918848082, +7630703, +393221, +634, +1667592307, +1918987381, +1869574751, +116, +327685, +643, +1416851299, +1952402514, +28777, +327685, +656, +1416522099, +1952402514, +28777, +393221, +662, +1667592307, +1918987381, +1885959263, +0, +262149, +671, +1819231094, +29295, +327685, +713, +1702060386, +1869377347, +114, +196613, +717, +25675, +262149, +720, +1819231094, +29295, +327685, +731, +1684291950, +1936942450, +0, +327685, +744, +1785688688, +1936683103, +0, +393221, +746, +1180658791, +1130848626, +1685221231, +0, +327685, +765, +1819438967, +1869635428, +115, +327685, +779, +1987212643, +1668505445, +6646881, +262149, +786, +1735287156, +7630437, +393221, +789, +1700948326, +1634885490, +1937074532, +0, +327685, +794, +1702260579, +1701273970, +0, +262149, +803, +829436016, +0, +262149, +804, +1634886000, +109, +262149, +807, +1634886000, +109, +262149, +810, +1634886000, +109, +262149, +814, +1752198241, +97, +327685, +827, +1734439494, +1869377347, +114, +393221, +830, +1919112054, +1097753957, +1701995620, +29555, +393221, +834, +1734439526, +1953391981, +1701080649, +120, +262149, +835, +1634886000, +109, +262149, +838, +1885684853, +26740, +262149, +842, +1885684853, +3172468, +524293, +845, +1734439494, +1953391981, +1953523012, +1700033384, +1920300152, +101, +262149, +855, +1885684853, +3238004, +262149, +863, +1885684853, +3303540, +327685, +871, +1970236769, +1766618222, +7628903, +262149, +873, +1634886000, +109, +262149, +876, +1634886000, +109, +262149, +880, +1869377379, +114, +327685, +881, +1634890867, +1866687598, +7499628, +262149, +882, +1634886000, +109, +262149, +885, +1634886000, +109, +262149, +888, +1634886000, +109, +262149, +889, +1634886000, +109, +262149, +891, +1634886000, +109, +262149, +895, +1819231093, +29295, +262149, +902, +1634886000, +109, +262149, +913, +1953523044, +104, +262216, +176, +0, +5, +327752, +176, +0, +35, +0, +327752, +176, +0, +7, +16, +262216, +176, +1, +5, +327752, +176, +1, +35, +64, +327752, +176, +1, +7, +16, +262216, +176, +2, +5, +327752, +176, +2, +35, +128, +327752, +176, +2, +7, +16, +262216, +176, +3, +5, +327752, +176, +3, +35, +192, +327752, +176, +3, +7, +16, +327752, +176, +4, +35, +256, +327752, +176, +5, +35, +268, +327752, +176, +6, +35, +272, +327752, +176, +7, +35, +288, +327752, +176, +8, +35, +304, +327752, +176, +9, +35, +320, +327752, +176, +10, +35, +336, +327752, +176, +11, +35, +352, +327752, +176, +12, +35, +356, +327752, +176, +13, +35, +360, +327752, +176, +14, +35, +364, +327752, +176, +15, +35, +368, +327752, +176, +16, +35, +384, +327752, +176, +17, +35, +388, +327752, +176, +18, +35, +392, +327752, +176, +19, +35, +396, +327752, +176, +20, +35, +400, +327752, +176, +21, +35, +404, +327752, +176, +22, +35, +408, +327752, +176, +23, +35, +412, +327752, +176, +24, +35, +416, +327752, +176, +25, +35, +420, +327752, +176, +26, +35, +424, +262216, +176, +27, +5, +327752, +176, +27, +35, +432, +327752, +176, +27, +7, +16, +196679, +176, +2, +262215, +178, +34, +0, +262215, +178, +33, +16, +262215, +349, +34, +0, +262215, +349, +33, +3, +262215, +353, +34, +0, +262215, +353, +33, +19, +262215, +746, +11, +15, +262215, +786, +30, +2, +262215, +803, +30, +1, +262215, +827, +30, +0, +262215, +845, +34, +0, +262215, +845, +33, +13, +262215, +881, +30, +3, +262215, +913, +30, +0, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +262165, +9, +32, +0, +262177, +10, +9, +8, +262176, +14, +7, +9, +262177, +15, +7, +14, +262167, +19, +6, +3, +262176, +20, +7, +19, +262176, +21, +7, +6, +327713, +22, +9, +20, +21, +262177, +27, +19, +14, +262177, +31, +6, +14, +262167, +35, +6, +2, +262176, +36, +7, +35, +393249, +37, +6, +36, +36, +36, +327713, +43, +6, +20, +21, +524321, +52, +19, +20, +20, +8, +21, +20, +458785, +60, +19, +20, +20, +8, +21, +262165, +67, +32, +1, +262167, +68, +67, +2, +262176, +69, +7, +68, +262177, +70, +67, +69, +262187, +9, +75, +0, +262187, +6, +78, +1132396544, +262187, +9, +81, +255, +262187, +9, +84, +1, +262187, +9, +91, +2, +262187, +9, +98, +3, +262187, +67, +105, +24, +262187, +67, +108, +16, +262187, +67, +112, +8, +262187, +9, +120, +4278190080, +262187, +9, +126, +16711680, +262187, +9, +132, +65280, +262187, +6, +145, +1056964608, +262187, +6, +158, +1073741824, +262187, +6, +164, +1065353216, +262168, +175, +7, +4, +1966110, +176, +175, +175, +175, +175, +19, +6, +7, +7, +7, +7, +7, +6, +6, +6, +6, +7, +6, +6, +6, +6, +67, +67, +67, +67, +6, +6, +6, +175, +262176, +177, +2, +176, +262203, +177, +178, +2, +262187, +67, +179, +15, +262176, +180, +2, +7, +262187, +6, +191, +3212836864, +131092, +216, +262176, +217, +7, +216, +262187, +6, +222, +0, +262167, +228, +216, +2, +262187, +67, +251, +3, +262176, +252, +2, +175, +262187, +6, +287, +1008981770, +262176, +294, +7, +67, +262187, +67, +296, +4294967294, +262187, +67, +303, +2, +262187, +6, +314, +1075419546, +262187, +6, +316, +1075838976, +262187, +67, +320, +4294967295, +262187, +6, +336, +1086911939, +262187, +6, +342, +1076677837, +589849, +347, +6, +1, +0, +0, +0, +1, +0, +262176, +348, +0, +347, +262203, +348, +349, +0, +131098, +351, +262176, +352, +0, +351, +262203, +352, +353, +0, +196635, +355, +347, +262187, +6, +363, +1142947840, +262187, +67, +372, +18, +262176, +373, +2, +6, +262187, +67, +377, +19, +262187, +67, +398, +14, +262187, +6, +405, +925353388, +262187, +67, +426, +1, +262187, +67, +535, +9, +262187, +67, +541, +10, +262187, +67, +554, +25, +262187, +67, +558, +26, +262187, +67, +571, +4, +262176, +572, +2, +19, +262187, +6, +595, +1092616192, +262187, +6, +597, +1078523331, +262187, +6, +599, +1127481344, +262187, +6, +645, +3225419776, +262187, +67, +673, +6, +262187, +67, +681, +7, +262176, +745, +1, +7, +262203, +745, +746, +1, +262176, +747, +1, +6, +262187, +67, +780, +17, +262203, +745, +786, +1, +262187, +67, +795, +21, +262176, +796, +2, +67, +262187, +67, +799, +0, +262203, +745, +803, +1, +262187, +67, +816, +11, +262176, +826, +3, +7, +262203, +826, +827, +3, +458796, +7, +828, +222, +222, +222, +222, +589849, +843, +9, +1, +0, +1, +0, +2, +33, +262176, +844, +0, +843, +262203, +844, +845, +0, +262167, +848, +67, +3, +262167, +852, +9, +4, +262187, +67, +872, +12, +262203, +745, +881, +1, +262203, +747, +913, +1, +327734, +2, +4, +0, +3, +131320, +5, +262203, +8, +744, +7, +262203, +8, +765, +7, +262203, +21, +779, +7, +262203, +21, +789, +7, +262203, +21, +794, +7, +262203, +36, +804, +7, +262203, +36, +807, +7, +262203, +36, +810, +7, +262203, +21, +814, +7, +262203, +69, +830, +7, +262203, +294, +834, +7, +262203, +69, +835, +7, +262203, +14, +838, +7, +262203, +14, +842, +7, +262203, +14, +855, +7, +262203, +14, +863, +7, +262203, +21, +871, +7, +262203, +20, +873, +7, +262203, +21, +876, +7, +262203, +20, +880, +7, +262203, +20, +882, +7, +262203, +20, +885, +7, +262203, +8, +888, +7, +262203, +21, +889, +7, +262203, +20, +891, +7, +262203, +14, +895, +7, +262203, +8, +902, +7, +327745, +747, +748, +746, +75, +262205, +6, +749, +748, +327813, +6, +750, +158, +749, +393281, +373, +751, +178, +179, +91, +262205, +6, +752, +751, +327813, +6, +753, +750, +752, +327811, +6, +754, +753, +164, +327745, +747, +755, +746, +84, +262205, +6, +756, +755, +327813, +6, +757, +158, +756, +393281, +373, +758, +178, +179, +98, +262205, +6, +759, +758, +327813, +6, +760, +757, +759, +327811, +6, +761, +164, +760, +327745, +747, +762, +746, +91, +262205, +6, +763, +762, +458832, +7, +764, +754, +761, +763, +164, +196670, +744, +764, +327745, +252, +766, +178, +303, +262205, +175, +767, +766, +262205, +7, +768, +744, +327825, +7, +769, +767, +768, +196670, +765, +769, +262205, +7, +770, +765, +524367, +19, +771, +770, +770, +0, +1, +2, +327745, +21, +772, +765, +98, +262205, +6, +773, +772, +393296, +19, +774, +773, +773, +773, +327816, +19, +775, +771, +774, +262205, +7, +776, +765, +589903, +7, +777, +776, +775, +4, +5, +6, +3, +196670, +765, +777, +327745, +21, +778, +765, +98, +196670, +778, +164, +196670, +779, +164, +327745, +373, +781, +178, +780, +262205, +6, +782, +781, +327866, +216, +783, +782, +222, +196855, +785, +0, +262394, +783, +784, +785, +131320, +784, +327745, +747, +787, +786, +98, +262205, +6, +788, +787, +196670, +779, +788, +131321, +785, +131320, +785, +262205, +6, +790, +779, +327745, +373, +791, +178, +398, +262205, +6, +792, +791, +327813, +6, +793, +790, +792, +196670, +789, +793, +196670, +794, +164, +327745, +796, +797, +178, +795, +262205, +67, +798, +797, +327851, +216, +800, +798, +799, +196855, +802, +0, +262394, +800, +801, +802, +131320, +801, +262205, +7, +805, +803, +458831, +35, +806, +805, +805, +0, +1, +196670, +804, +806, +262205, +7, +808, +803, +458831, +35, +809, +808, +808, +2, +3, +196670, +807, +809, +262205, +7, +811, +744, +458831, +35, +812, +811, +811, +0, +1, +196670, +810, +812, +458809, +6, +813, +41, +804, +807, +810, +196670, +794, +813, +131321, +802, +131320, +802, +262205, +6, +815, +794, +327745, +373, +817, +178, +816, +262205, +6, +818, +817, +327813, +6, +819, +815, +818, +196670, +814, +819, +262205, +6, +820, +814, +327745, +373, +821, +178, +105, +262205, +6, +822, +821, +327864, +216, +823, +820, +822, +196855, +825, +0, +262394, +823, +824, +825, +131320, +824, +196670, +827, +828, +65789, +131320, +825, +262205, +7, +831, +746, +458831, +35, +832, +831, +831, +0, +1, +262254, +68, +833, +832, +196670, +830, +833, +262205, +68, +836, +830, +196670, +835, +836, +327737, +67, +837, +72, +835, +196670, +834, +837, +327745, +747, +839, +746, +91, +262205, +6, +840, +839, +262268, +9, +841, +840, +196670, +838, +841, +262205, +843, +846, +845, +262205, +68, +847, +830, +327761, +67, +849, +847, +0, +327761, +67, +850, +847, +1, +393296, +848, +851, +849, +850, +799, +327778, +852, +853, +846, +851, +327761, +9, +854, +853, +0, +196670, +842, +854, +262205, +843, +856, +845, +262205, +68, +857, +830, +327761, +67, +858, +857, +0, +327761, +67, +859, +857, +1, +393296, +848, +860, +858, +859, +426, +327778, +852, +861, +856, +860, +327761, +9, +862, +861, +0, +196670, +855, +862, +262205, +843, +864, +845, +262205, +68, +865, +830, +327761, +67, +866, +865, +0, +327761, +67, +867, +865, +1, +393296, +848, +868, +866, +867, +303, +327778, +852, +869, +864, +868, +327761, +9, +870, +869, +0, +196670, +863, +870, +262205, +7, +874, +765, +524367, +19, +875, +874, +874, +0, +1, +2, +196670, +873, +875, +327745, +373, +877, +178, +872, +262205, +6, +878, +877, +196670, +876, +878, +393273, +6, +879, +46, +873, +876, +196670, +871, +879, +262205, +7, +883, +765, +524367, +19, +884, +883, +883, +0, +1, +2, +196670, +882, +884, +262205, +7, +886, +786, +524367, +19, +887, +886, +886, +0, +1, +2, +196670, +885, +887, +196670, +888, +828, +262205, +6, +890, +871, +196670, +889, +890, +262205, +7, +892, +881, +524367, +19, +893, +892, +892, +0, +1, +2, +196670, +891, +893, +589881, +19, +894, +58, +882, +885, +888, +889, +891, +196670, +880, +894, +262205, +19, +896, +880, +262205, +6, +897, +814, +327761, +6, +898, +896, +0, +327761, +6, +899, +896, +1, +327761, +6, +900, +896, +2, +458832, +7, +901, +898, +899, +900, +897, +196670, +902, +901, +327737, +9, +903, +12, +902, +196670, +895, +903, +262205, +19, +904, +880, +262205, +6, +905, +814, +327822, +19, +906, +904, +905, +262205, +6, +907, +814, +327761, +6, +908, +906, +0, +327761, +6, +909, +906, +1, +327761, +6, +910, +906, +2, +458832, +7, +911, +908, +909, +910, +907, +196670, +827, +911, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +262203, +14, +74, +7, +262203, +14, +83, +7, +262203, +14, +90, +7, +262203, +14, +97, +7, +327745, +21, +76, +11, +75, +262205, +6, +77, +76, +327813, +6, +79, +77, +78, +262253, +9, +80, +79, +327879, +9, +82, +80, +81, +196670, +74, +82, +327745, +21, +85, +11, +84, +262205, +6, +86, +85, +327813, +6, +87, +86, +78, +262253, +9, +88, +87, +327879, +9, +89, +88, +81, +196670, +83, +89, +327745, +21, +92, +11, +91, +262205, +6, +93, +92, +327813, +6, +94, +93, +78, +262253, +9, +95, +94, +327879, +9, +96, +95, +81, +196670, +90, +96, +327745, +21, +99, +11, +98, +262205, +6, +100, +99, +327813, +6, +101, +100, +78, +262253, +9, +102, +101, +327879, +9, +103, +102, +81, +196670, +97, +103, +262205, +9, +104, +74, +327876, +9, +106, +104, +105, +262205, +9, +107, +83, +327876, +9, +109, +107, +108, +327877, +9, +110, +106, +109, +262205, +9, +111, +90, +327876, +9, +113, +111, +112, +327877, +9, +114, +110, +113, +262205, +9, +115, +97, +327877, +9, +116, +114, +115, +131326, +116, +65592, +327734, +7, +17, +0, +15, +196663, +14, +16, +131320, +18, +262205, +9, +119, +16, +327879, +9, +121, +119, +120, +327874, +9, +122, +121, +105, +262256, +6, +123, +122, +327816, +6, +124, +123, +78, +262205, +9, +125, +16, +327879, +9, +127, +125, +126, +327874, +9, +128, +127, +108, +262256, +6, +129, +128, +327816, +6, +130, +129, +78, +262205, +9, +131, +16, +327879, +9, +133, +131, +132, +327874, +9, +134, +133, +112, +262256, +6, +135, +134, +327816, +6, +136, +135, +78, +262205, +9, +137, +16, +327879, +9, +138, +137, +81, +262256, +6, +139, +138, +327816, +6, +140, +139, +78, +458832, +7, +141, +124, +130, +136, +140, +131326, +141, +65592, +327734, +9, +25, +0, +22, +196663, +20, +23, +196663, +21, +24, +131320, +26, +262203, +8, +154, +7, +262205, +19, +144, +23, +327822, +19, +146, +144, +145, +393296, +19, +147, +145, +145, +145, +327809, +19, +148, +146, +147, +262205, +6, +149, +24, +327761, +6, +150, +148, +0, +327761, +6, +151, +148, +1, +327761, +6, +152, +148, +2, +458832, +7, +153, +150, +151, +152, +149, +196670, +154, +153, +327737, +9, +155, +12, +154, +131326, +155, +65592, +327734, +19, +29, +0, +27, +196663, +14, +28, +131320, +30, +262203, +14, +159, +7, +262205, +9, +160, +28, +196670, +159, +160, +327737, +7, +161, +17, +159, +524367, +19, +162, +161, +161, +0, +1, +2, +327822, +19, +163, +162, +158, +393296, +19, +165, +164, +164, +164, +327811, +19, +166, +163, +165, +131326, +166, +65592, +327734, +6, +33, +0, +31, +196663, +14, +32, +131320, +34, +262203, +14, +169, +7, +262205, +9, +170, +32, +196670, +169, +170, +327737, +7, +171, +17, +169, +327761, +6, +172, +171, +3, +131326, +172, +65592, +327734, +6, +41, +0, +37, +196663, +36, +38, +196663, +36, +39, +196663, +36, +40, +131320, +42, +262203, +21, +201, +7, +262203, +21, +206, +7, +262203, +21, +211, +7, +262203, +217, +218, +7, +262203, +21, +231, +7, +262203, +21, +232, +7, +262203, +21, +238, +7, +327745, +180, +181, +178, +179, +262205, +7, +182, +181, +458831, +35, +183, +182, +182, +0, +1, +262205, +35, +184, +38, +327813, +35, +185, +184, +183, +196670, +38, +185, +327745, +180, +186, +178, +179, +262205, +7, +187, +186, +458831, +35, +188, +187, +187, +0, +1, +262205, +35, +189, +39, +327813, +35, +190, +189, +188, +196670, +39, +190, +327745, +21, +192, +40, +84, +262205, +6, +193, +192, +327813, +6, +194, +193, +191, +327745, +21, +195, +40, +84, +196670, +195, +194, +327745, +180, +196, +178, +179, +262205, +7, +197, +196, +458831, +35, +198, +197, +197, +0, +1, +262205, +35, +199, +40, +327813, +35, +200, +199, +198, +196670, +40, +200, +262205, +35, +202, +38, +262205, +35, +203, +40, +327811, +35, +204, +202, +203, +393228, +6, +205, +1, +66, +204, +196670, +201, +205, +262205, +35, +207, +39, +262205, +35, +208, +40, +327811, +35, +209, +207, +208, +393228, +6, +210, +1, +66, +209, +196670, +206, +210, +262205, +35, +212, +38, +262205, +35, +213, +39, +327811, +35, +214, +212, +213, +393228, +6, +215, +1, +66, +214, +196670, +211, +215, +262205, +6, +219, +211, +262205, +6, +220, +201, +458764, +6, +221, +1, +48, +219, +220, +327866, +216, +223, +221, +222, +262205, +6, +224, +211, +262205, +6, +225, +206, +458764, +6, +226, +1, +48, +224, +225, +327866, +216, +227, +226, +222, +327760, +228, +229, +223, +227, +262298, +216, +230, +229, +196670, +218, +230, +262205, +216, +233, +218, +196855, +235, +0, +262394, +233, +234, +236, +131320, +234, +196670, +232, +191, +131321, +235, +131320, +236, +196670, +232, +164, +131321, +235, +131320, +235, +262205, +6, +237, +232, +196670, +231, +237, +262205, +6, +239, +231, +262205, +6, +240, +201, +262205, +6, +241, +206, +458764, +6, +242, +1, +37, +240, +241, +524300, +6, +243, +1, +43, +242, +222, +164, +327813, +6, +244, +239, +243, +196670, +238, +244, +262205, +6, +245, +238, +327809, +6, +246, +245, +164, +327813, +6, +247, +246, +145, +131326, +247, +65592, +327734, +6, +46, +0, +43, +196663, +20, +44, +196663, +21, +45, +131320, +47, +262203, +8, +250, +7, +262203, +36, +269, +7, +262203, +21, +279, +7, +262203, +21, +285, +7, +262203, +21, +289, +7, +262203, +21, +292, +7, +262203, +21, +293, +7, +262203, +294, +295, +7, +262203, +294, +305, +7, +262203, +21, +313, +7, +262203, +21, +315, +7, +262203, +21, +319, +7, +262203, +21, +335, +7, +262203, +21, +346, +7, +262203, +21, +371, +7, +262203, +21, +389, +7, +262203, +21, +394, +7, +262203, +21, +403, +7, +262203, +21, +433, +7, +327745, +252, +253, +178, +251, +262205, +175, +254, +253, +262205, +19, +255, +44, +327761, +6, +256, +255, +0, +327761, +6, +257, +255, +1, +327761, +6, +258, +255, +2, +458832, +7, +259, +256, +257, +258, +164, +327825, +7, +260, +254, +259, +196670, +250, +260, +327745, +21, +261, +250, +98, +262205, +6, +262, +261, +262205, +7, +263, +250, +458831, +35, +264, +263, +263, +0, +1, +327760, +35, +265, +262, +262, +327816, +35, +266, +264, +265, +262205, +7, +267, +250, +589903, +7, +268, +267, +266, +4, +5, +2, +3, +196670, +250, +268, +262205, +7, +270, +250, +458831, +35, +271, +270, +270, +0, +1, +327822, +35, +272, +271, +145, +327760, +35, +273, +145, +145, +327809, +35, +274, +272, +273, +196670, +269, +274, +327745, +21, +275, +269, +84, +262205, +6, +276, +275, +327811, +6, +277, +164, +276, +327745, +21, +278, +269, +84, +196670, +278, +277, +327745, +21, +280, +250, +91, +262205, +6, +281, +280, +327745, +21, +282, +250, +98, +262205, +6, +283, +282, +327816, +6, +284, +281, +283, +196670, +279, +284, +262205, +6, +286, +279, +327813, +6, +288, +286, +287, +196670, +285, +288, +327745, +21, +290, +250, +98, +262205, +6, +291, +290, +196670, +289, +291, +196670, +292, +222, +196670, +293, +222, +196670, +292, +222, +196670, +295, +296, +131321, +297, +131320, +297, +262390, +299, +300, +0, +131321, +301, +131320, +301, +262205, +67, +302, +295, +327859, +216, +304, +302, +303, +262394, +304, +298, +299, +131320, +298, +196670, +305, +296, +131321, +306, +131320, +306, +262390, +308, +309, +0, +131321, +310, +131320, +310, +262205, +67, +311, +305, +327859, +216, +312, +311, +303, +262394, +312, +307, +308, +131320, +307, +196670, +313, +314, +262205, +6, +317, +313, +327816, +6, +318, +316, +317, +196670, +315, +318, +262205, +67, +321, +295, +262205, +67, +322, +295, +327812, +67, +323, +321, +322, +262205, +67, +324, +305, +262205, +67, +325, +305, +327812, +67, +326, +324, +325, +327808, +67, +327, +323, +326, +327812, +67, +328, +320, +327, +262255, +6, +329, +328, +262205, +6, +330, +315, +327813, +6, +331, +158, +330, +262205, +6, +332, +315, +327813, +6, +333, +331, +332, +327816, +6, +334, +329, +333, +196670, +319, +334, +262205, +6, +337, +315, +327813, +6, +338, +336, +337, +262205, +6, +339, +315, +327813, +6, +340, +338, +339, +327816, +6, +341, +164, +340, +262205, +6, +343, +319, +458764, +6, +344, +1, +26, +342, +343, +327813, +6, +345, +341, +344, +196670, +335, +345, +262205, +347, +350, +349, +262205, +351, +354, +353, +327766, +355, +356, +350, +354, +262205, +35, +357, +269, +262205, +67, +358, +295, +262255, +6, +359, +358, +262205, +67, +360, +305, +262255, +6, +361, +360, +327760, +35, +362, +359, +361, +327760, +35, +364, +363, +363, +327816, +35, +365, +362, +364, +327809, +35, +366, +357, +365, +327767, +7, +367, +356, +366, +327761, +6, +368, +367, +0, +327813, +6, +369, +158, +368, +327811, +6, +370, +369, +164, +196670, +346, +370, +327745, +373, +374, +178, +372, +262205, +6, +375, +374, +262205, +6, +376, +346, +327745, +373, +378, +178, +377, +262205, +6, +379, +378, +327745, +373, +380, +178, +372, +262205, +6, +381, +380, +327811, +6, +382, +379, +381, +327813, +6, +383, +376, +382, +327745, +373, +384, +178, +377, +262205, +6, +385, +384, +327816, +6, +386, +383, +385, +327811, +6, +387, +164, +386, +327816, +6, +388, +375, +387, +196670, +371, +388, +262205, +6, +390, +289, +262205, +6, +391, +371, +327811, +6, +392, +390, +391, +458764, +6, +393, +1, +40, +222, +392, +196670, +389, +393, +262205, +6, +395, +389, +327745, +373, +396, +178, +108, +262205, +6, +397, +396, +327745, +373, +399, +178, +398, +262205, +6, +400, +399, +327813, +6, +401, +397, +400, +327816, +6, +402, +395, +401, +196670, +394, +402, +262205, +6, +404, +389, +327866, +216, +406, +404, +405, +196855, +408, +0, +262394, +406, +407, +409, +131320, +407, +196670, +403, +164, +131321, +408, +131320, +409, +196670, +403, +222, +131321, +408, +131320, +408, +262205, +6, +410, +403, +262205, +6, +411, +394, +327809, +6, +412, +411, +410, +196670, +394, +412, +262205, +6, +413, +45, +327811, +6, +414, +164, +413, +393228, +6, +415, +1, +4, +414, +262205, +6, +416, +394, +458764, +6, +417, +1, +26, +415, +416, +262205, +6, +418, +335, +327813, +6, +419, +417, +418, +262205, +6, +420, +293, +327809, +6, +421, +420, +419, +196670, +293, +421, +262205, +6, +422, +335, +262205, +6, +423, +292, +327809, +6, +424, +423, +422, +196670, +292, +424, +131321, +309, +131320, +309, +262205, +67, +425, +305, +327808, +67, +427, +425, +426, +196670, +305, +427, +131321, +306, +131320, +308, +131321, +300, +131320, +300, +262205, +67, +428, +295, +327808, +67, +429, +428, +426, +196670, +295, +429, +131321, +297, +131320, +299, +262205, +6, +430, +292, +262205, +6, +431, +293, +327816, +6, +432, +431, +430, +196670, +293, +432, +196670, +433, +164, +262205, +6, +434, +293, +262205, +6, +435, +433, +327813, +6, +436, +434, +435, +131326, +436, +65592, +327734, +6, +50, +0, +43, +196663, +20, +48, +196663, +21, +49, +131320, +51, +262203, +8, +439, +7, +262203, +36, +456, +7, +262203, +21, +466, +7, +262203, +21, +472, +7, +262203, +21, +475, +7, +262203, +21, +478, +7, +262203, +21, +479, +7, +262203, +21, +488, +7, +262203, +21, +503, +7, +262203, +21, +508, +7, +262203, +21, +516, +7, +262203, +21, +525, +7, +327745, +252, +440, +178, +251, +262205, +175, +441, +440, +262205, +19, +442, +48, +327761, +6, +443, +442, +0, +327761, +6, +444, +442, +1, +327761, +6, +445, +442, +2, +458832, +7, +446, +443, +444, +445, +164, +327825, +7, +447, +441, +446, +196670, +439, +447, +327745, +21, +448, +439, +98, +262205, +6, +449, +448, +262205, +7, +450, +439, +458831, +35, +451, +450, +450, +0, +1, +327760, +35, +452, +449, +449, +327816, +35, +453, +451, +452, +262205, +7, +454, +439, +589903, +7, +455, +454, +453, +4, +5, +2, +3, +196670, +439, +455, +262205, +7, +457, +439, +458831, +35, +458, +457, +457, +0, +1, +327822, +35, +459, +458, +145, +327760, +35, +460, +145, +145, +327809, +35, +461, +459, +460, +196670, +456, +461, +327745, +21, +462, +456, +84, +262205, +6, +463, +462, +327811, +6, +464, +164, +463, +327745, +21, +465, +456, +84, +196670, +465, +464, +327745, +21, +467, +439, +91, +262205, +6, +468, +467, +327745, +21, +469, +439, +98, +262205, +6, +470, +469, +327816, +6, +471, +468, +470, +196670, +466, +471, +262205, +6, +473, +466, +327813, +6, +474, +473, +287, +196670, +472, +474, +327745, +21, +476, +439, +98, +262205, +6, +477, +476, +196670, +475, +477, +196670, +478, +164, +262205, +347, +480, +349, +262205, +351, +481, +353, +327766, +355, +482, +480, +481, +262205, +35, +483, +456, +327767, +7, +484, +482, +483, +327761, +6, +485, +484, +0, +327813, +6, +486, +158, +485, +327811, +6, +487, +486, +164, +196670, +479, +487, +327745, +373, +489, +178, +372, +262205, +6, +490, +489, +262205, +6, +491, +479, +327745, +373, +492, +178, +377, +262205, +6, +493, +492, +327745, +373, +494, +178, +372, +262205, +6, +495, +494, +327811, +6, +496, +493, +495, +327813, +6, +497, +491, +496, +327745, +373, +498, +178, +377, +262205, +6, +499, +498, +327816, +6, +500, +497, +499, +327811, +6, +501, +164, +500, +327816, +6, +502, +490, +501, +196670, +488, +502, +262205, +6, +504, +475, +262205, +6, +505, +488, +327811, +6, +506, +504, +505, +458764, +6, +507, +1, +40, +222, +506, +196670, +503, +507, +262205, +6, +509, +503, +327745, +373, +510, +178, +108, +262205, +6, +511, +510, +327745, +373, +512, +178, +398, +262205, +6, +513, +512, +327813, +6, +514, +511, +513, +327816, +6, +515, +509, +514, +196670, +508, +515, +262205, +6, +517, +503, +327866, +216, +518, +517, +405, +196855, +520, +0, +262394, +518, +519, +521, +131320, +519, +196670, +516, +164, +131321, +520, +131320, +521, +196670, +516, +222, +131321, +520, +131320, +520, +262205, +6, +522, +516, +262205, +6, +523, +508, +327809, +6, +524, +523, +522, +196670, +508, +524, +262205, +6, +526, +49, +327811, +6, +527, +164, +526, +393228, +6, +528, +1, +4, +527, +262205, +6, +529, +508, +458764, +6, +530, +1, +26, +528, +529, +196670, +525, +530, +262205, +6, +531, +525, +131326, +531, +65592, +327734, +19, +58, +0, +52, +196663, +20, +53, +196663, +20, +54, +196663, +8, +55, +196663, +21, +56, +196663, +20, +57, +131320, +59, +262203, +20, +534, +7, +262203, +21, +539, +7, +262203, +21, +540, +7, +262203, +21, +544, +7, +262203, +21, +547, +7, +262203, +21, +550, +7, +262203, +21, +553, +7, +262203, +21, +557, +7, +262203, +20, +561, +7, +262203, +20, +565, +7, +262203, +20, +570, +7, +262203, +20, +578, +7, +262203, +21, +581, +7, +262203, +21, +585, +7, +262203, +21, +591, +7, +262203, +21, +593, +7, +262203, +21, +601, +7, +262203, +21, +604, +7, +262203, +21, +606, +7, +262203, +21, +610, +7, +262203, +21, +616, +7, +262203, +21, +628, +7, +262203, +21, +634, +7, +262203, +21, +643, +7, +262203, +21, +656, +7, +262203, +21, +662, +7, +262203, +20, +671, +7, +327745, +180, +536, +178, +535, +262205, +7, +537, +536, +524367, +19, +538, +537, +537, +0, +1, +2, +196670, +534, +538, +196670, +539, +164, +393281, +373, +542, +178, +541, +75, +262205, +6, +543, +542, +196670, +540, +543, +393281, +373, +545, +178, +541, +84, +262205, +6, +546, +545, +196670, +544, +546, +393281, +373, +548, +178, +541, +91, +262205, +6, +549, +548, +196670, +547, +549, +393281, +373, +551, +178, +541, +98, +262205, +6, +552, +551, +196670, +550, +552, +327745, +373, +555, +178, +554, +262205, +6, +556, +555, +196670, +553, +556, +327745, +373, +559, +178, +558, +262205, +6, +560, +559, +196670, +557, +560, +327745, +180, +562, +178, +112, +262205, +7, +563, +562, +524367, +19, +564, +563, +563, +0, +1, +2, +196670, +561, +564, +262205, +19, +566, +561, +262205, +19, +567, +53, +327811, +19, +568, +566, +567, +393228, +19, +569, +1, +69, +568, +196670, +565, +569, +327745, +572, +573, +178, +571, +262205, +19, +574, +573, +262205, +19, +575, +53, +327811, +19, +576, +574, +575, +393228, +19, +577, +1, +69, +576, +196670, +570, +577, +262205, +19, +579, +54, +393228, +19, +580, +1, +69, +579, +196670, +578, +580, +262205, +19, +582, +578, +262205, +19, +583, +565, +327828, +6, +584, +582, +583, +196670, +581, +584, +262205, +6, +586, +581, +262205, +6, +587, +581, +327813, +6, +588, +586, +587, +327811, +6, +589, +164, +588, +393228, +6, +590, +1, +31, +589, +196670, +585, +590, +262205, +6, +592, +585, +196670, +591, +592, +262205, +6, +594, +539, +327813, +6, +596, +594, +595, +327813, +6, +598, +596, +597, +327816, +6, +600, +598, +599, +196670, +593, +600, +262205, +6, +602, +581, +262271, +6, +603, +602, +196670, +601, +603, +262205, +6, +605, +585, +196670, +604, +605, +262205, +19, +607, +578, +262205, +19, +608, +570, +327828, +6, +609, +607, +608, +196670, +606, +609, +262205, +6, +611, +606, +262205, +6, +612, +606, +327813, +6, +613, +611, +612, +327811, +6, +614, +164, +613, +393228, +6, +615, +1, +31, +614, +196670, +610, +615, +262205, +6, +617, +601, +262205, +6, +618, +593, +327813, +6, +619, +158, +618, +393228, +6, +620, +1, +14, +619, +327813, +6, +621, +617, +620, +262205, +6, +622, +604, +262205, +6, +623, +593, +327813, +6, +624, +158, +623, +393228, +6, +625, +1, +13, +624, +327813, +6, +626, +622, +625, +327811, +6, +627, +621, +626, +196670, +616, +627, +262205, +6, +629, +616, +262205, +6, +630, +616, +327813, +6, +631, +629, +630, +327811, +6, +632, +164, +631, +393228, +6, +633, +1, +31, +632, +196670, +628, +633, +262205, +6, +635, +616, +262205, +6, +636, +606, +327813, +6, +637, +635, +636, +262205, +6, +638, +628, +262205, +6, +639, +610, +327813, +6, +640, +638, +639, +327809, +6, +641, +637, +640, +458764, +6, +642, +1, +40, +222, +641, +196670, +634, +642, +262205, +6, +644, +601, +262205, +6, +646, +593, +327813, +6, +647, +645, +646, +393228, +6, +648, +1, +14, +647, +327813, +6, +649, +644, +648, +262205, +6, +650, +604, +262205, +6, +651, +593, +327813, +6, +652, +645, +651, +393228, +6, +653, +1, +13, +652, +327813, +6, +654, +650, +653, +327811, +6, +655, +649, +654, +196670, +643, +655, +262205, +6, +657, +643, +262205, +6, +658, +643, +327813, +6, +659, +657, +658, +327811, +6, +660, +164, +659, +393228, +6, +661, +1, +31, +660, +196670, +656, +661, +262205, +6, +663, +643, +262205, +6, +664, +606, +327813, +6, +665, +663, +664, +262205, +6, +666, +656, +262205, +6, +667, +610, +327813, +6, +668, +666, +667, +327809, +6, +669, +665, +668, +458764, +6, +670, +1, +40, +222, +669, +196670, +662, +670, +262205, +6, +672, +540, +327745, +180, +674, +178, +673, +262205, +7, +675, +674, +524367, +19, +676, +675, +675, +0, +1, +2, +327822, +19, +677, +676, +672, +262205, +19, +678, +534, +327813, +19, +679, +677, +678, +262205, +6, +680, +56, +327745, +180, +682, +178, +681, +262205, +7, +683, +682, +524367, +19, +684, +683, +683, +0, +1, +2, +327822, +19, +685, +684, +680, +262205, +6, +686, +544, +262205, +6, +687, +591, +327813, +6, +688, +686, +687, +262205, +19, +689, +534, +327822, +19, +690, +689, +688, +262205, +6, +691, +547, +262205, +6, +692, +634, +262205, +6, +693, +550, +458764, +6, +694, +1, +26, +692, +693, +327813, +6, +695, +691, +694, +393296, +19, +696, +695, +695, +695, +327809, +19, +697, +690, +696, +262205, +6, +698, +553, +262205, +6, +699, +662, +262205, +6, +700, +557, +458764, +6, +701, +1, +26, +699, +700, +327813, +6, +702, +698, +701, +262205, +19, +703, +534, +327822, +19, +704, +703, +702, +327809, +19, +705, +697, +704, +327813, +19, +706, +685, +705, +327809, +19, +707, +679, +706, +196670, +671, +707, +262205, +19, +708, +671, +262205, +6, +709, +56, +327822, +19, +710, +708, +709, +131326, +710, +65592, +327734, +19, +65, +0, +60, +196663, +20, +61, +196663, +20, +62, +196663, +8, +63, +196663, +21, +64, +131320, +66, +262203, +20, +713, +7, +262203, +21, +717, +7, +262203, +20, +720, +7, +327745, +180, +714, +178, +535, +262205, +7, +715, +714, +524367, +19, +716, +715, +715, +0, +1, +2, +196670, +713, +716, +393281, +373, +718, +178, +541, +84, +262205, +6, +719, +718, +196670, +717, +719, +262205, +6, +721, +64, +262205, +6, +722, +717, +327813, +6, +723, +721, +722, +262205, +19, +724, +713, +327822, +19, +725, +724, +723, +196670, +720, +725, +262205, +19, +726, +720, +262205, +6, +727, +64, +327822, +19, +728, +726, +727, +131326, +728, +65592, +327734, +67, +72, +0, +70, +196663, +69, +71, +131320, +73, +262203, +294, +731, +7, +327745, +294, +732, +71, +84, +262205, +67, +733, +732, +393281, +373, +734, +178, +179, +75, +262205, +6, +735, +734, +262254, +67, +736, +735, +327812, +67, +737, +733, +736, +327745, +294, +738, +71, +75, +262205, +67, +739, +738, +327808, +67, +740, +737, +739, +196670, +731, +740, +262205, +67, +741, +731, +131326, +741, +65592, +}; +const std::vector resolvecolors = {119734787, +65536, +524289, +240, +0, +131089, +1, +131089, +40, +393227, +1, +1280527431, +1685353262, +808793134, +0, +196622, +0, +1, +458767, +4, +4, +1852399981, +0, +165, +193, +196624, +4, +7, +196624, +4, +9, +196611, +2, +450, +589828, +1096764487, +1935622738, +1918988389, +1600484449, +1684105331, +1868526181, +1667590754, +29556, +589828, +1096764487, +1935622738, +1768186216, +1818191726, +1969712737, +1600481121, +1882206772, +7037793, +655364, +1197427783, +1279741775, +1885560645, +1953718128, +1600482425, +1701734764, +1919509599, +1769235301, +25974, +524292, +1197427783, +1279741775, +1852399429, +1685417059, +1768185701, +1952671090, +6649449, +262149, +4, +1852399981, +0, +524293, +12, +1801675088, +1634692166, +1850291316, +1767206772, +1982362734, +3880038, +262149, +11, +1818318454, +25973, +589829, +17, +1634758229, +1767205731, +1850307694, +1816555380, +880042351, +993097000, +0, +262149, +16, +1818318453, +25973, +655365, +25, +1801675088, +1735287124, +1098149477, +1866687598, +1634887030, +1982358887, +1715155814, +15153, +262149, +23, +1735287156, +7630437, +327685, +24, +1702260579, +1701273970, +0, +393221, +29, +1416914247, +1701277281, +1965585518, +15153, +393221, +28, +1801675120, +1632920677, +1852139374, +116, +393221, +33, +1131701575, +1919252079, +677734241, +3879285, +393221, +32, +1801675120, +1866687589, +1634887030, +25959, +393221, +40, +1098147143, +1701995620, +1982362483, +3879529, +327685, +39, +1684291958, +1936942450, +0, +262149, +42, +1702132066, +51, +262149, +51, +1702132066, +50, +262149, +58, +1702132066, +49, +262149, +65, +1702132066, +48, +262149, +122, +1634886000, +109, +262149, +127, +1634886000, +109, +262149, +137, +1634886000, +109, +327685, +144, +1684291950, +1936942450, +0, +327685, +148, +1936617283, +1953390964, +115, +393222, +148, +0, +1466785639, +1684828783, +0, +393222, +148, +1, +1450008423, +1350002025, +6975346, +458758, +148, +2, +1231904615, +1767274094, +1917876069, +27247, +524294, +148, +3, +1450008423, +1350002025, +1282043762, +1952999273, +0, +327686, +148, +4, +1165385575, +25977, +327686, +148, +5, +1986420583, +7761734, +524294, +148, +6, +1833000807, +1852139874, +1734954100, +1866691688, +7499628, +524294, +148, +7, +1867538279, +1282698857, +1952999273, +1869377347, +114, +458758, +148, +8, +1867538279, +1282698857, +1952999273, +7565136, +458758, +148, +9, +1632460647, +1935753844, +1819231077, +29295, +393222, +148, +10, +1632460647, +1633045364, +6649196, +458758, +148, +11, +1766219623, +1098016098, +1634234476, +0, +524294, +148, +12, +1632132967, +1750299241, +2003788897, +1752198209, +97, +458758, +148, +13, +1164074855, +1851879544, +2020167780, +7564389, +458758, +148, +14, +1766219623, +1383228770, +1969841249, +115, +393222, +148, +15, +1767333735, +2053722990, +101, +458758, +148, +16, +1766219623, +1400005986, +1768120688, +26478, +393222, +148, +17, +1415733095, +1416522088, +28777, +458758, +148, +18, +1315331943, +1282564453, +1952999273, +0, +393222, +148, +19, +1181114215, +1766617697, +7628903, +393222, +148, +20, +1416191847, +1399350117, +77, +458758, +148, +21, +1432510311, +1866687859, +1634887030, +25959, +458758, +148, +22, +1399414631, +1851880052, +1886339940, +7562601, +458758, +148, +23, +1298751335, +1917220961, +1701668705, +7566446, +524294, +148, +24, +1818320743, +1415669872, +1936028264, +1684828008, +0, +393222, +148, +25, +1214668647, +1265789281, +12915, +393222, +148, +26, +1214668647, +1165125985, +12920, +589830, +148, +27, +1231904615, +1767274094, +1917876069, +1767271023, +1869641573, +29810, +196613, +150, +0, +393221, +163, +1919112054, +1097753957, +1701995620, +29555, +393221, +165, +1180658791, +1130848626, +1685221231, +0, +393221, +170, +1734439526, +1953391981, +1701080649, +120, +262149, +171, +1634886000, +109, +327685, +174, +1986939238, +1752198209, +97, +393221, +177, +1667449204, +1850305909, +1886142838, +24936, +262149, +183, +1886142822, +24936, +327685, +193, +1734439494, +1869377347, +114, +262149, +197, +1819239270, +29295, +393221, +198, +1734439494, +1953391981, +1869377347, +29554, +327685, +201, +1869377379, +1836405618, +88, +327685, +204, +1869377379, +1836405618, +89, +327685, +207, +1869377379, +1836405618, +90, +327685, +210, +1869377379, +1836405618, +87, +393221, +236, +1919508808, +1684105299, +1632466799, +112, +393221, +239, +1634951015, +1768902765, +1816360046, +7368033, +262216, +148, +0, +5, +327752, +148, +0, +35, +0, +327752, +148, +0, +7, +16, +262216, +148, +1, +5, +327752, +148, +1, +35, +64, +327752, +148, +1, +7, +16, +262216, +148, +2, +5, +327752, +148, +2, +35, +128, +327752, +148, +2, +7, +16, +262216, +148, +3, +5, +327752, +148, +3, +35, +192, +327752, +148, +3, +7, +16, +327752, +148, +4, +35, +256, +327752, +148, +5, +35, +268, +327752, +148, +6, +35, +272, +327752, +148, +7, +35, +288, +327752, +148, +8, +35, +304, +327752, +148, +9, +35, +320, +327752, +148, +10, +35, +336, +327752, +148, +11, +35, +352, +327752, +148, +12, +35, +356, +327752, +148, +13, +35, +360, +327752, +148, +14, +35, +364, +327752, +148, +15, +35, +368, +327752, +148, +16, +35, +384, +327752, +148, +17, +35, +388, +327752, +148, +18, +35, +392, +327752, +148, +19, +35, +396, +327752, +148, +20, +35, +400, +327752, +148, +21, +35, +404, +327752, +148, +22, +35, +408, +327752, +148, +23, +35, +412, +327752, +148, +24, +35, +416, +327752, +148, +25, +35, +420, +327752, +148, +26, +35, +424, +262216, +148, +27, +5, +327752, +148, +27, +35, +432, +327752, +148, +27, +7, +16, +196679, +148, +2, +262215, +150, +34, +0, +262215, +150, +33, +16, +262215, +165, +11, +15, +262215, +177, +34, +0, +262215, +177, +33, +15, +262215, +177, +43, +1, +262215, +193, +30, +0, +262215, +198, +34, +0, +262215, +198, +33, +14, +262215, +198, +43, +2, +262215, +236, +34, +0, +262215, +236, +33, +3, +262215, +239, +34, +0, +262215, +239, +33, +19, +131091, +2, +196641, +3, +2, +196630, +6, +32, +262167, +7, +6, +4, +262176, +8, +7, +7, +262165, +9, +32, +0, +262177, +10, +9, +8, +262176, +14, +7, +9, +262177, +15, +7, +14, +262167, +19, +6, +3, +262176, +20, +7, +19, +262176, +21, +7, +6, +327713, +22, +9, +20, +21, +262177, +27, +19, +14, +262177, +31, +6, +14, +262165, +35, +32, +1, +262167, +36, +35, +2, +262176, +37, +7, +36, +262177, +38, +35, +37, +262187, +9, +43, +0, +262187, +6, +46, +1132396544, +262187, +9, +49, +255, +262187, +9, +52, +1, +262187, +9, +59, +2, +262187, +9, +66, +3, +262187, +35, +73, +24, +262187, +35, +76, +16, +262187, +35, +80, +8, +262187, +9, +88, +4278190080, +262187, +9, +94, +16711680, +262187, +9, +100, +65280, +262187, +6, +113, +1056964608, +262187, +6, +126, +1073741824, +262187, +6, +132, +1065353216, +262176, +143, +7, +35, +262168, +147, +7, +4, +1966110, +148, +147, +147, +147, +147, +19, +6, +7, +7, +7, +7, +7, +6, +6, +6, +6, +7, +6, +6, +6, +6, +35, +35, +35, +35, +6, +6, +6, +147, +262176, +149, +2, +148, +262203, +149, +150, +2, +262187, +35, +151, +15, +262176, +152, +2, +6, +262176, +164, +1, +7, +262203, +164, +165, +1, +262167, +166, +6, +2, +589849, +175, +6, +6, +0, +0, +0, +2, +0, +262176, +176, +0, +175, +262203, +176, +177, +0, +262187, +35, +179, +0, +327724, +36, +180, +179, +179, +262187, +6, +187, +1017370378, +131092, +188, +262176, +192, +3, +7, +262203, +192, +193, +3, +262187, +6, +194, +0, +458796, +7, +195, +194, +194, +194, +132, +262203, +176, +198, +0, +589849, +234, +6, +1, +0, +0, +0, +1, +0, +262176, +235, +0, +234, +262203, +235, +236, +0, +131098, +237, +262176, +238, +0, +237, +262203, +238, +239, +0, +327734, +2, +4, +0, +3, +131320, +5, +262203, +37, +163, +7, +262203, +143, +170, +7, +262203, +37, +171, +7, +262203, +21, +174, +7, +262203, +21, +183, +7, +262203, +8, +197, +7, +262203, +21, +201, +7, +262203, +21, +204, +7, +262203, +21, +207, +7, +262203, +21, +210, +7, +262205, +7, +167, +165, +458831, +166, +168, +167, +167, +0, +1, +262254, +36, +169, +168, +196670, +163, +169, +262205, +36, +172, +163, +196670, +171, +172, +327737, +35, +173, +40, +171, +196670, +170, +173, +262205, +175, +178, +177, +327778, +7, +181, +178, +180, +327761, +6, +182, +181, +0, +196670, +174, +182, +262205, +6, +184, +174, +327811, +6, +185, +132, +184, +196670, +183, +185, +262205, +6, +186, +183, +327864, +188, +189, +186, +187, +196855, +191, +0, +262394, +189, +190, +191, +131320, +190, +196670, +193, +195, +65789, +131320, +191, +262205, +175, +199, +198, +327778, +7, +200, +199, +180, +196670, +197, +200, +327745, +21, +202, +197, +43, +262205, +6, +203, +202, +196670, +201, +203, +327745, +21, +205, +197, +52, +262205, +6, +206, +205, +196670, +204, +206, +327745, +21, +208, +197, +59, +262205, +6, +209, +208, +196670, +207, +209, +327745, +21, +211, +197, +66, +262205, +6, +212, +211, +196670, +210, +212, +262205, +6, +213, +201, +262205, +6, +214, +210, +327816, +6, +215, +213, +214, +327745, +21, +216, +197, +43, +196670, +216, +215, +262205, +6, +217, +204, +262205, +6, +218, +210, +327816, +6, +219, +217, +218, +327745, +21, +220, +197, +52, +196670, +220, +219, +262205, +6, +221, +207, +262205, +6, +222, +210, +327816, +6, +223, +221, +222, +327745, +21, +224, +197, +59, +196670, +224, +223, +262205, +6, +225, +183, +262205, +7, +226, +197, +524367, +19, +227, +226, +226, +0, +1, +2, +327822, +19, +228, +227, +225, +262205, +7, +229, +197, +589903, +7, +230, +229, +228, +4, +5, +6, +3, +196670, +197, +230, +262205, +6, +231, +174, +327745, +21, +232, +197, +66, +196670, +232, +231, +262205, +7, +233, +197, +196670, +193, +233, +65789, +65592, +327734, +9, +12, +0, +10, +196663, +8, +11, +131320, +13, +262203, +14, +42, +7, +262203, +14, +51, +7, +262203, +14, +58, +7, +262203, +14, +65, +7, +327745, +21, +44, +11, +43, +262205, +6, +45, +44, +327813, +6, +47, +45, +46, +262253, +9, +48, +47, +327879, +9, +50, +48, +49, +196670, +42, +50, +327745, +21, +53, +11, +52, +262205, +6, +54, +53, +327813, +6, +55, +54, +46, +262253, +9, +56, +55, +327879, +9, +57, +56, +49, +196670, +51, +57, +327745, +21, +60, +11, +59, +262205, +6, +61, +60, +327813, +6, +62, +61, +46, +262253, +9, +63, +62, +327879, +9, +64, +63, +49, +196670, +58, +64, +327745, +21, +67, +11, +66, +262205, +6, +68, +67, +327813, +6, +69, +68, +46, +262253, +9, +70, +69, +327879, +9, +71, +70, +49, +196670, +65, +71, +262205, +9, +72, +42, +327876, +9, +74, +72, +73, +262205, +9, +75, +51, +327876, +9, +77, +75, +76, +327877, +9, +78, +74, +77, +262205, +9, +79, +58, +327876, +9, +81, +79, +80, +327877, +9, +82, +78, +81, +262205, +9, +83, +65, +327877, +9, +84, +82, +83, +131326, +84, +65592, +327734, +7, +17, +0, +15, +196663, +14, +16, +131320, +18, +262205, +9, +87, +16, +327879, +9, +89, +87, +88, +327874, +9, +90, +89, +73, +262256, +6, +91, +90, +327816, +6, +92, +91, +46, +262205, +9, +93, +16, +327879, +9, +95, +93, +94, +327874, +9, +96, +95, +76, +262256, +6, +97, +96, +327816, +6, +98, +97, +46, +262205, +9, +99, +16, +327879, +9, +101, +99, +100, +327874, +9, +102, +101, +80, +262256, +6, +103, +102, +327816, +6, +104, +103, +46, +262205, +9, +105, +16, +327879, +9, +106, +105, +49, +262256, +6, +107, +106, +327816, +6, +108, +107, +46, +458832, +7, +109, +92, +98, +104, +108, +131326, +109, +65592, +327734, +9, +25, +0, +22, +196663, +20, +23, +196663, +21, +24, +131320, +26, +262203, +8, +122, +7, +262205, +19, +112, +23, +327822, +19, +114, +112, +113, +393296, +19, +115, +113, +113, +113, +327809, +19, +116, +114, +115, +262205, +6, +117, +24, +327761, +6, +118, +116, +0, +327761, +6, +119, +116, +1, +327761, +6, +120, +116, +2, +458832, +7, +121, +118, +119, +120, +117, +196670, +122, +121, +327737, +9, +123, +12, +122, +131326, +123, +65592, +327734, +19, +29, +0, +27, +196663, +14, +28, +131320, +30, +262203, +14, +127, +7, +262205, +9, +128, +28, +196670, +127, +128, +327737, +7, +129, +17, +127, +524367, +19, +130, +129, +129, +0, +1, +2, +327822, +19, +131, +130, +126, +393296, +19, +133, +132, +132, +132, +327811, +19, +134, +131, +133, +131326, +134, +65592, +327734, +6, +33, +0, +31, +196663, +14, +32, +131320, +34, +262203, +14, +137, +7, +262205, +9, +138, +32, +196670, +137, +138, +327737, +7, +139, +17, +137, +327761, +6, +140, +139, +3, +131326, +140, +65592, +327734, +35, +40, +0, +38, +196663, +37, +39, +131320, +41, +262203, +143, +144, +7, +327745, +143, +145, +39, +52, +262205, +35, +146, +145, +393281, +152, +153, +150, +151, +43, +262205, +6, +154, +153, +262254, +35, +155, +154, +327812, +35, +156, +146, +155, +327745, +143, +157, +39, +43, +262205, +35, +158, +157, +327808, +35, +159, +156, +158, +196670, +144, +159, +262205, +35, +160, +144, +131326, +160, +65592, +}; diff --git a/amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp b/amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp new file mode 100644 index 0000000..ce36111 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp @@ -0,0 +1,1569 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXRenderer.cpp +// +// Main hair rendering code +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#include "TressFXRendererVulkan.h" +#include "AMD_Types.h" +#include "TressFXOpaqueVulkan.h" +#include "TressFXPrecompiledShadersVulkan.h" +#include "UtilVulkan.h" + +#ifndef AMD_V_RETURN +#define AMD_V_RETURN(x) \ + { \ + vr = (x); \ + if (vr != VK_SUCCESS) \ + { \ + return vr; \ + } \ + } +#endif + +// unreferenced formal parameter +#pragma warning(disable : 4100) + +using namespace DirectX; + +extern int g_TressFXNumVerticesPerStrand; + +struct CB_PER_FRAME +{ + XMMATRIX m_mWorld; + XMMATRIX m_mViewProj; + XMMATRIX m_mInvViewProj; + XMMATRIX m_mViewProjLight; + + XMFLOAT3 m_vEye; + float m_fvFOV; + + XMFLOAT4 m_AmbientLightColor; + XMFLOAT4 m_PointLightColor; + XMFLOAT4 m_PointLightPos; + XMFLOAT4 m_MatBaseColor; + XMFLOAT4 m_MatKValue; + + float m_FiberAlpha; + float m_HairSMAlpha; + float m_bExpandPixels; + float m_FiberRadius; + + XMFLOAT4 m_WinSize; + + float m_FiberSpacing; + float m_bThinTip; + float m_fNearLight; + float m_fFarLight; + + int m_iTechSM; + int m_bUseCoverage; + int m_iStrandCopies; + int m_iMaxFragments; + + float m_alphaThreshold; + float m_fHairKs2; + float m_fHairEx2; + unsigned m_optionalSRVs; + + XMMATRIX m_mInvViewProjViewport; + + int m_mNumVerticesPerStrand; + int m_mNumFollowHairsPerGuideHair; + int m_bSingleHeadTransform; + int padding0; +}; + +// Optional SRVs +#define PER_STRAND_TEX_COORDS 0x0001 +#define PER_VERTEX_TEX_COORDS 0x0002 +#define PER_VERTEX_COLORS 0x0004 + +struct PER_PIXEL_LINKED_LIST_STRUCT +{ + DWORD TangentAndCoverage; + DWORD depth; + DWORD strandColor; + DWORD dwNext; +}; + +struct PPLL_BUFFERS +{ + // Buffers for the head of the per-pixel linked lists (PPLL) + VkImage pHeadPPLL_Buffer; + VkDeviceMemory pHeadPPLL_Memory; + VkImageView pHeadPPLL_View; + + // Buffers for the per-pixel linked list (PPLL) data + VkBuffer pPPLL_Buffer; + VkDeviceMemory pPPLL_Memory; + + // Buffer for the atomic counter + VkBuffer pAtomicCounterPLL_Buffer; + VkDeviceMemory pAtomicCounterPLL_Memory; + + int width; + int height; + int refCount; // reference count - delete buffers when 0 +}; + +PPLL_BUFFERS g_PPLBuffers = {nullptr, nullptr, nullptr, 0, 0, 0}; + +const static UINT g_HairTotalLayers = 32; + +namespace +{ +//---------------------------------------------------------------------------------- +// +// CreateRenderPass +// +// Create the render pass used for the non shortcut algorithm +// +//---------------------------------------------------------------------------------- +VkRenderPass CreateRenderPass(VkDevice dev) +{ + const VkAttachmentDescription attachments[] = { + // Depth Buffer + {0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, + // color texture + {0, VK_FORMAT_R8G8B8A8_SRGB, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}}; + + const VkAttachmentReference depthStencilReference = { + 0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + const VkAttachmentReference colorReference = { + 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + const VkSubpassDescription subpasses[] = { + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, + &depthStencilReference, 0, nullptr}, + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &colorReference, nullptr, + &depthStencilReference, 0, nullptr}}; + + const VkSubpassDependency dependencies[] = { + {0, 1, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, 0}}; + + VkRenderPassCreateInfo renderPassInfo{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + nullptr, + 0, + AMD_ARRAY_SIZE(attachments), + attachments, + AMD_ARRAY_SIZE(subpasses), + subpasses, + AMD_ARRAY_SIZE(dependencies), + dependencies}; + VkRenderPass result; + vkCreateRenderPass(dev, &renderPassInfo, nullptr, &result); + return result; +} + +VkRenderPass CreateShadowRenderPass(VkDevice dev) +{ + const VkAttachmentDescription attachments[] = { + // Depth Buffer + {0, VK_FORMAT_D32_SFLOAT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}, + }; + + const VkAttachmentReference depthReference = { + 0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + const VkSubpassDescription subpasses[] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, + nullptr, 0, nullptr, nullptr, + &depthReference, 0, nullptr}}; + + VkRenderPassCreateInfo renderPassInfo{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + nullptr, + 0, + AMD_ARRAY_SIZE(attachments), + attachments, + AMD_ARRAY_SIZE(subpasses), + subpasses, + 0, + nullptr}; + VkRenderPass result; + vkCreateRenderPass(dev, &renderPassInfo, nullptr, &result); + return result; +} + +} // End anonymous namespace + +namespace AMD +{ +//-------------------------------------------------------------------------------------- +// +// CreateTextureAndViews +// +// Creates the textures and corresponding views for hair rendering +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::CreateTextureAndViews( + VkDevice pvkDevice, uint32_t texture_memory_index, VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) +{ + VkResult vr; + + // Create SM DSVs for hair + { + VkImageCreateInfo hairShadowMapInfo = getImageCreateInfo( + VK_FORMAT_D32_SFLOAT, SM_HAIR_WIDTH, SM_HAIR_HEIGHT, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + AMD_V_RETURN( + vkCreateImage(pvkDevice, &hairShadowMapInfo, nullptr, &m_pSMHairTexture)); + + VkMemoryRequirements mem_requirement; + vkGetImageMemoryRequirements(pvkDevice, m_pSMHairTexture, &mem_requirement); + VkMemoryAllocateInfo memoryAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + nullptr, mem_requirement.size, + texture_memory_index}; + AMD_V_RETURN( + vkAllocateMemory(pvkDevice, &memoryAllocateInfo, nullptr, &m_pSMHairMemory)); + AMD_V_RETURN(vkBindImageMemory(pvkDevice, m_pSMHairTexture, m_pSMHairMemory, 0)); + + VkImageViewCreateInfo dsvDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + dsvDesc.format = VK_FORMAT_D32_SFLOAT; + dsvDesc.viewType = VK_IMAGE_VIEW_TYPE_2D; + dsvDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + dsvDesc.subresourceRange.layerCount = 1; + dsvDesc.subresourceRange.levelCount = 1; + dsvDesc.image = m_pSMHairTexture; + AMD_V_RETURN(vkCreateImageView(pvkDevice, &dsvDesc, nullptr, &m_pSMHairView)); + + VkImageMemoryBarrier defineHairSMLayoutBarrier[] = {getImageMemoryBarrier( + m_pSMHairTexture, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, + nullptr, AMD_ARRAY_SIZE(defineHairSMLayoutBarrier), + defineHairSMLayoutBarrier); + } + + // Noise texture + { + VkImageCreateInfo noiseTextureInfo = getImageCreateInfo( + VK_FORMAT_R32G32B32A32_SFLOAT, 512, 512, + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + AMD_V_RETURN( + vkCreateImage(pvkDevice, &noiseTextureInfo, nullptr, &m_pNoiseTexture)); + + VkMemoryRequirements mem_requirement; + vkGetImageMemoryRequirements(pvkDevice, m_pNoiseTexture, &mem_requirement); + VkMemoryAllocateInfo memoryAllocateInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + nullptr, mem_requirement.size, + texture_memory_index}; + AMD_V_RETURN( + vkAllocateMemory(pvkDevice, &memoryAllocateInfo, nullptr, &m_pNoiseMemory)); + AMD_V_RETURN(vkBindImageMemory(pvkDevice, m_pNoiseTexture, m_pNoiseMemory, 0)); + + XMFLOAT4 *noiseArray = new XMFLOAT4[512 * 512]; + for (UINT i = 0; i < 512 * 512; i++) + { + noiseArray[i].x = rand() / (float)RAND_MAX; + noiseArray[i].y = rand() / (float)RAND_MAX; + noiseArray[i].z = rand() / (float)RAND_MAX; + noiseArray[i].w = rand() / (float)RAND_MAX; + } + + void *memoryPointer; + vkMapMemory(pvkDevice, scratchMemory, offsetInScratchBuffer, + 512 * 512 * sizeof(XMFLOAT4), 0, &memoryPointer); + memcpy(memoryPointer, noiseArray, 512 * 512 * sizeof(XMFLOAT4)); + vkUnmapMemory(pvkDevice, scratchMemory); + + VkImageMemoryBarrier makeNoiseTextureTransferableBarrier[] = { + getImageMemoryBarrier(m_pNoiseTexture, 0, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, + nullptr, AMD_ARRAY_SIZE(makeNoiseTextureTransferableBarrier), + makeNoiseTextureTransferableBarrier); + + VkBufferImageCopy copyInfo{offsetInScratchBuffer, 512, 512}; + copyInfo.imageExtent.width = 512; + copyInfo.imageExtent.height = 512; + copyInfo.imageExtent.depth = 1; + copyInfo.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copyInfo.imageSubresource.layerCount = 1; + vkCmdCopyBufferToImage(commandBuffer, scratchBuffer, m_pNoiseTexture, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Info); + offsetInScratchBuffer += 512 * 512 * sizeof(XMFLOAT4); + + VkImageMemoryBarrier makeNoiseTextureSampleableBarrier[] = {getImageMemoryBarrier( + m_pNoiseTexture, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, + nullptr, AMD_ARRAY_SIZE(makeNoiseTextureSampleableBarrier), + makeNoiseTextureSampleableBarrier); + + delete[] noiseArray; + + VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + srDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + srDesc.viewType = VK_IMAGE_VIEW_TYPE_2D; + srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + srDesc.subresourceRange.layerCount = 1; + srDesc.subresourceRange.levelCount = 1; + srDesc.image = m_pNoiseTexture; + + AMD_V_RETURN(vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pNoiseView)); + } + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// CreateVertexBuffers +// +// Creates the vertex buffers for hair rendering +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::CreateVertexBuffers( + VkDevice pvkDevice, uint32_t texture_memory_index, VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) +{ + VkResult vr; + // Create the screen quad vertex buffer(use StandardVertex for simplicity) + const StandardVertex screenQuad[6] = { + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), + XMFLOAT2(0.0f, 1.0f)}, // 0 + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), + XMFLOAT2(0.0f, 0.0f)}, // 1 + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), + XMFLOAT2(1.0f, 1.0f)}, // 2 + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), + XMFLOAT2(1.0f, 1.0f)}, // 2 + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), + XMFLOAT2(0.0f, 0.0f)}, // 1 + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), + XMFLOAT2(1.0f, 0.0f)} // 3 + }; + + VkBufferCreateInfo bd{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + bd.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + bd.size = sizeof(StandardVertex) * 6; + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pScreenQuadVB)); + + VkMemoryRequirements memReq; + vkGetBufferMemoryRequirements(pvkDevice, m_pScreenQuadVB, &memReq); + VkMemoryAllocateInfo allocInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; + allocInfo.allocationSize = memReq.size; + allocInfo.memoryTypeIndex = texture_memory_index; + AMD_V_RETURN(vkAllocateMemory(pvkDevice, &allocInfo, nullptr, &m_pScreenQuadMemory)); + AMD_V_RETURN(vkBindBufferMemory(pvkDevice, m_pScreenQuadVB, m_pScreenQuadMemory, 0)); + + void *memoryPointer; + vkMapMemory(pvkDevice, scratchMemory, offsetInScratchBuffer, + 6 * sizeof(StandardVertex), 0, &memoryPointer); + memcpy(memoryPointer, screenQuad, 6 * sizeof(StandardVertex)); + + VkBufferCopy region{offsetInScratchBuffer, 0, 6 * sizeof(StandardVertex)}; + vkCmdCopyBuffer(commandBuffer, scratchBuffer, m_pScreenQuadVB, 1, ®ion); + offsetInScratchBuffer += 6 * sizeof(StandardVertex); + vkUnmapMemory(pvkDevice, scratchMemory); + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// CreateConstantBuffers +// +// Creates the constant buffers for hair rendering +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::CreateConstantBuffer(VkDevice pvkDevice, + uint32_t maxUniformBuffer, + uint32_t cpu_memory_index) +{ + VkResult vr; + VkBufferCreateInfo cbDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + cbDesc.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + cbDesc.size = maxUniformBuffer * sizeof(CB_PER_FRAME); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &cbDesc, nullptr, &m_pcbPerFrame)); + m_pcbPerFrameMemory = allocBufferMemory(pvkDevice, m_pcbPerFrame, cpu_memory_index); + + return VK_SUCCESS; +} + +VkResult TressFXRenderer::CreateFrameBuffer(VkDevice pvkDevice, + VkImageView depthTextureView, + VkImageView colorTexture, uint32_t width, + uint32_t height) +{ + m_depthBuffer = depthTextureView; + m_colorTexture = colorTexture; + VkResult vr; + + { + VkImageView attachements[] = {m_depthBuffer, m_colorTexture}; + VkFramebufferCreateInfo info{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; + info.renderPass = m_pRPHairRendering; + info.attachmentCount = AMD_ARRAY_SIZE(attachements); + info.pAttachments = attachements; + info.width = width; + info.height = height; + info.layers = 1; + AMD_V_RETURN( + vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_renderHairFramebuffer)); + } + + VkImageView attachements[1] = {m_pSMHairView}; + VkFramebufferCreateInfo info{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; + info.renderPass = m_RPHairShadow; + info.attachmentCount = AMD_ARRAY_SIZE(attachements); + info.pAttachments = attachements; + info.width = SM_HAIR_WIDTH; + info.height = SM_HAIR_HEIGHT; + info.layers = 1; + AMD_V_RETURN(vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_shadowFrameBuffer)); + return VK_SUCCESS; +} + +VkResult TressFXRenderer::CreateSamplers(VkDevice pvkDevice) +{ + VkResult vr; + + // Create sampler state objects + VkSamplerCreateInfo samDesc{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; + samDesc.minFilter = VK_FILTER_LINEAR; + samDesc.magFilter = VK_FILTER_LINEAR; + samDesc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samDesc.addressModeU = samDesc.addressModeV = samDesc.addressModeW = + VK_SAMPLER_ADDRESS_MODE_REPEAT; + samDesc.maxAnisotropy = 16.f; + samDesc.compareOp = VK_COMPARE_OP_NEVER; + samDesc.minLod = 0.f; + samDesc.maxLod = 1000.f; + AMD_V_RETURN( + vkCreateSampler(pvkDevice, &samDesc, nullptr, &m_pSamplerStateLinearWrap)); + + samDesc.minFilter = VK_FILTER_NEAREST; + samDesc.magFilter = VK_FILTER_NEAREST; + samDesc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + AMD_V_RETURN( + vkCreateSampler(pvkDevice, &samDesc, nullptr, &m_pSamplerStatePointClamp)); + + samDesc.minFilter = VK_FILTER_LINEAR; + samDesc.magFilter = VK_FILTER_LINEAR; + samDesc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samDesc.compareEnable = true, samDesc.compareOp = VK_COMPARE_OP_LESS; + samDesc.borderColor = VK_BORDER_COLOR_INT_OPAQUE_WHITE; + samDesc.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + samDesc.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + samDesc.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + AMD_V_RETURN(vkCreateSampler(pvkDevice, &samDesc, nullptr, &m_pSamplerStateCmpLess)); + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// CreateRenderStateObjects +// +// Creates the render state objects for hair rendering +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::CreateRenderStateObjects(VkDevice pvkDevice) +{ + VkResult vr; + + m_pRPHairRendering = CreateRenderPass(pvkDevice); + ShaderModule fragmentShadersModule(pvkDevice, pass1_fragment); + + ShaderModule vertexShadersModule(pvkDevice, render_hair_aa_strand_copies_vertex); + VkPipelineShaderStageCreateInfo renderHairAAStrandCopiesStage[2] = { + getShaderStageCreateInfo(vertexShadersModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(fragmentShadersModule.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + VkGraphicsPipelineCreateInfo renderHairAAStrandCopiesDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::ColorWritesOff, + &CommonPipelineState::inputAssemblyTriangle, renderHairAAStrandCopiesStage, + m_pass1_layout, m_pRPHairRendering, 0); + + ShaderModule RenderHairAAVertexShader(pvkDevice, render_hair_aa_vertex); + VkPipelineShaderStageCreateInfo renderHairAAStage[2] = { + getShaderStageCreateInfo(RenderHairAAVertexShader.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(fragmentShadersModule.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + VkGraphicsPipelineCreateInfo renderHairAADesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::ColorWritesOff, + &CommonPipelineState::inputAssemblyTriangle, renderHairAAStage, + m_pass1_layout, m_pRPHairRendering, 0); + + ShaderModule renderHairStrandCopiesVertexModule(pvkDevice, + render_hair_strand_copies_vertex); + VkPipelineShaderStageCreateInfo renderHairStrandCopiesStage[2] = { + getShaderStageCreateInfo(renderHairStrandCopiesVertexModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(fragmentShadersModule.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + VkGraphicsPipelineCreateInfo renderHairStrandCopiesDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::ColorWritesOff, + &CommonPipelineState::inputAssemblyTriangle, renderHairStrandCopiesStage, + m_pass1_layout, m_pRPHairRendering, 0); + + ShaderModule renderHairVertexModule(pvkDevice, render_hair_vertex); + VkPipelineShaderStageCreateInfo renderHairStage[2] = { + getShaderStageCreateInfo(renderHairVertexModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(fragmentShadersModule.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + VkGraphicsPipelineCreateInfo renderHairDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::ColorWritesOff, + &CommonPipelineState::inputAssemblyTriangle, renderHairStage, m_pass1_layout, + m_pRPHairRendering, 0); + + ShaderModule pass2VSModule(pvkDevice, pass2_vertex); + ShaderModule pass2FSModule(pvkDevice, pass2_fragment); + VkPipelineShaderStageCreateInfo renderKBufferStage[2] = { + getShaderStageCreateInfo(pass2VSModule.m_shaderModule, VK_SHADER_STAGE_VERTEX_BIT, + "main"), + getShaderStageCreateInfo(pass2FSModule.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + VkGraphicsPipelineCreateInfo renderKBufferDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutQuad, + &CommonPipelineState::DepthTestDisabledStencilTestLessDSS, + &CommonPipelineState::BlendStateBlendToBg, + &CommonPipelineState::inputAssemblyTriangle, renderKBufferStage, + m_pass2_layout, m_pRPHairRendering, 1); + + m_RPHairShadow = CreateShadowRenderPass(pvkDevice); + + ShaderModule shadowVSModule(pvkDevice, hair_shadow_vertex); + ShaderModule shadowFSModule(pvkDevice, hair_shadow_fragment); + VkPipelineShaderStageCreateInfo renderHairShadow[2] = { + getShaderStageCreateInfo(shadowVSModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(shadowFSModule.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + VkGraphicsPipelineCreateInfo renderHairShadowDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledDesc, + &CommonPipelineState::ColorWritesOff, &CommonPipelineState::inputAssemblyLine, + renderHairShadow, m_shadow_pass_layout, m_RPHairShadow, 0); + + VkGraphicsPipelineCreateInfo pipelineInfoArray[] = {renderHairAAStrandCopiesDesc, + renderHairAADesc, + renderHairStrandCopiesDesc, + renderHairDesc, + renderKBufferDesc, + renderHairShadowDesc}; + + VkPipeline pipelineArray[6] = {}; + + AMD_V_RETURN(vkCreateGraphicsPipelines(pvkDevice, VK_NULL_HANDLE, + AMD_ARRAY_SIZE(pipelineInfoArray), + pipelineInfoArray, nullptr, pipelineArray)); + + m_pPLRenderHairAAStrandCopies = pipelineArray[0]; + m_pPLRenderHairAA = pipelineArray[1]; + m_pPLRenderHairStrandCopies = pipelineArray[2]; + m_pPLRenderHair = pipelineArray[3]; + m_pPLResolveKBuffer = pipelineArray[4]; + m_pPLGenerateHairSM = pipelineArray[5]; + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// OnCreateDevice +// +// Called when the device is created to create resources for hair rendering +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::OnCreateDevice( + VkDevice pvkDevice, int winWidth, int winHeight, bool bShortCutOn, + uint32_t maxUniformBuffer, uint32_t cpu_memory_index, uint32_t texture_memory_index, + VkImageView depthTexture, VkImageView colorTexture, VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) +{ + m_pvkDevice = pvkDevice; + VkResult vr; + + AMD_V_RETURN(CreateTextureAndViews(pvkDevice, texture_memory_index, commandBuffer, + scratchMemory, scratchBuffer, + offsetInScratchBuffer)); + AMD_V_RETURN(CreateConstantBuffer(pvkDevice, maxUniformBuffer, cpu_memory_index)); + AMD_V_RETURN(CreateVertexBuffers(pvkDevice, texture_memory_index, commandBuffer, + scratchMemory, scratchBuffer, + offsetInScratchBuffer)); + AMD_V_RETURN(CreateSamplers(pvkDevice)); + AMD_V_RETURN(CreateLayouts(pvkDevice)); + if (!bShortCutOn) + { + AMD_V_RETURN( + CreatePPLL(pvkDevice, winWidth, winHeight, false, texture_memory_index)); + VkImageMemoryBarrier defineHeadPPLLBarrier[] = {getImageMemoryBarrier( + m_pHeadPPLLTexture, 0, VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL)}; + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, + nullptr, AMD_ARRAY_SIZE(defineHeadPPLLBarrier), + defineHeadPPLLBarrier); + } + else + { + m_ShortCut.OnCreateDevice(pvkDevice, winWidth, winHeight, m_pass1_hair_set_layout, + m_pSamplerStateLinearWrap, m_pSamplerStatePointClamp, + depthTexture, colorTexture, m_pcbPerFrame, + sizeof(CB_PER_FRAME), m_pNoiseView, m_pSMHairView, + texture_memory_index, winWidth, winHeight); + + VkImageMemoryBarrier barriers[] = { + getImageMemoryBarrier(m_ShortCut.m_pAccumInvAlphaTexture, 0, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), + getImageMemoryBarrier(m_ShortCut.m_pFragmentDepthsTexture, 0, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL), + getImageMemoryBarrier(m_ShortCut.m_pFragmentColorsTexture, 0, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)}; + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, + nullptr, AMD_ARRAY_SIZE(barriers), barriers); + } + + AMD_V_RETURN(CreateRenderStateObjects(pvkDevice)); + AMD_V_RETURN(AllocateAndPopulateSets(pvkDevice, bShortCutOn)); + AMD_V_RETURN( + CreateFrameBuffer(pvkDevice, depthTexture, colorTexture, winWidth, winHeight)); + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// CreateRenderStateObjects +// +// Creates the pipelines for hair rendering +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) +{ + VkResult vr; + + // First pass model dependent set layout + { + const VkDescriptorSetLayoutBinding pass1_hair_bindings[] = { + // Hair Pos + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_VERTEX_BIT}, + // Hair Tangent + {IDSRV_HAIR_TANGENTS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_VERTEX_BIT}, + // Hair Thickness + {IDSRV_HAIR_THICKNESSES, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_VERTEX_BIT}, + }; + AMD_V_RETURN(getDescriptorLayout(pvkDevice, pass1_hair_bindings, + AMD_ARRAY_SIZE(pass1_hair_bindings), + m_pass1_hair_set_layout)); + } + + // First pass non model dependent set layout + { + VkDescriptorSetLayoutBinding pass1_config_bindings[] = { + // TressFX parameters + {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT}, + // Atomic counter + {IDSRV_ATOMIC_COUNTER_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // PPLL Head + {IDSRV_HEAD_PPLL, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // PPLL List + {IDSRV_PPLL, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // Sampler for noise texture in VS + {IDSRV_NOISE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLER, 1, + VK_SHADER_STAGE_VERTEX_BIT, &m_pSamplerStateLinearWrap}, + // Noise texture + {IDSRV_NOISEMAP, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, + VK_SHADER_STAGE_VERTEX_BIT}, + }; + AMD_V_RETURN(getDescriptorLayout(pvkDevice, pass1_config_bindings, + AMD_ARRAY_SIZE(pass1_config_bindings), + m_pass1_config_set_layout)); + } + + VkDescriptorSetLayout pass1_descriptor_set_layouts[] = {m_pass1_config_set_layout, + m_pass1_hair_set_layout}; + VkPipelineLayoutCreateInfo pipelineLayoutInfo{ + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, + AMD_ARRAY_SIZE(pass1_descriptor_set_layouts), pass1_descriptor_set_layouts}; + AMD_V_RETURN( + vkCreatePipelineLayout(pvkDevice, &pipelineLayoutInfo, nullptr, &m_pass1_layout)); + + // Pass 2 set layout + { + VkDescriptorSetLayoutBinding pass2_bindings[] = { + // TressFX parameters + {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT}, + // PPLL Head + {IDSRV_HEAD_PPLL, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // PPLL List + {IDSRV_PPLL, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // Shadow texture + {IDSRV_HAIRSM, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // Sampler for hair shadow texture + {IDSRV_SHADOW_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLER, 1, + VK_SHADER_STAGE_FRAGMENT_BIT, &m_pSamplerStatePointClamp}, + }; + AMD_V_RETURN(getDescriptorLayout(pvkDevice, pass2_bindings, + AMD_ARRAY_SIZE(pass2_bindings), + m_pass2_set_layout)); + } + + VkPipelineLayoutCreateInfo pass2PipelineLayoutInfo{ + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, + &m_pass2_set_layout}; + AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &pass2PipelineLayoutInfo, nullptr, + &m_pass2_layout)); + + // Shadow pass model dependent set layout + { + VkDescriptorSetLayoutBinding shadow_pass_hair_bindings[] = { + // TressFX parameters + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_VERTEX_BIT}, + }; + AMD_V_RETURN(getDescriptorLayout(pvkDevice, shadow_pass_hair_bindings, + AMD_ARRAY_SIZE(shadow_pass_hair_bindings), + m_shadow_pass_hair_set_layout)); + } + + // Shadow pass non model dependent set layout + { + VkDescriptorSetLayoutBinding shadow_pass_config_bindings[] = { + // TressFX parameters + {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, + VK_SHADER_STAGE_VERTEX_BIT}}; + AMD_V_RETURN(getDescriptorLayout(pvkDevice, shadow_pass_config_bindings, + AMD_ARRAY_SIZE(shadow_pass_config_bindings), + m_shadow_pass_config_set_layout)); + } + + VkDescriptorSetLayout shadow_pass_descriptor_set_layouts[] = { + m_shadow_pass_config_set_layout, m_shadow_pass_hair_set_layout}; + VkPipelineLayoutCreateInfo shadowPassPipelineLayoutInfo{ + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, + AMD_ARRAY_SIZE(shadow_pass_descriptor_set_layouts), + shadow_pass_descriptor_set_layouts}; + AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &shadowPassPipelineLayoutInfo, nullptr, + &m_shadow_pass_layout)); + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// AllocateAndPopulateSets +// +// Allocate descriptor set and fills them +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::AllocateAndPopulateSets(VkDevice pvkDevice, bool isShortcut) +{ + VkResult vr; + const VkDescriptorPoolSize descriptorPoolSize[] = { + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3}, + {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 3}, + {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3}, + {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2}, + {VK_DESCRIPTOR_TYPE_SAMPLER, 3}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2}}; + + VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{ + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; + descriptorPoolCreateInfo.maxSets = 3; + descriptorPoolCreateInfo.poolSizeCount = AMD_ARRAY_SIZE(descriptorPoolSize); + descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSize; + AMD_V_RETURN(vkCreateDescriptorPool(pvkDevice, &descriptorPoolCreateInfo, nullptr, + &m_descriptorStorage)); + + if (!isShortcut) + { + VkDescriptorSetAllocateInfo allocateInfo{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + allocateInfo.descriptorPool = m_descriptorStorage; + allocateInfo.descriptorSetCount = 1; + allocateInfo.pSetLayouts = &m_pass1_config_set_layout; + AMD_V_RETURN( + vkAllocateDescriptorSets(pvkDevice, &allocateInfo, &m_pass1_config_set)); + } + + if (!isShortcut) + { + VkDescriptorSetAllocateInfo allocate2Info{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + allocate2Info.descriptorPool = m_descriptorStorage; + allocate2Info.descriptorSetCount = 1; + allocate2Info.pSetLayouts = &m_pass2_set_layout; + AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &allocate2Info, &m_pass2_set)); + } + + { + VkDescriptorSetAllocateInfo allocate3Info{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + allocate3Info.descriptorPool = m_descriptorStorage; + allocate3Info.descriptorSetCount = 1; + allocate3Info.pSetLayouts = &m_shadow_pass_config_set_layout; + AMD_V_RETURN( + vkAllocateDescriptorSets(pvkDevice, &allocate3Info, &m_shadow_pass_set)); + } + + VkDescriptorBufferInfo bufferDescriptor{m_pcbPerFrame, 0, sizeof(CB_PER_FRAME)}; + if (!isShortcut) + { + + VkDescriptorBufferInfo atomicCounterDescriptor{m_pAtomicCounterPPLLBuffer, 0, + sizeof(unsigned int)}; + VkDescriptorBufferInfo PPLL_Buffer_Descriptor{ + m_pPPLLBuffer, 0, + g_HairTotalLayers * 1024 * 1024 * sizeof(PER_PIXEL_LINKED_LIST_STRUCT)}; + VkDescriptorImageInfo headPLLDescriptor{VK_NULL_HANDLE, m_pHeadPPLLView, + VK_IMAGE_LAYOUT_GENERAL}; + VkDescriptorImageInfo noiseDescriptor{VK_NULL_HANDLE, m_pNoiseView, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + VkDescriptorImageInfo shadowDescriptor{VK_NULL_HANDLE, m_pSMHairView, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + + VkWriteDescriptorSet writeDescriptorSets[] = { + getWriteDescriptor(m_pass1_config_set, IDSRV_CONSTANTS_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + &bufferDescriptor), + getWriteDescriptor(m_pass1_config_set, IDSRV_ATOMIC_COUNTER_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + &atomicCounterDescriptor), + getWriteDescriptor(m_pass1_config_set, IDSRV_HEAD_PPLL, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &headPLLDescriptor), + getWriteDescriptor(m_pass1_config_set, IDSRV_PPLL, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + &PPLL_Buffer_Descriptor), + getWriteDescriptor(m_pass1_config_set, IDSRV_NOISEMAP, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &noiseDescriptor), + getWriteDescriptor(m_pass2_set, IDSRV_CONSTANTS_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + &bufferDescriptor), + getWriteDescriptor(m_pass2_set, IDSRV_HEAD_PPLL, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &headPLLDescriptor), + getWriteDescriptor(m_pass2_set, IDSRV_PPLL, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + &PPLL_Buffer_Descriptor), + getWriteDescriptor(m_pass2_set, IDSRV_HAIRSM, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &shadowDescriptor), + getWriteDescriptor(m_shadow_pass_set, IDSRV_CONSTANTS_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + &bufferDescriptor), + }; + + vkUpdateDescriptorSets(pvkDevice, AMD_ARRAY_SIZE(writeDescriptorSets), + writeDescriptorSets, 0, nullptr); + } + else + { + VkWriteDescriptorSet writeDescriptorSets[] = { + getWriteDescriptor(m_shadow_pass_set, IDSRV_CONSTANTS_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + &bufferDescriptor), + }; + + vkUpdateDescriptorSets(pvkDevice, AMD_ARRAY_SIZE(writeDescriptorSets), + writeDescriptorSets, 0, nullptr); + } + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// CreatePPLL +// +// Creates the per pixel linked list buffers and views. To save space, the PPLL is +// shared between multiple TressFXRenderer objects. The ref count gets incremented +// when the PPLL is shared with a new TressFXRenderer object. +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::CreatePPLL(VkDevice pvkDevice, int winWidth, int winHeight, + bool resize, uint32_t texture_memory_index) +{ + VkResult vr; + + // see if the buffer needs to be resized or if refCount is 0 + if ((winWidth != g_PPLBuffers.width) || (winHeight != g_PPLBuffers.height) || + (g_PPLBuffers.refCount == 0)) + { + // Release any previously allocated buffers + // AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_Buffer); + // AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_SRV); + // AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_UAV); + // AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_Buffer); + // AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_UAV); + // AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_SRV); + + // linked list head texture + VkImageCreateInfo headPPLLInfo = + getImageCreateInfo(VK_FORMAT_R32_UINT, winWidth, winHeight, + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT); + AMD_V_RETURN(vkCreateImage(pvkDevice, &headPPLLInfo, nullptr, + &g_PPLBuffers.pHeadPPLL_Buffer)); + g_PPLBuffers.pHeadPPLL_Memory = allocImageMemory( + pvkDevice, g_PPLBuffers.pHeadPPLL_Buffer, texture_memory_index); + + // View for linked list head + VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + srDesc.format = VK_FORMAT_R32_UINT; + srDesc.viewType = VK_IMAGE_VIEW_TYPE_2D; + srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + srDesc.subresourceRange.layerCount = 1; + srDesc.subresourceRange.levelCount = 1; + srDesc.image = g_PPLBuffers.pHeadPPLL_Buffer; + AMD_V_RETURN( + vkCreateImageView(pvkDevice, &srDesc, nullptr, &g_PPLBuffers.pHeadPPLL_View)); + + // Per-pixel Linked List (PPLL) buffer + VkBufferCreateInfo BufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + BufferDesc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + BufferDesc.size = (DWORD)(g_HairTotalLayers * winWidth * winHeight * + sizeof(PER_PIXEL_LINKED_LIST_STRUCT)); + AMD_V_RETURN( + vkCreateBuffer(pvkDevice, &BufferDesc, nullptr, &g_PPLBuffers.pPPLL_Buffer)); + g_PPLBuffers.pPPLL_Memory = + allocBufferMemory(pvkDevice, g_PPLBuffers.pPPLL_Buffer, texture_memory_index); + + // Atomic counter buffer + BufferDesc.usage = + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + BufferDesc.size = sizeof(unsigned int); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &BufferDesc, nullptr, + &g_PPLBuffers.pAtomicCounterPLL_Buffer)); + g_PPLBuffers.pAtomicCounterPLL_Memory = allocBufferMemory( + pvkDevice, g_PPLBuffers.pAtomicCounterPLL_Buffer, texture_memory_index); + + // update the width and height + g_PPLBuffers.width = winWidth; + g_PPLBuffers.height = winHeight; + + // if the refCount is non-zero, then we're just resizing the buffers + if (g_PPLBuffers.refCount == 0) + { + g_PPLBuffers.refCount++; + } + } + else + { + if (!resize) + { + g_PPLBuffers.refCount++; + } + } + + m_pHeadPPLLTexture = g_PPLBuffers.pHeadPPLL_Buffer; + m_pHeadPPLLView = g_PPLBuffers.pHeadPPLL_View; + m_pPPLLBuffer = g_PPLBuffers.pPPLL_Buffer; + m_pAtomicCounterPPLLBuffer = g_PPLBuffers.pAtomicCounterPLL_Buffer; + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// DeletePPLL +// +// Deletes the PPLL buffers when the refCount goes to 0 +// +//-------------------------------------------------------------------------------------- +void TressFXRenderer::DeletePPLL(VkDevice pvkDevice) +{ + if (g_PPLBuffers.refCount == 0) + { + return; + } + + g_PPLBuffers.refCount--; + + m_pHeadPPLLTexture = NULL; + m_pHeadPPLLView = NULL; + m_pPPLLBuffer = NULL; + + if (g_PPLBuffers.refCount == 0) + { + AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_View, vkDestroyImageView, pvkDevice); + AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_Buffer, vkDestroyImage, pvkDevice); + AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_Memory, vkFreeMemory, pvkDevice); + AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_Buffer, vkDestroyBuffer, pvkDevice); + AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_Memory, vkFreeMemory, pvkDevice); + AMD_SAFE_RELEASE(g_PPLBuffers.pAtomicCounterPLL_Buffer, vkDestroyBuffer, + pvkDevice); + AMD_SAFE_RELEASE(g_PPLBuffers.pAtomicCounterPLL_Memory, vkFreeMemory, pvkDevice); + + g_PPLBuffers.width = 0; + g_PPLBuffers.height = 0; + } +} + +//-------------------------------------------------------------------------------------- +// +// OnResizedSwapChain +// +// Called when the swap chain is being resized. Allocate resources that need to be +// created at this time because they are dependent on the size of the frame buffer. +// +//-------------------------------------------------------------------------------------- +VkResult TressFXRenderer::OnResizedSwapChain(VkDevice pvkDevice, int width, int height, + bool bShortCutOn, + uint32_t texture_memory_index) +{ + VkResult vr; + if (bShortCutOn) + { + // AMD_V_RETURN(m_ShortCut.OnResizedSwapChain(pd3dDevice, width, height)); + } + else + { + AMD_V_RETURN(CreatePPLL(pvkDevice, width, height, true, texture_memory_index)); + } + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// BeginHairFrame +// +// Start of hair rendering. +// +//-------------------------------------------------------------------------------------- +void TressFXRenderer::BeginHairFrame( + VkDevice pvkDevice, DirectX::XMVECTOR eyePoint, DirectX::XMVECTOR lightPosition, + DirectX::XMMATRIX *pModelTransformForHead, DirectX::XMMATRIX *pViewProj, + DirectX::XMMATRIX *pViewProjLightOut, float screenWidth, float screenHeight, + bool singleHeadTransform, uint32_t uniformBufferIndex) +{ + // Set up camera parameters for when the camera is at the position of the light for + // rendering the shadow map + XMMATRIX mViewLight, mProjLight; + XMVECTOR modelCenter = XMVector3TransformCoord( + XMLoadFloat3(&m_pTressFXMesh->m_HairAsset.m_bSphere.center), + *pModelTransformForHead); + XMVECTOR vLightAt = modelCenter; + XMVECTOR vUp = XMVectorSet(0, 1, 0, 0); + mViewLight = XMMatrixLookAtLH(lightPosition, vLightAt, vUp); + + XMVECTOR vLightToObject = XMVectorSubtract(lightPosition, modelCenter); + float dis = XMVectorGetX(XMVector3Length(vLightToObject)); + + float min_dis = max(0.001f, dis - m_pTressFXMesh->m_HairAsset.m_bSphere.radius); + float max_dis = dis + m_pTressFXMesh->m_HairAsset.m_bSphere.radius; + + float halfAngle = 1.5f * asin(m_pTressFXMesh->m_HairAsset.m_bSphere.radius / dis); + float FOV = 2 * halfAngle; + + float ratio = 1; + + mProjLight = XMMatrixPerspectiveFovLH(FOV, ratio, min_dis, max_dis); + *pViewProjLightOut = mViewLight * mProjLight; + + // Map the per-frame constant buffer + CB_PER_FRAME *pcbPerFrame; + vkMapMemory(pvkDevice, m_pcbPerFrameMemory, uniformBufferIndex * sizeof(CB_PER_FRAME), + sizeof(CB_PER_FRAME), 0, reinterpret_cast(&pcbPerFrame)); + + // camera parameters + XMMATRIX mViewProj = *pViewProj; + XMMATRIX mInvViewProj = XMMatrixInverse(0, mViewProj); + + float fRenderWidth = screenWidth; + float fRenderHeight = screenHeight; + + // Inverse of viewprojection matrix with viewport mapping + XMMATRIX mViewport(2.0f / fRenderWidth, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / fRenderHeight, + 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f); + + XMMATRIX mInvViewProjViewport = mInvViewProj; + + pcbPerFrame->m_mViewProj = XMMatrixTranspose(mViewProj); + pcbPerFrame->m_mInvViewProj = XMMatrixTranspose(mInvViewProj); + + pcbPerFrame->m_mInvViewProjViewport = XMMatrixTranspose(mInvViewProjViewport); + + pcbPerFrame->m_mWorld = XMMatrixTranspose(*pModelTransformForHead); + + XMStoreFloat3(&pcbPerFrame->m_vEye, eyePoint); + + pcbPerFrame->m_fvFOV = XM_PI / 4; + + // Light camera parameters + pcbPerFrame->m_mViewProjLight = *pViewProjLightOut; + pcbPerFrame->m_fNearLight = min_dis; + pcbPerFrame->m_fFarLight = max_dis; + + XMStoreFloat4(&pcbPerFrame->m_PointLightPos, lightPosition); + pcbPerFrame->m_PointLightPos.w = 1; + + // scene light color + pcbPerFrame->m_AmbientLightColor = m_hairParams.ambientLightColor; + pcbPerFrame->m_PointLightColor = m_hairParams.pointLightColor; + + // hair material + pcbPerFrame->m_MatBaseColor = + XMFLOAT4(m_hairParams.color.x, m_hairParams.color.y, m_hairParams.color.z, 1); + pcbPerFrame->m_MatKValue = + XMFLOAT4(m_hairParams.Ka, m_hairParams.Kd, m_hairParams.Ks1, m_hairParams.Ex1); + pcbPerFrame->m_fHairKs2 = m_hairParams.Ks2; + pcbPerFrame->m_fHairEx2 = m_hairParams.Ex2; + + pcbPerFrame->m_FiberAlpha = m_hairParams.alpha; + pcbPerFrame->m_HairSMAlpha = m_hairParams.shadowMapAlpha; + + pcbPerFrame->m_FiberRadius = m_hairParams.thickness; + + pcbPerFrame->m_FiberSpacing = m_hairParams.duplicateStrandSpacing; + + pcbPerFrame->m_bThinTip = (m_hairParams.bThinTip ? 1.f : -1.f); + pcbPerFrame->m_bExpandPixels = 1; + + pcbPerFrame->m_WinSize = + XMFLOAT4((float)screenWidth, (float)screenHeight, 1.0f / (float)screenWidth, + 1.0f / (float)screenHeight); + + pcbPerFrame->m_iMaxFragments = m_hairParams.maxFragments; + + pcbPerFrame->m_alphaThreshold = m_hairParams.alphaThreshold; + + pcbPerFrame->m_iTechSM = m_hairParams.shadowTechnique; + pcbPerFrame->m_bUseCoverage = m_hairParams.bAntialias ? 1 : 0; + pcbPerFrame->m_iStrandCopies = m_hairParams.strandCopies; + + pcbPerFrame->m_mNumVerticesPerStrand = g_TressFXNumVerticesPerStrand; + pcbPerFrame->m_mNumFollowHairsPerGuideHair = + m_pTressFXMesh->m_HairAsset.m_NumFollowHairsPerGuideHair; + pcbPerFrame->m_bSingleHeadTransform = singleHeadTransform; + + unsigned optionalSRVs = 0; + if ((m_pTressFXMesh->m_pStrandTexCoordView) && (m_pTressFXMesh->m_pHairTextureSRV)) + { + optionalSRVs |= PER_STRAND_TEX_COORDS; + // ignore the material base color when getting hair color from the texture + pcbPerFrame->m_MatBaseColor = XMFLOAT4(1, 1, 1, 1); + } + pcbPerFrame->m_optionalSRVs = optionalSRVs; + + vkUnmapMemory(pvkDevice, m_pcbPerFrameMemory); +} + +//-------------------------------------------------------------------------------------- +// +// RenderScreenQuad +// +// Renders a full screen quad +// +////-------------------------------------------------------------------------------------- +void TressFXRenderer::RenderScreenQuad(VkCommandBuffer cmdbuffer, VkPipeline pPipeline) +{ + // set shader + vkCmdBindPipeline(cmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pPipeline); + + VkDeviceSize offsets = 0; + vkCmdBindVertexBuffers(cmdbuffer, 0, 1, &m_pScreenQuadVB, &offsets); + + // Draw full screen quad + vkCmdDraw(cmdbuffer, 6, 1, 0, 0); +} + +//-------------------------------------------------------------------------------------- +// +// GenerateShadowMap +// +// Renders the hair from the point of view of the light into a shadow map +// +//-------------------------------------------------------------------------------------- +void TressFXRenderer::GenerateShadowMap(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + float density, uint32_t uniformBufferIndex) +{ + VkViewport viewport{0.f, 0.f, SM_HAIR_WIDTH, SM_HAIR_HEIGHT, 0.f, 1.f}; + vkCmdSetViewport(commandBuffer, 0, 1, &viewport); + VkRect2D scissor{0, 0, SM_HAIR_WIDTH, SM_HAIR_HEIGHT}; + vkCmdSetScissor(commandBuffer, 0, 1, &scissor); + // clear depth for early z + VkRenderPassBeginInfo info{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO}; + info.renderPass = m_RPHairShadow; + info.framebuffer = m_shadowFrameBuffer; + info.clearValueCount = 1; + VkClearValue depthClear{}; + depthClear.depthStencil.depth = 1.f; + info.pClearValues = &depthClear; + info.renderArea.extent = {SM_HAIR_WIDTH, SM_HAIR_HEIGHT}; + vkCmdBeginRenderPass(commandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pPLGenerateHairSM); + VkDescriptorSet sets[] = {m_shadow_pass_set, m_pTressFXMesh->m_shadow_pass_set}; + uint32_t descriptorOffsets[] = {uniformBufferIndex * sizeof(CB_PER_FRAME)}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_shadow_pass_layout, 0, AMD_ARRAY_SIZE(sets), sets, + AMD_ARRAY_SIZE(descriptorOffsets), descriptorOffsets); + vkCmdBindIndexBuffer(commandBuffer, m_pTressFXMesh->m_pIndexBuffer, 0, + VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(commandBuffer, UINT(density * m_pTressFXMesh->m_TotalIndexCount), 1, + 0, 0, 0); + vkCmdEndRenderPass(commandBuffer); +} + +//-------------------------------------------------------------------------------------- +// +// RenderHair +// +// Renders the hair in two passes. The first pass fills an A-buffer by rendering the +// hair geometry into a per-pixel linked list which keeps all of the overlapping +// fragments. +// The second pass renders a full screen quad (using a stencil mask set in the first pass +// to avoid unnecessary pixels) which reads fragments from the per-pixel linked list +// and blends the nearest k fragments (K-buffer) in back to front order. +// +////-------------------------------------------------------------------------------------- +void TressFXRenderer::RenderHair(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height, + uint32_t uniformBufferIndex) +{ + // Caller must rebind original render target and depth stencil view after call + + // render hair + + // Clear HeadPPLL buffer as it's not an attachment + VkClearColorValue dwClearDataMinusOne{}; + dwClearDataMinusOne.uint32[0] = 0xFFFFFFFF; + VkImageSubresourceRange range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + vkCmdClearColorImage(commandBuffer, m_pHeadPPLLTexture, VK_IMAGE_LAYOUT_GENERAL, + &dwClearDataMinusOne, 1, &range); + vkCmdFillBuffer(commandBuffer, m_pAtomicCounterPPLLBuffer, 0, sizeof(unsigned int), + 0); + + VkBufferMemoryBarrier flushAtomicCounterBarrier[] = { + getBufferBarrier(m_pAtomicCounterPPLLBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(flushAtomicCounterBarrier), + flushAtomicCounterBarrier, 0, nullptr); + + uint32_t descriptorOffsets[] = {uniformBufferIndex * sizeof(CB_PER_FRAME)}; + + { + VkClearValue clearStencil{}; + clearStencil.depthStencil.stencil = 0; + VkRenderPassBeginInfo renderPassBeginInfo{ + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO}; + renderPassBeginInfo.renderPass = m_pRPHairRendering; + renderPassBeginInfo.framebuffer = m_renderHairFramebuffer; + renderPassBeginInfo.renderArea.extent.width = width; + renderPassBeginInfo.renderArea.extent.height = height; + renderPassBeginInfo.clearValueCount = 1; + renderPassBeginInfo.pClearValues = &clearStencil; + vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, + VK_SUBPASS_CONTENTS_INLINE); + } + + // Pass 1: A-Buffer pass + if (m_hairParams.bAntialias) + { + if (m_hairParams.strandCopies > 1) + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pPLRenderHairAAStrandCopies); + } + else + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pPLRenderHairAA); + } + } + else + { + if (m_hairParams.strandCopies > 1) + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pPLRenderHairStrandCopies); + } + else + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pPLRenderHair); + } + } + VkDescriptorSet descriptorSets[] = {m_pass1_config_set, m_pTressFXMesh->m_pass1_set}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pass1_layout, 0, AMD_ARRAY_SIZE(descriptorSets), + descriptorSets, AMD_ARRAY_SIZE(descriptorOffsets), + descriptorOffsets); + + vkCmdBindIndexBuffer(commandBuffer, m_pTressFXMesh->m_pTriangleIndexBuffer, 0, + VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(commandBuffer, UINT(m_hairParams.density * + m_pTressFXMesh->m_TotalTriangleIndexCount), + m_hairParams.strandCopies, 0, 0, 0); + + vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); + + // Pass 2: K-Buffer pass + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pass2_layout, 0, 1, &m_pass2_set, + AMD_ARRAY_SIZE(descriptorOffsets), descriptorOffsets); + RenderScreenQuad(commandBuffer, m_pPLResolveKBuffer); + vkCmdEndRenderPass(commandBuffer); +} + +void TressFXRenderer::RenderHairShortcut(VkDevice pvkDevice, + VkCommandBuffer commandBuffer, uint32_t width, + uint32_t height, uint32_t uniformBufferIndex) +{ + m_ShortCut.SetupDepthPass(pvkDevice, commandBuffer, width, height); + + uint32_t descriptorOffsets[] = {uniformBufferIndex * sizeof(CB_PER_FRAME)}; + + // DEPTH FILL + if (m_hairParams.bAntialias) + { + if (m_hairParams.strandCopies > 1) + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairAAStrandCopiesDepthsAlpha); + } + else + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairAADepthsAlpha); + } + } + else + { + if (m_hairParams.strandCopies > 1) + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairStrandCopiesDepthsAlpha); + } + else + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairDepthsAlpha); + } + } + + { + VkDescriptorSet descriptorSets[] = {m_ShortCut.m_depthPassSet, + m_pTressFXMesh->m_pass1_set}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_depthPassPipelineLayout, 0, + AMD_ARRAY_SIZE(descriptorSets), descriptorSets, + AMD_ARRAY_SIZE(descriptorOffsets), descriptorOffsets); + } + + vkCmdBindIndexBuffer(commandBuffer, m_pTressFXMesh->m_pTriangleIndexBuffer, 0, + VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(commandBuffer, UINT(m_hairParams.density * + m_pTressFXMesh->m_TotalTriangleIndexCount), + m_hairParams.strandCopies, 0, 0, 0); + + // DEPTH RESOLVE + m_ShortCut.SetupResolveDepth(pvkDevice, commandBuffer, width, height); + RenderScreenQuad(commandBuffer, m_ShortCut.m_pPLDepthResolve); + + // COLOR FILL + m_ShortCut.SetupShadePass(pvkDevice, commandBuffer, width, height); + + if (m_hairParams.bAntialias) + { + if (m_hairParams.strandCopies > 1) + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairAAStrandCopiesFillColors); + } + else + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairAAFillColors); + } + } + else + { + if (m_hairParams.strandCopies > 1) + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairStrandCopiesFillColors); + } + else + { + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_pPLRenderHairFillColors); + } + } + + { + VkDescriptorSet descriptorSets[] = {m_ShortCut.m_colorPassSet, + m_pTressFXMesh->m_pass1_set}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_ShortCut.m_colorPassPipelineLayout, 0, + AMD_ARRAY_SIZE(descriptorSets), descriptorSets, + AMD_ARRAY_SIZE(descriptorOffsets), descriptorOffsets); + } + + vkCmdBindIndexBuffer(commandBuffer, m_pTressFXMesh->m_pTriangleIndexBuffer, 0, + VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(commandBuffer, UINT(m_hairParams.density * + m_pTressFXMesh->m_TotalTriangleIndexCount), + m_hairParams.strandCopies, 0, 0, 0); + + // COLOR RESOLVE + m_ShortCut.SetupResolveColor(pvkDevice, commandBuffer, width, height); + RenderScreenQuad(commandBuffer, m_ShortCut.m_pPLColorResolve); + vkCmdEndRenderPass(commandBuffer); +} + +//-------------------------------------------------------------------------------------- +// +// EndHairFrame +// +// Start of hair rendering. +// +//-------------------------------------------------------------------------------------- +void TressFXRenderer::EndHairFrame(VkDevice pvkDevice) {} + +//-------------------------------------------------------------------------------------- +// +// OnDestroy +// +// Called when device is destroyed. +// +//-------------------------------------------------------------------------------------- +void TressFXRenderer::OnDestroy() +{ + m_ShortCut.OnDestroy(true); + + AMD_SAFE_RELEASE(m_pScreenQuadVB, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_pScreenQuadMemory, vkFreeMemory, m_pvkDevice); + + { + AMD_SAFE_RELEASE(m_pPLRenderHairAAStrandCopies, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairAA, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairStrandCopies, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHair, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLResolveKBuffer, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLGenerateHairSM, vkDestroyPipeline, m_pvkDevice); + + AMD_SAFE_RELEASE(m_renderHairFramebuffer, vkDestroyFramebuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_shadowFrameBuffer, vkDestroyFramebuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_pRPHairRendering, vkDestroyRenderPass, m_pvkDevice); + AMD_SAFE_RELEASE(m_RPHairShadow, vkDestroyRenderPass, m_pvkDevice); + AMD_SAFE_RELEASE(m_pass1_layout, vkDestroyPipelineLayout, m_pvkDevice); + AMD_SAFE_RELEASE(m_pass2_layout, vkDestroyPipelineLayout, m_pvkDevice); + AMD_SAFE_RELEASE(m_shadow_pass_layout, vkDestroyPipelineLayout, m_pvkDevice); + AMD_SAFE_RELEASE(m_pass1_config_set_layout, vkDestroyDescriptorSetLayout, + m_pvkDevice); + AMD_SAFE_RELEASE(m_pass1_hair_set_layout, vkDestroyDescriptorSetLayout, + m_pvkDevice); + AMD_SAFE_RELEASE(m_pass2_set_layout, vkDestroyDescriptorSetLayout, m_pvkDevice); + AMD_SAFE_RELEASE(m_shadow_pass_config_set_layout, vkDestroyDescriptorSetLayout, + m_pvkDevice); + AMD_SAFE_RELEASE(m_shadow_pass_hair_set_layout, vkDestroyDescriptorSetLayout, + m_pvkDevice); + } + + AMD_SAFE_RELEASE(m_pSamplerStateLinearWrap, vkDestroySampler, m_pvkDevice); + AMD_SAFE_RELEASE(m_pSamplerStatePointClamp, vkDestroySampler, m_pvkDevice); + AMD_SAFE_RELEASE(m_pSamplerStateCmpLess, vkDestroySampler, m_pvkDevice); + + AMD_SAFE_RELEASE(m_descriptorStorage, vkDestroyDescriptorPool, m_pvkDevice); + + // constant buffer + AMD_SAFE_RELEASE(m_pcbPerFrame, vkDestroyBuffer, m_pvkDevice); + AMD_SAFE_RELEASE(m_pcbPerFrameMemory, vkFreeMemory, m_pvkDevice); + + // PPLL buffers + DeletePPLL(m_pvkDevice); + + // textures and views + AMD_SAFE_RELEASE(m_pNoiseView, vkDestroyImageView, m_pvkDevice); + AMD_SAFE_RELEASE(m_pNoiseTexture, vkDestroyImage, m_pvkDevice); + AMD_SAFE_RELEASE(m_pNoiseMemory, vkFreeMemory, m_pvkDevice); + + // Hair shadow map depth stencil buffer + AMD_SAFE_RELEASE(m_pSMHairView, vkDestroyImageView, m_pvkDevice); + AMD_SAFE_RELEASE(m_pSMHairTexture, vkDestroyImage, m_pvkDevice); + AMD_SAFE_RELEASE(m_pSMHairMemory, vkFreeMemory, m_pvkDevice); +} + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXRendererVulkan.h b/amd_tressfx_vulkan/src/TressFXRendererVulkan.h new file mode 100644 index 0000000..c373db8 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXRendererVulkan.h @@ -0,0 +1,174 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXRenderer.h +// +// Header file for the main hair rendering code +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#pragma once +#include "AMD_TressFX.h" +#include "Math\Vector3D.h" +#include "TressFXMeshVulkan.h" +#include "TressFXShortCutVulkan.h" + +#define SM_HAIR_WIDTH 640 +#define SM_HAIR_HEIGHT 640 + +namespace AMD +{ + +class TressFXRenderer +{ + private: + VkDevice m_pvkDevice; + // We need 2 pass because buffer need to be flushed inbetween + VkRenderPass m_pRPHairRendering; + VkRenderPass m_RPHairShadow; + + // Layout + VkDescriptorSetLayout m_pass1_config_set_layout; + VkPipelineLayout m_pass1_layout; + VkDescriptorSetLayout m_pass2_set_layout; + VkPipelineLayout m_pass2_layout; + VkDescriptorSetLayout m_shadow_pass_config_set_layout; + VkPipelineLayout m_shadow_pass_layout; + VkDescriptorPool m_descriptorStorage; + VkDescriptorSet m_pass1_config_set; + VkDescriptorSet m_pass2_set; + VkDescriptorSet m_shadow_pass_set; + + // Pass 1 pipeline + VkPipeline m_pPLRenderHair; + VkPipeline m_pPLRenderHairStrandCopies; + VkPipeline m_pPLRenderHairAA; + VkPipeline m_pPLRenderHairAAStrandCopies; + // final rendering using a k-buffer for sorting the k nearest fragments + VkPipeline m_pPLResolveKBuffer; + // pipeline for generating the hair shadow map + VkPipeline m_pPLGenerateHairSM; + + // samplers + VkSampler m_pSamplerStateLinearWrap; + VkSampler m_pSamplerStatePointClamp; + VkSampler m_pSamplerStateCmpLess; + + // constant buffer + VkBuffer m_pcbPerFrame; + VkDeviceMemory m_pcbPerFrameMemory; + + // Buffers for the head of the per-pixel linked lists (PPLL) + VkImage m_pHeadPPLLTexture; + VkImageView m_pHeadPPLLView; + + // Buffers for the per-pixel linked list (PPLL) data + VkBuffer m_pPPLLBuffer; + + // Buffer for the atomic counter + VkBuffer m_pAtomicCounterPPLLBuffer; + + // textures and views + VkImage m_pNoiseTexture; + VkDeviceMemory m_pNoiseMemory; + VkImageView m_pNoiseView; + + // Hair shadow map depth stencil buffer + VkImage m_pSMHairTexture; + VkDeviceMemory m_pSMHairMemory; + VkImageView m_pSMHairView; + + // vertex buffer for full screen quad + VkBuffer m_pScreenQuadVB; + VkDeviceMemory m_pScreenQuadMemory; + + TressFXShortCut m_ShortCut; + + VkImageView m_depthBuffer; + VkImageView m_colorTexture; + VkFramebuffer m_renderHairFramebuffer; + VkFramebuffer m_shadowFrameBuffer; + + public: + VkDescriptorSetLayout m_pass1_hair_set_layout; + VkDescriptorSetLayout m_shadow_pass_hair_set_layout; + + // hair rendering params + TressFX_HairParams m_hairParams; + + // hair geometry + TressFXMesh *m_pTressFXMesh; + + private: + VkResult CreateFrameBuffer(VkDevice pvkDevice, VkImageView depthTextureView, + VkImageView colorTextureView, uint32_t width, + uint32_t height); + VkResult CreateTextureAndViews(VkDevice pvkDevice, uint32_t MemoryIndexGPU, + VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, + size_t &offsetInScratchBuffer); + VkResult CreateConstantBuffer(VkDevice pvkDevice, uint32_t maxUniformBuffer, + uint32_t MemoryIndexCPU); + VkResult CreateVertexBuffers(VkDevice pvkDevice, uint32_t MemoryIndexGPU, + VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, + size_t &offsetInScratchBuffer); + VkResult CreateSamplers(VkDevice pvkDevice); + VkResult CreateRenderStateObjects(VkDevice pvkDevice); + VkResult CreatePPLL(VkDevice pvkDevice, int winWidth, int winHeight, bool resize, + uint32_t MemoryIndexGPU); + VkResult CreateLayouts(VkDevice pvkDevice); + VkResult AllocateAndPopulateSets(VkDevice pvkDevice, bool isShortcut); + void DeletePPLL(VkDevice pvkDevice); + void RenderScreenQuad(VkCommandBuffer pcmdbuffer, VkPipeline pPipeline); + + public: + TressFXRenderer(void){}; + ~TressFXRenderer(void){}; + + VkImageView GetShadowMapSRV() { return m_pSMHairView; }; + VkResult OnCreateDevice(VkDevice pvkDevice, int winWidth, int winHeight, + bool bShortCutOn, uint32_t maxUniformBuffer, + uint32_t MemoryIndexCPU, uint32_t MemoryIndexGPU, + VkImageView depthTexture, VkImageView colorTexture, + VkCommandBuffer commandBuffer, VkDeviceMemory scratchMemory, + VkBuffer scratchBuffer, size_t &offsetInScratchBuffer); + VkResult OnResizedSwapChain(VkDevice pvkDevice, int winWidth, int WinHeight, + bool bShortCutOn, uint32_t MemoryIndexGPU); + void BeginHairFrame(VkDevice pvkDevice, DirectX::XMVECTOR eyePoint, + DirectX::XMVECTOR lightPosition, + DirectX::XMMATRIX *pModelTrasnsformForHead, + DirectX::XMMATRIX *pViewProj, + DirectX::XMMATRIX *pViewProjLightOut, float screenWidth, + float screenHeight, bool singleHeadTransform, + uint32_t uniformBufferIndex); + void GenerateShadowMap(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + float density, uint32_t uniformBufferIndex); + void RenderHair(VkDevice pvkDevice, VkCommandBuffer commandBuffer, uint32_t width, + uint32_t height, uint32_t uniformBufferIndex); + void RenderHairShortcut(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height, uint32_t uniformBufferIndex); + void EndHairFrame(VkDevice pvkDevice); + void OnDestroy(); +}; + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp new file mode 100644 index 0000000..852e76f --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp @@ -0,0 +1,865 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXShortCut.cpp +// +// TressFX ShortCut method. +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#include "TressFXShortCutVulkan.h" +#include "AMD_Types.h" +#include "TressFXPrecompiledShadersVulkan.h" +#include "UtilVulkan.h" +#include + +#ifndef AMD_V_RETURN +#define AMD_V_RETURN(x) \ + { \ + vr = (x); \ + if (vr != VK_SUCCESS) \ + { \ + return vr; \ + } \ + } +#endif + +// unreferenced formal parameter +#pragma warning(disable : 4100) + +// Constants must match in TressFXRender.hlsl + +// Clear value for depths resource +#define SHORTCUT_INITIAL_DEPTH 0x3f800000 + +// Number of depth layers to use. 2 or 3 supported. +#define SHORTCUT_NUM_DEPTHS 3 + +// Compute source color as weighted average of front fragments, vs blending in order. +#define SHORTCUT_WEIGHTED_AVERAGE 1 + +// Output color deterministically when fragments have the same depth. Requires additional +// clear of colors resource. +#define SHORTCUT_DETERMINISTIC 1 + +namespace AMD +{ + +VkResult GPUOnlyStructuredBuffer::Create(VkDevice pvkDevice, uint32_t structSize, + uint32_t structCount) +{ + VkResult vr; + + // Per-pixel Linked List (PPLL) buffer + VkBufferCreateInfo BufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + BufferDesc.size = structCount * structSize; + BufferDesc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &BufferDesc, NULL, &m_pBuffer)); + m_pvkDevice = pvkDevice; + + return VK_SUCCESS; +} + +void GPUOnlyStructuredBuffer::Destroy() +{ + if (m_pBuffer) + vkDestroyBuffer(m_pvkDevice, m_pBuffer, nullptr); +} + +VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidth, + int winHeight, + uint32_t texture_memory_index) +{ + m_pvkDevice = pvkDevice; + VkResult vr; + { + VkImageCreateInfo accumInvAlphaInfo = getImageCreateInfo( + VK_FORMAT_R16_SFLOAT, winWidth, winHeight, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); + AMD_V_RETURN(vkCreateImage(pvkDevice, &accumInvAlphaInfo, nullptr, + &m_pAccumInvAlphaTexture)); + m_pAccumInvAlphaMemory = + allocImageMemory(pvkDevice, m_pAccumInvAlphaTexture, texture_memory_index); + + VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + srDesc.format = VK_FORMAT_R16_SFLOAT; + srDesc.viewType = VK_IMAGE_VIEW_TYPE_2D; + srDesc.subresourceRange.levelCount = 1; + srDesc.subresourceRange.layerCount = 1; + srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + srDesc.image = m_pAccumInvAlphaTexture; + AMD_V_RETURN( + vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pAccumInvAlphaView)); + } + + { + VkImageCreateInfo fragmentDepthInfo = + getImageCreateInfo(VK_FORMAT_R32_UINT, winWidth, winHeight, + VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT, + SHORTCUT_NUM_DEPTHS); + AMD_V_RETURN(vkCreateImage(pvkDevice, &fragmentDepthInfo, nullptr, + &m_pFragmentDepthsTexture)); + + m_pFragmentDepthsMemory = + allocImageMemory(pvkDevice, m_pFragmentDepthsTexture, texture_memory_index); + + VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + srDesc.format = VK_FORMAT_R32_UINT; + srDesc.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + srDesc.subresourceRange.levelCount = 1; + srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + srDesc.subresourceRange.layerCount = SHORTCUT_NUM_DEPTHS; + srDesc.image = m_pFragmentDepthsTexture; + AMD_V_RETURN( + vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pFragmentDepthsView)); + } + +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + { + VkImageCreateInfo fragmentColorInfo = getImageCreateInfo( + VK_FORMAT_R16G16B16A16_SFLOAT, winWidth, winHeight, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); + AMD_V_RETURN(vkCreateImage(pvkDevice, &fragmentColorInfo, nullptr, + &m_pFragmentColorsTexture)); + + m_pFragmentColorsMemory = + allocImageMemory(pvkDevice, m_pFragmentColorsTexture, texture_memory_index); + + VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + srDesc.format = VK_FORMAT_R16G16B16A16_SFLOAT; + srDesc.viewType = VK_IMAGE_VIEW_TYPE_2D; + srDesc.subresourceRange.levelCount = 1; + srDesc.subresourceRange.layerCount = 1; + srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + srDesc.image = m_pFragmentColorsTexture; + AMD_V_RETURN( + vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pFragmentColorsView)); + } +#else + m_FragmentColors.Create(pd3dDevice, 4 * SHORTCUT_NUM_DEPTHS, winWidth * winHeight); +#endif + + return VK_SUCCESS; +} + +void TressFXShortCut::DestroyScreenSizedItems() +{ + AMD_SAFE_RELEASE(m_pFBRenderHair, vkDestroyFramebuffer, m_pvkDevice); + + AMD_SAFE_RELEASE(m_pFragmentColorsView, vkDestroyImageView, m_pvkDevice); + AMD_SAFE_RELEASE(m_pFragmentDepthsView, vkDestroyImageView, m_pvkDevice); + AMD_SAFE_RELEASE(m_pAccumInvAlphaView, vkDestroyImageView, m_pvkDevice); + + AMD_SAFE_RELEASE(m_pFragmentColorsMemory, vkFreeMemory, m_pvkDevice); + AMD_SAFE_RELEASE(m_pFragmentDepthsMemory, vkFreeMemory, m_pvkDevice); + AMD_SAFE_RELEASE(m_pAccumInvAlphaMemory, vkFreeMemory, m_pvkDevice); + + AMD_SAFE_RELEASE(m_pFragmentColorsTexture, vkDestroyImage, m_pvkDevice); + AMD_SAFE_RELEASE(m_pFragmentDepthsTexture, vkDestroyImage, m_pvkDevice); + AMD_SAFE_RELEASE(m_pAccumInvAlphaTexture, vkDestroyImage, m_pvkDevice); + m_FragmentColors.Destroy(); +} + +namespace +{ +VkAttachmentDescription getAttachmentDescription( + VkFormat format, VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp, + VkImageLayout inoutLayout, + VkAttachmentLoadOp stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VkAttachmentStoreOp stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE) +{ + return {0, format, VK_SAMPLE_COUNT_1_BIT, loadOp, + storeOp, stencilLoadOp, stencilStoreOp, inoutLayout, + inoutLayout}; +} + +VkRenderPass createRenderPass(VkDevice pvkDevice) +{ + VkRenderPassCreateInfo info{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO}; + + const VkAttachmentDescription attachments[] = { + // DS + getAttachmentDescription(VK_FORMAT_D24_UNORM_S8_UINT, VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_DONT_CARE), + // accumInvAlpha + getAttachmentDescription(VK_FORMAT_R16_SFLOAT, VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + // FragmentColor + getAttachmentDescription( + VK_FORMAT_R16G16B16A16_SFLOAT, VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), +#else +// TODO +#endif + // Result + getAttachmentDescription(VK_FORMAT_R8G8B8A8_SNORM, VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), + + }; + + VkAttachmentReference depthStencil{0, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + VkAttachmentReference accumInvAlpha{1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + VkAttachmentReference FragmentColor{2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; +#else +// TODO +#endif + VkAttachmentReference colorAttachment{3, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference colorResolveInputAttachments[] = {{1, VK_IMAGE_LAYOUT_GENERAL}, + {2, VK_IMAGE_LAYOUT_GENERAL}}; + + uint32_t untouchedAttachmentDepthResolve[] = {1}; + uint32_t untouchedAttachmentColorFill[] = {1}; + + const VkSubpassDescription subpasses[] = { + // Depth alpha + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &accumInvAlpha, nullptr, + &depthStencil, 0, nullptr}, + // Depth resolve + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, + &depthStencil, AMD_ARRAY_SIZE(untouchedAttachmentDepthResolve), + untouchedAttachmentDepthResolve}, + // Color fill + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &FragmentColor, nullptr, + &depthStencil, AMD_ARRAY_SIZE(untouchedAttachmentColorFill), + untouchedAttachmentColorFill}, + // Color resolve + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, AMD_ARRAY_SIZE(colorResolveInputAttachments), + colorResolveInputAttachments, 1, &colorAttachment, nullptr, &depthStencil, 0, + nullptr}, + }; + + const VkSubpassDependency dependencies[] = { + // Depth alpha modifies fragment depth image while depth resolve reads it + {0, 1, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT}, + {0, 2, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, VK_DEPENDENCY_BY_REGION_BIT}, + {0, 3, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT}, + // Depth resolve update depth attachement while color fill reads it + {1, 2, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT}, + {1, 3, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, VK_DEPENDENCY_BY_REGION_BIT}, + // color resolve consumes output from color fill + {2, 3, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT}, + }; + + info.attachmentCount = AMD_ARRAY_SIZE(attachments); + info.pAttachments = attachments; + info.subpassCount = AMD_ARRAY_SIZE(subpasses); + info.pSubpasses = subpasses; + info.dependencyCount = AMD_ARRAY_SIZE(dependencies); + info.pDependencies = dependencies; + + VkRenderPass result; + vkCreateRenderPass(pvkDevice, &info, nullptr, &result); + return result; +} +} + +//-------------------------------------------------------------------------------------- +// +// CreateRenderStateObjects +// +// Creates the pipelines for hair rendering +// +//-------------------------------------------------------------------------------------- +VkResult TressFXShortCut::CreateRenderStateObjects(VkDevice pvkDevice) +{ + m_pRPRenderHair = createRenderPass(pvkDevice); + + ShaderModule m_pPSDepthsAlpha(pvkDevice, depth_hair_data); + ShaderModule m_pPSFillColors(pvkDevice, fillcolors_hair_data); + + ShaderModule render_hair_aa_strand_copiesModule(pvkDevice, + render_hair_aa_strand_copies_vertex); + const VkPipelineShaderStageCreateInfo renderHairAAStrandCopiesDepthsAlphaStage[2] = { + getShaderStageCreateInfo(render_hair_aa_strand_copiesModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSDepthsAlpha.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairAAStrandCopiesDepthsAlphaDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pDepthWritesToColor_BS, + &CommonPipelineState::inputAssemblyTriangle, + renderHairAAStrandCopiesDepthsAlphaStage, m_depthPassPipelineLayout, + m_pRPRenderHair, 0); + + const VkPipelineShaderStageCreateInfo renderHairAAStrandCopiesFillColorsStage[2] = { + getShaderStageCreateInfo(render_hair_aa_strand_copiesModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSFillColors.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairAAStrandCopiesFillColorsDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pSum_BS, +#else + &m_pDepthTestEnabledNoDepthWritesStencilWriteIncrement_DSS, &m_pNoWrites_BS, +#endif + &CommonPipelineState::inputAssemblyTriangle, + renderHairAAStrandCopiesFillColorsStage, m_colorPassPipelineLayout, + m_pRPRenderHair, 2); + + ShaderModule RenderHairAAVertexShader(pvkDevice, render_hair_aa_vertex); + const VkPipelineShaderStageCreateInfo renderHairAADepthsAlphaStage[2] = { + getShaderStageCreateInfo(RenderHairAAVertexShader.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSDepthsAlpha.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairAADepthsAlphaDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pDepthWritesToColor_BS, + &CommonPipelineState::inputAssemblyTriangle, renderHairAADepthsAlphaStage, + m_depthPassPipelineLayout, m_pRPRenderHair, 0); + + const VkPipelineShaderStageCreateInfo renderHairAAFillColorsStage[2] = { + getShaderStageCreateInfo(RenderHairAAVertexShader.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSFillColors.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairAAFillColorsDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pSum_BS, +#else + &m_pDepthTestEnabledNoDepthWritesStencilWriteIncrement_DSS, &m_pNoWrites_BS, +#endif + &CommonPipelineState::inputAssemblyTriangle, renderHairAAFillColorsStage, + m_colorPassPipelineLayout, m_pRPRenderHair, 2); + + ShaderModule renderHairStrandCopiesVertexModule(pvkDevice, + render_hair_strand_copies_vertex); + const VkPipelineShaderStageCreateInfo renderHairStrandCopiesDepthsAlphaStage[2] = { + getShaderStageCreateInfo(renderHairStrandCopiesVertexModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSDepthsAlpha.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairStrandCopiesDepthsAlphaDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pDepthWritesToColor_BS, + &CommonPipelineState::inputAssemblyTriangle, + renderHairStrandCopiesDepthsAlphaStage, m_depthPassPipelineLayout, + m_pRPRenderHair, 0); + + const VkPipelineShaderStageCreateInfo renderHairStrandCopiesFillColorsStage[2] = { + getShaderStageCreateInfo(renderHairStrandCopiesVertexModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSFillColors.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairStrandCopiesFillColorsDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pSum_BS, +#else + &m_pDepthTestEnabledNoDepthWritesStencilWriteIncrement_DSS, &m_pNoWrites_BS, +#endif + &CommonPipelineState::inputAssemblyTriangle, + renderHairStrandCopiesFillColorsStage, m_colorPassPipelineLayout, + m_pRPRenderHair, 2); + + ShaderModule renderHairVertexModule(pvkDevice, render_hair_vertex); + const VkPipelineShaderStageCreateInfo renderHairDepthsAlphaStage[2] = { + getShaderStageCreateInfo(renderHairVertexModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSDepthsAlpha.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairDepthsAlphaDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pDepthWritesToColor_BS, + &CommonPipelineState::inputAssemblyTriangle, renderHairDepthsAlphaStage, + m_depthPassPipelineLayout, m_pRPRenderHair, 0); + + const VkPipelineShaderStageCreateInfo renderHairFillColorsStage[2] = { + getShaderStageCreateInfo(renderHairVertexModule.m_shaderModule, + VK_SHADER_STAGE_VERTEX_BIT, "main"), + getShaderStageCreateInfo(m_pPSFillColors.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo renderHairFillColorsDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutHair, +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + &CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc, + &CommonPipelineState::m_pSum_BS, +#else + &m_pDepthTestEnabledNoDepthWritesStencilWriteIncrement_DSS, &m_pNoWrites_BS, +#endif + &CommonPipelineState::inputAssemblyTriangle, renderHairFillColorsStage, + m_colorPassPipelineLayout, m_pRPRenderHair, 2); + + // Resolve depth + ShaderModule renderQuadVS(pvkDevice, pass2_vertex); + ShaderModule depth_resolve(pvkDevice, resolve_depth); + const VkPipelineShaderStageCreateInfo depthResolveStage[2] = { + getShaderStageCreateInfo(renderQuadVS.m_shaderModule, VK_SHADER_STAGE_VERTEX_BIT, + "main"), + getShaderStageCreateInfo(depth_resolve.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo depthResolveDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutQuad, + &CommonPipelineState::m_pDepthWriteEnabledStencilTestLess_DSS, + &CommonPipelineState::ColorWritesOff, + &CommonPipelineState::inputAssemblyTriangle, depthResolveStage, + m_depthPassPipelineLayout, m_pRPRenderHair, 1); + + // Resolve Color + ShaderModule color_resolve(pvkDevice, resolvecolors); + const VkPipelineShaderStageCreateInfo colorResolveStage[2] = { + getShaderStageCreateInfo(renderQuadVS.m_shaderModule, VK_SHADER_STAGE_VERTEX_BIT, + "main"), + getShaderStageCreateInfo(color_resolve.m_shaderModule, + VK_SHADER_STAGE_FRAGMENT_BIT, "main"), + }; + + const VkGraphicsPipelineCreateInfo colorResolveDesc = + CommonPipelineState::getBasePipelineCreateInfo( + &CommonPipelineState::m_pLayoutQuad, + &CommonPipelineState::DepthTestDisabledStencilTestLessDSS, + &CommonPipelineState::m_pResolveColor_BS, + &CommonPipelineState::inputAssemblyTriangle, colorResolveStage, + m_colorPassPipelineLayout, m_pRPRenderHair, 3); + + VkGraphicsPipelineCreateInfo pipelinesDesc[] = { + renderHairAAStrandCopiesDepthsAlphaDesc, + renderHairAAStrandCopiesFillColorsDesc, + renderHairAADepthsAlphaDesc, + renderHairAAFillColorsDesc, + renderHairStrandCopiesDepthsAlphaDesc, + renderHairStrandCopiesFillColorsDesc, + renderHairDepthsAlphaDesc, + renderHairFillColorsDesc, + depthResolveDesc, + colorResolveDesc}; + + VkPipeline pipelines[AMD_ARRAY_SIZE(pipelinesDesc)]; + + VkResult vr; + AMD_V_RETURN(vkCreateGraphicsPipelines(pvkDevice, VK_NULL_HANDLE, + AMD_ARRAY_SIZE(pipelinesDesc), pipelinesDesc, + nullptr, pipelines)); + + m_pPLRenderHairAAStrandCopiesDepthsAlpha = pipelines[0]; + m_pPLRenderHairAAStrandCopiesFillColors = pipelines[1]; + m_pPLRenderHairAADepthsAlpha = pipelines[2]; + m_pPLRenderHairAAFillColors = pipelines[3]; + m_pPLRenderHairStrandCopiesDepthsAlpha = pipelines[4]; + m_pPLRenderHairStrandCopiesFillColors = pipelines[5]; + m_pPLRenderHairDepthsAlpha = pipelines[6]; + m_pPLRenderHairFillColors = pipelines[7]; + m_pPLDepthResolve = pipelines[8]; + m_pPLColorResolve = pipelines[9]; + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// CreateLayouts +// +// Creates the descriptors set and pipeline layouts. +// +//-------------------------------------------------------------------------------------- +VkResult TressFXShortCut::CreateLayouts(VkDevice pvkDevice, + VkDescriptorSetLayout mesh_layout, + VkSampler noiseSamplerRef, + VkSampler shadowSamplerRef) +{ + VkResult vr; + + { + VkDescriptorSetLayoutCreateInfo info{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}; + VkDescriptorSetLayoutBinding bindings[] = { + // TressFX parameters + {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT}, + // Fragment depth + {IDSRV_HAIR_FRAGMENT_DEPTHS, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // Sampler for noise texture in VS + {IDSRV_NOISE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLER, 1, + VK_SHADER_STAGE_VERTEX_BIT, &noiseSamplerRef}, + // Noise texture + {IDSRV_NOISEMAP, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, + VK_SHADER_STAGE_VERTEX_BIT}, + }; + info.bindingCount = AMD_ARRAY_SIZE(bindings); + info.pBindings = bindings; + AMD_V_RETURN( + vkCreateDescriptorSetLayout(pvkDevice, &info, nullptr, &m_pSLDepthAlpha)); + } + + { + VkDescriptorSetLayoutCreateInfo info{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}; + VkDescriptorSetLayoutBinding bindings[] = { + // TressFX parameters + {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT}, + // Fragment depth + {IDSRV_HAIR_FRAGMENT_DEPTHS, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // Sampler for noise texture in VS + {IDSRV_NOISE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLER, 1, + VK_SHADER_STAGE_VERTEX_BIT, &noiseSamplerRef}, + // Noise texture + {IDSRV_NOISEMAP, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, + VK_SHADER_STAGE_VERTEX_BIT}, + // Hair shadow + {IDSRV_HAIRSM, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + // Hair shadow sampler + {IDSRV_SHADOW_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLER, 1, + VK_SHADER_STAGE_FRAGMENT_BIT, &shadowSamplerRef}, +// Fragment color +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + {IDSRV_HAIR_FRAGMENT_COLORS, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, +#else +// TODO +#endif + // inv alpha accum + {IDSRV_HAIR_ACCUM_INV_ALPHA, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, + VK_SHADER_STAGE_FRAGMENT_BIT}, + }; + info.bindingCount = AMD_ARRAY_SIZE(bindings); + info.pBindings = bindings; + AMD_V_RETURN( + vkCreateDescriptorSetLayout(pvkDevice, &info, nullptr, &m_pSLColors)); + } + + { + VkPipelineLayoutCreateInfo info{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO}; + VkDescriptorSetLayout set_layout[] = {m_pSLDepthAlpha, mesh_layout}; + + info.setLayoutCount = AMD_ARRAY_SIZE(set_layout); + info.pSetLayouts = set_layout; + AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &info, nullptr, + &m_depthPassPipelineLayout)); + } + + { + VkPipelineLayoutCreateInfo info{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO}; + VkDescriptorSetLayout set_layout[] = {m_pSLColors, mesh_layout}; + + info.setLayoutCount = AMD_ARRAY_SIZE(set_layout); + info.pSetLayouts = set_layout; + AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &info, nullptr, + &m_colorPassPipelineLayout)); + } + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// CreateFramebuffer +// +// Creates the framebuffer for every pass of the shortcut algorithm +// +//-------------------------------------------------------------------------------------- +VkResult TressFXShortCut::CreateFramebuffer(VkDevice pvkDevice, + VkImageView depthStencilView, + VkImageView colorView, uint32_t width, + uint32_t height) +{ + VkResult vr; + { + VkFramebufferCreateInfo info{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; + info.renderPass = m_pRPRenderHair; + info.height = height; + info.width = width; + info.layers = 1; +#if SHORTCUT_DETERMINISTIC && SHORTCUT_WEIGHTED_AVERAGE + VkImageView attachments[] = {depthStencilView, m_pAccumInvAlphaView, + m_pFragmentColorsView, colorView}; + info.attachmentCount = AMD_ARRAY_SIZE(attachments); + info.pAttachments = attachments; +#else +// TODO +#endif + AMD_V_RETURN(vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_pFBRenderHair)); + } + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// AllocateAndPopulateSets +// +// Allocate descriptor set and fills them +// +//-------------------------------------------------------------------------------------- +VkResult TressFXShortCut::AllocateAndPopulateSets(VkDevice pvkDevice, + VkBuffer configBuffer, + uint64_t configBufferSize, + VkImageView noiseMap, + VkImageView hairShadowMap) +{ + VkResult vr; + { + VkDescriptorPoolCreateInfo info{VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; + VkDescriptorPoolSize sizes[] = {{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 2}, + {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 5}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 5}, + {VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2}, + {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1}, + {VK_DESCRIPTOR_TYPE_SAMPLER, 5}}; + info.maxSets = 2; + info.poolSizeCount = AMD_ARRAY_SIZE(sizes); + info.pPoolSizes = sizes; + AMD_V_RETURN( + vkCreateDescriptorPool(pvkDevice, &info, nullptr, &m_pDPShortcutPool)); + } + + { + VkDescriptorSetLayout setLayout[] = {m_pSLDepthAlpha, m_pSLColors}; + VkDescriptorSetAllocateInfo info{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + info.descriptorPool = m_pDPShortcutPool; + info.descriptorSetCount = AMD_ARRAY_SIZE(setLayout); + info.pSetLayouts = setLayout; + VkDescriptorSet sets[AMD_ARRAY_SIZE(setLayout)]; + AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &info, sets)); + m_depthPassSet = sets[0]; + m_colorPassSet = sets[1]; + } + + VkDescriptorBufferInfo bufferdesc{configBuffer, 0, configBufferSize}; + VkDescriptorImageInfo noise_descriptor{VK_NULL_HANDLE, noiseMap, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + VkDescriptorImageInfo hairSM_descriptor{VK_NULL_HANDLE, hairShadowMap, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + VkDescriptorImageInfo hairFragmentDepthsDescriptor{ + VK_NULL_HANDLE, m_pFragmentDepthsView, VK_IMAGE_LAYOUT_GENERAL}; + VkDescriptorImageInfo hairFragmentColorDescriptor{ + VK_NULL_HANDLE, m_pFragmentColorsView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + VkDescriptorImageInfo hairAccumInvAlphaDescriptor{ + VK_NULL_HANDLE, m_pAccumInvAlphaView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + + VkWriteDescriptorSet writes[] = { + getWriteDescriptor(m_depthPassSet, IDSRV_CONSTANTS_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, &bufferdesc), + getWriteDescriptor(m_depthPassSet, IDSRV_HAIR_FRAGMENT_DEPTHS, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + &hairFragmentDepthsDescriptor), + getWriteDescriptor(m_depthPassSet, IDSRV_NOISEMAP, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &noise_descriptor), + + getWriteDescriptor(m_colorPassSet, IDSRV_CONSTANTS_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, &bufferdesc), + getWriteDescriptor(m_colorPassSet, IDSRV_HAIR_FRAGMENT_DEPTHS, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + &hairFragmentDepthsDescriptor), + getWriteDescriptor(m_colorPassSet, IDSRV_NOISEMAP, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &noise_descriptor), + getWriteDescriptor(m_colorPassSet, IDSRV_HAIRSM, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + &hairSM_descriptor), + getWriteDescriptor(m_colorPassSet, IDSRV_HAIR_FRAGMENT_COLORS, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + &hairFragmentColorDescriptor), + getWriteDescriptor(m_colorPassSet, IDSRV_HAIR_ACCUM_INV_ALPHA, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + &hairAccumInvAlphaDescriptor), + }; + + vkUpdateDescriptorSets(pvkDevice, AMD_ARRAY_SIZE(writes), writes, 0, nullptr); + + return VK_SUCCESS; +} + +VkResult TressFXShortCut::OnCreateDevice( + VkDevice pd3dDevice, int winWidth, int winHeight, VkDescriptorSetLayout mesh_layout, + VkSampler noiseSamplerRef, VkSampler shadowSamplerRef, VkImageView depthStencilView, + VkImageView colorView, VkBuffer configBuffer, uint64_t configBufferSize, + VkImageView noiseMap, VkImageView hairShadowMap, uint32_t deviceLocalMemoryIndex, + uint32_t width, uint32_t height) +{ + VkResult vr; + + AMD_V_RETURN( + CreateScreenSizedItems(pd3dDevice, winWidth, winHeight, deviceLocalMemoryIndex)); + AMD_V_RETURN( + CreateLayouts(pd3dDevice, mesh_layout, noiseSamplerRef, shadowSamplerRef)); + AMD_V_RETURN(CreateRenderStateObjects(pd3dDevice)); + AMD_V_RETURN( + CreateFramebuffer(pd3dDevice, depthStencilView, colorView, width, height)); + AMD_V_RETURN(AllocateAndPopulateSets(pd3dDevice, configBuffer, configBufferSize, + noiseMap, hairShadowMap)) + + return VK_SUCCESS; +} + +VkResult TressFXShortCut::OnResizedSwapChain(VkDevice pd3dDevice, int winWidth, + int winHeight, + uint32_t deviceLocalMemoryIndex) +{ + DestroyScreenSizedItems(); + + VkResult vr; + AMD_V_RETURN( + CreateScreenSizedItems(pd3dDevice, winWidth, winHeight, deviceLocalMemoryIndex)); + return VK_SUCCESS; +} + +void TressFXShortCut::OnDestroy(bool destroyShaders) +{ + DestroyScreenSizedItems(); + + if (destroyShaders) + { + AMD_SAFE_RELEASE(m_pPLRenderHairAAStrandCopiesDepthsAlpha, vkDestroyPipeline, + m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairAAStrandCopiesFillColors, vkDestroyPipeline, + m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairAADepthsAlpha, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairAAFillColors, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairStrandCopiesDepthsAlpha, vkDestroyPipeline, + m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairStrandCopiesFillColors, vkDestroyPipeline, + m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairDepthsAlpha, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLRenderHairFillColors, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLDepthResolve, vkDestroyPipeline, m_pvkDevice); + AMD_SAFE_RELEASE(m_pPLColorResolve, vkDestroyPipeline, m_pvkDevice); + + AMD_SAFE_RELEASE(m_pRPRenderHair, vkDestroyRenderPass, m_pvkDevice); + + AMD_SAFE_RELEASE(m_depthPassPipelineLayout, vkDestroyPipelineLayout, m_pvkDevice); + AMD_SAFE_RELEASE(m_colorPassPipelineLayout, vkDestroyPipelineLayout, m_pvkDevice); + AMD_SAFE_RELEASE(m_pSLDepthAlpha, vkDestroyDescriptorSetLayout, m_pvkDevice); + AMD_SAFE_RELEASE(m_pSLColors, vkDestroyDescriptorSetLayout, m_pvkDevice); + } + AMD_SAFE_RELEASE(m_pDPShortcutPool, vkDestroyDescriptorPool, m_pvkDevice); +} + +void TressFXShortCut::SetupDepthPass(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height) +{ + VkClearColorValue dwDepthClearMax{}; + dwDepthClearMax.uint32[0] = SHORTCUT_INITIAL_DEPTH; + dwDepthClearMax.uint32[1] = SHORTCUT_INITIAL_DEPTH; + dwDepthClearMax.uint32[2] = SHORTCUT_INITIAL_DEPTH; + dwDepthClearMax.uint32[3] = SHORTCUT_INITIAL_DEPTH; + VkImageSubresourceRange range{}; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.layerCount = SHORTCUT_NUM_DEPTHS; + range.levelCount = 1; + vkCmdClearColorImage(commandBuffer, m_pFragmentDepthsTexture, VK_IMAGE_LAYOUT_GENERAL, + &dwDepthClearMax, 1, &range); + + { + VkRenderPassBeginInfo info{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO}; + info.framebuffer = m_pFBRenderHair; + info.renderPass = m_pRPRenderHair; + info.renderArea.extent.height = height; + info.renderArea.extent.width = width; + VkClearValue clearValue[3]; + clearValue[0].depthStencil.stencil = 0; + // alpha + clearValue[1].color.float32[0] = 1; + clearValue[1].color.float32[1] = 1; + clearValue[1].color.float32[2] = 1; + clearValue[1].color.float32[3] = 1; + // color + clearValue[2].color.float32[0] = 0.; + clearValue[2].color.float32[1] = 0.; + clearValue[2].color.float32[2] = 0.; + clearValue[2].color.float32[3] = 0.; + info.clearValueCount = 3; + info.pClearValues = clearValue; + vkCmdBeginRenderPass(commandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } +} + +void TressFXShortCut::SetupResolveDepth(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height) +{ + vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); +} + +void TressFXShortCut::SetupShadePass(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height) +{ + vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); +} + +void TressFXShortCut::SetupResolveColor(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height) +{ + vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); +} +} diff --git a/amd_tressfx_vulkan/src/TressFXShortCutVulkan.h b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.h new file mode 100644 index 0000000..89c5a6d --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.h @@ -0,0 +1,142 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXShortCut.h +// +// Header file for TressFX ShortCut method. +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#pragma once +#include "AMD_TressFX.h" +#include "Math\Vector3D.h" + +namespace AMD +{ +struct GPUOnlyStructuredBuffer +{ + GPUOnlyStructuredBuffer() : m_pBuffer(nullptr), m_pvkDevice(nullptr) {} + VkResult Create(VkDevice pd3dDevice, uint32_t structCount, uint32_t structSize); + void Destroy(); + + VkBuffer m_pBuffer; + + private: + VkDevice m_pvkDevice; +}; + +class TressFXShortCut +{ + private: + VkDevice m_pvkDevice; + VkDescriptorPool m_pDPShortcutPool; + + VkDescriptorSetLayout m_pSLDepthAlpha; + VkDescriptorSetLayout m_pSLColors; + + VkRenderPass m_pRPRenderHair; + VkFramebuffer m_pFBRenderHair; + + public: + VkPipelineLayout m_depthPassPipelineLayout; + VkPipelineLayout m_colorPassPipelineLayout; + VkDescriptorSet m_depthPassSet; + VkDescriptorSet m_colorPassSet; + // Pipelines for depth alpha + VkPipeline m_pPLRenderHairDepthsAlpha; + VkPipeline m_pPLRenderHairStrandCopiesDepthsAlpha; + VkPipeline m_pPLRenderHairAADepthsAlpha; + VkPipeline m_pPLRenderHairAAStrandCopiesDepthsAlpha; + // Pipeline for depth resolve + VkPipeline m_pPLDepthResolve; + // Pipelines for color filling + VkPipeline m_pPLRenderHairFillColors; + VkPipeline m_pPLRenderHairAAStrandCopiesFillColors; + VkPipeline m_pPLRenderHairAAFillColors; + VkPipeline m_pPLRenderHairStrandCopiesFillColors; + // Pipeline for color resolve + VkPipeline m_pPLColorResolve; + + VkImage m_pFragmentColorsTexture; + VkDeviceMemory m_pFragmentColorsMemory; + VkImageView m_pFragmentColorsView; + + VkImage m_pFragmentDepthsTexture; + VkDeviceMemory m_pFragmentDepthsMemory; + VkImageView m_pFragmentDepthsView; + + VkImage m_pAccumInvAlphaTexture; + VkDeviceMemory m_pAccumInvAlphaMemory; + VkImageView m_pAccumInvAlphaView; + + private: + GPUOnlyStructuredBuffer m_FragmentColors; + + VkResult CreateScreenSizedItems(VkDevice pvkDevice, int winWidth, int winHeight, + uint32_t MemoryIndexGPU); + void DestroyScreenSizedItems(); + VkResult CreateRenderStateObjects(VkDevice pvkDevice); + VkResult CreateLayouts(VkDevice pvkDevice, VkDescriptorSetLayout SLMesh, + VkSampler noiseSamplerRef, VkSampler shadowSamplerRef); + VkResult CreateFramebuffer(VkDevice pvkDevice, VkImageView depthStencilView, + VkImageView colorView, uint32_t width, uint32_t height); + VkResult AllocateAndPopulateSets(VkDevice pvkDevice, VkBuffer configBuffer, + uint64_t configBufferSize, VkImageView noiseMap, + VkImageView hairShadowMap); + + public: + TressFXShortCut(void) + : m_pFragmentColorsTexture(nullptr), m_pFragmentColorsMemory(nullptr), + m_pFragmentColorsView(nullptr), m_pFragmentDepthsTexture(nullptr), + m_pFragmentDepthsMemory(nullptr), m_pFragmentDepthsView(nullptr), + m_pAccumInvAlphaTexture(nullptr), m_pAccumInvAlphaMemory(nullptr), + m_pAccumInvAlphaView(nullptr) + { + } + ~TressFXShortCut(void){}; + + VkResult OnCreateDevice(VkDevice pvkDevice, int winWidth, int winHeight, + VkDescriptorSetLayout mesh_layout, VkSampler noiseSamplerRef, + VkSampler shadowSamplerRef, VkImageView depthStencilView, + VkImageView colorView, VkBuffer configBuffer, + uint64_t configBufferSize, VkImageView noiseMap, + VkImageView hairShadowMap, uint32_t deviceLocalMemoryIndex, + uint32_t width, uint32_t height); + VkResult OnResizedSwapChain(VkDevice pvkDevice, int winWidth, int WinHeight, + uint32_t deviceLocalMemoryIndex); + + // Individual render pass setups. + // Each basically sets up render state, UAVs, SRVs, and returns pixel + // shader to use. + void SetupDepthPass(VkDevice pvkDevice, VkCommandBuffer commandBuffer, uint32_t width, + uint32_t height); + void SetupShadePass(VkDevice pvkDevice, VkCommandBuffer commandBuffer, uint32_t width, + uint32_t height); + void SetupResolveDepth(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height); + void SetupResolveColor(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height); + + void OnDestroy(bool destroyShaders); +}; + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp new file mode 100644 index 0000000..e422ae4 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp @@ -0,0 +1,1180 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXSimulation.cpp +// +// Hair physics simulation using DirectCompute +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#include "TressFXSimulationVulkan.h" +#include "AMD_Types.h" +#include "Math\\Transform.h" +#include "TressFXMeshVulkan.h" +#include "TressFXPrecompiledShadersVulkan.h" +#include "UtilVulkan.h" + +#include + +using namespace DirectX; + +extern int g_TressFXNumVerticesPerStrand; + +struct TransformConstantBuffer +{ + DirectX::XMMATRIX ModelTransformForHead; +}; + +struct ConstBufferCS_Per_Frame +{ + float4 Wind; + float4 Wind1; + float4 Wind2; + float4 Wind3; + + int NumLengthConstraintIterations; + int bCollision; + + float GravityMagnitude; + float timeStep; + + float Damping0; + float StiffnessForLocalShapeMatching0; + float StiffnessForGlobalShapeMatching0; + float GlobalShapeMatchingEffectiveRange0; + + float Damping1; + float StiffnessForLocalShapeMatching1; + float StiffnessForGlobalShapeMatching1; + float GlobalShapeMatchingEffectiveRange1; + + float Damping2; + float StiffnessForLocalShapeMatching2; + float StiffnessForGlobalShapeMatching2; + float GlobalShapeMatchingEffectiveRange2; + + float Damping3; + float StiffnessForLocalShapeMatching3; + float StiffnessForGlobalShapeMatching3; + float GlobalShapeMatchingEffectiveRange3; + + unsigned int NumOfStrandsPerThreadGroup; + unsigned int NumFollowHairsPerGuideHair; + float TipSeparationFactor; + + int bWarp; + int NumLocalShapeMatchingIterations; + + int NumVerticesPerStrand; // should be 2^n (n is integer and greater and 3) and less + // than or equal to THREAD_GROUP_SIZE. i.e. 8, 16, 32 or 64 + float pad[2]; +}; + +struct ConstBufferCS_HeadTransform +{ + DirectX::XMMATRIX ModelTransformForHead; + XMVECTOR ModelRotateForHead; // quaternion + int bSingleHeadTransform; + float padding[3]; +}; + +namespace AMD +{ + +//-------------------------------------------------------------------------------------- +// +// Constructor +// +//-------------------------------------------------------------------------------------- +TressFXSimulation::TressFXSimulation(void) +{ + m_CSIntegrationAndGlobalShapeConstraints = NULL; + m_CSApplyHairTransformGlobally = NULL; + m_CSComputeTangents = NULL; + m_CSLocalShapeConstraints = NULL; + m_CSLengthConstriantsWindAndCollision = NULL; + m_CSUpdateFollowHairVertices = NULL; + m_CSPrepareFollowHairBeforeTurningIntoGuide = NULL; + m_pCBCSPerFrame = NULL; + m_pCBCSCollisionCapsule = NULL; + m_pCBHeadTransforms = NULL; + + m_simParams.numLengthConstraintIterations = 2; + m_simParams.numLocalShapeMatchingIterations = 1; + m_simParams.gravityMagnitude = 9.82f; + + m_simParams.bCollision = true; + m_simParams.bGuideFollowSimulation = true; + m_bGuideFollowHairPrev = m_simParams.bGuideFollowSimulation; + + m_elapsedTimeSinceLastSim = 0; +} + +//-------------------------------------------------------------------------------------- +// +// Destructor +// +//-------------------------------------------------------------------------------------- +TressFXSimulation::~TressFXSimulation(void) {} + +namespace +{ +VkComputePipelineCreateInfo getComputePipelineInfo(VkPipelineLayout layout, + VkShaderModule computeShader) +{ + VkComputePipelineCreateInfo result{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO}; + result.layout = layout; + result.stage.module = computeShader; + result.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + result.stage.pName = "main"; + result.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; + return result; +} +} + +namespace +{ +VkResult getPipelineLayout(VkDevice pvkDevice, VkDescriptorSetLayout configSetLayout, + VkDescriptorSetLayout secondSetLayout, + VkPipelineLayout &result) +{ + VkPipelineLayoutCreateInfo pipelineInfo{ + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO}; + VkDescriptorSetLayout setLayouts[] = {configSetLayout, secondSetLayout}; + pipelineInfo.setLayoutCount = AMD_ARRAY_SIZE(setLayouts); + pipelineInfo.pSetLayouts = setLayouts; + VkResult vr; + AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &pipelineInfo, nullptr, &result)); + return VK_SUCCESS; +} +} + +VkResult TressFXSimulation::CreateDescriptorSet(VkDevice pvkDevice) +{ + VkResult vr; + + const VkDescriptorSetLayoutBinding global_constraints_bindings[] = { + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_VERTEX_INITIAL_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + }; + + const VkDescriptorSetLayoutBinding local_constraints_bindings[] = { + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_GLOBAL_ROTATION, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_LOCAL_REF_VEC, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + }; + + const VkDescriptorSetLayoutBinding length_wind_collision_bindings[] = { + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_LENGTH, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + }; + + const VkDescriptorSetLayoutBinding prepare_follow_hair_bindings[] = { + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + }; + + const VkDescriptorSetLayoutBinding update_follow_hair_bindings[] = { + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_ROOT_OFFSET, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + }; + + const VkDescriptorSetLayoutBinding compute_tangent_bindings[] = { + {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HAIR_TANGENTS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + }; + + AMD_V_RETURN(getDescriptorLayout(pvkDevice, global_constraints_bindings, + AMD_ARRAY_SIZE(global_constraints_bindings), + m_GlobalConstraintsSetLayout)); + AMD_V_RETURN(getDescriptorLayout(pvkDevice, local_constraints_bindings, + AMD_ARRAY_SIZE(local_constraints_bindings), + m_LocalConstraintsSetLayout)); + AMD_V_RETURN(getDescriptorLayout(pvkDevice, length_wind_collision_bindings, + AMD_ARRAY_SIZE(length_wind_collision_bindings), + m_LenghtWindTangentSetLayout)); + AMD_V_RETURN(getDescriptorLayout(pvkDevice, prepare_follow_hair_bindings, + AMD_ARRAY_SIZE(prepare_follow_hair_bindings), + m_PrepareFollowHairSetLayout)); + AMD_V_RETURN(getDescriptorLayout(pvkDevice, update_follow_hair_bindings, + AMD_ARRAY_SIZE(update_follow_hair_bindings), + m_UpdateFollowHaitSetLayout)); + AMD_V_RETURN(getDescriptorLayout(pvkDevice, compute_tangent_bindings, + AMD_ARRAY_SIZE(compute_tangent_bindings), + m_ComputeTangentSetLayout)); + + const VkDescriptorSetLayoutBinding configBindings[] = { + {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, + VK_SHADER_STAGE_COMPUTE_BIT}, + {IDSRV_HEAD_TRANSFORM, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_COMPUTE_BIT}}; + AMD_V_RETURN(getDescriptorLayout(pvkDevice, configBindings, + AMD_ARRAY_SIZE(configBindings), m_configSetLayout)); + + AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, + m_GlobalConstraintsSetLayout, + m_CSIntegrationAndGlobalShapeConstraintsLayout)); + AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, + m_LocalConstraintsSetLayout, + m_CSLocalShapeConstraintsLayout)); + AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, + m_LocalConstraintsSetLayout, + m_CSLocalShapeConstraintsSingleDispatchLayout)); + AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, + m_LenghtWindTangentSetLayout, + m_CSLengthConstriantsWindAndCollisionLayout)); + AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, + m_PrepareFollowHairSetLayout, + m_CSPrepareFollowHairBeforeTurningIntoGuideLayout)); + AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, + m_UpdateFollowHaitSetLayout, + m_CSUpdateFollowHairVerticesLayout)); + AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, + m_ComputeTangentSetLayout, m_CSComputeTangentsLayout)); + + VkDescriptorPoolSize poolSizes[] = {{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1}, + {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}}; + VkDescriptorPoolCreateInfo descriptorPoolInfo{ + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; + descriptorPoolInfo.maxSets = 1; + descriptorPoolInfo.poolSizeCount = AMD_ARRAY_SIZE(poolSizes); + descriptorPoolInfo.pPoolSizes = poolSizes; + AMD_V_RETURN(vkCreateDescriptorPool(pvkDevice, &descriptorPoolInfo, nullptr, + &m_descriptorPool)); + + VkDescriptorSetAllocateInfo allocInfo{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + allocInfo.descriptorSetCount = 1; + allocInfo.pSetLayouts = &m_configSetLayout; + allocInfo.descriptorPool = m_descriptorPool; + + AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &allocInfo, &m_configSet)); + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// OnCreateDevice +// +// Called when the D3D device is being created. Creates the compute shaders and the D3D +// resources used for the hair simulation. +// +//-------------------------------------------------------------------------------------- +VkResult TressFXSimulation::OnCreateDevice(VkDevice pvkDevice, + TressFX_CollisionCapsule *pCollision, + uint32_t maxUniformCount, + uint32_t cpu_memory_index, + uint32_t gpu_memory_index) +{ + VkResult vr; + AMD_V_RETURN(CreateDescriptorSet(pvkDevice)); + // reset m_elapsedTimeSinceLastSim to zero + m_elapsedTimeSinceLastSim = 0; + + ShaderModule IntegrationAndGlobalShapeConstraints_Module(pvkDevice, + global_constraints); + // TODO + ShaderModule ApplyHairTransformGlobally_Module(pvkDevice, global_constraints); + ShaderModule ComputeTangents_Module(pvkDevice, compute_tangents); + ShaderModule LocalShapeConstraints_Module(pvkDevice, local_constraints); + ShaderModule LocalShapeConstraintsWithIteration_Module(pvkDevice, local_constraints); + ShaderModule LengthConstraintsWindAndCollision_Module(pvkDevice, + length_wind_collision); + ShaderModule UpdateFollowHairVertices_Module(pvkDevice, update_follow_hair); + ShaderModule PrepareFollowHairBeforeTurningIntoGuide_Data(pvkDevice, + prepare_follow_hair); + // TODO + ShaderModule GenerateTransforms_Module(pvkDevice, global_constraints); + + VkComputePipelineCreateInfo computePipelineInfo[] = { + getComputePipelineInfo( + m_CSIntegrationAndGlobalShapeConstraintsLayout, + IntegrationAndGlobalShapeConstraints_Module.m_shaderModule), + getComputePipelineInfo(m_CSIntegrationAndGlobalShapeConstraintsLayout, + ApplyHairTransformGlobally_Module.m_shaderModule), + getComputePipelineInfo(m_CSComputeTangentsLayout, + ComputeTangents_Module.m_shaderModule), + getComputePipelineInfo(m_CSLocalShapeConstraintsSingleDispatchLayout, + LocalShapeConstraints_Module.m_shaderModule), + getComputePipelineInfo(m_CSLocalShapeConstraintsLayout, + LocalShapeConstraintsWithIteration_Module.m_shaderModule), + getComputePipelineInfo(m_CSLengthConstriantsWindAndCollisionLayout, + LengthConstraintsWindAndCollision_Module.m_shaderModule), + getComputePipelineInfo(m_CSUpdateFollowHairVerticesLayout, + UpdateFollowHairVertices_Module.m_shaderModule), + getComputePipelineInfo( + m_CSPrepareFollowHairBeforeTurningIntoGuideLayout, + PrepareFollowHairBeforeTurningIntoGuide_Data.m_shaderModule), + getComputePipelineInfo(m_CSIntegrationAndGlobalShapeConstraintsLayout, + GenerateTransforms_Module.m_shaderModule), + }; + + VkPipeline pipelines[9]{}; + AMD_V_RETURN(vkCreateComputePipelines(pvkDevice, VK_NULL_HANDLE, + AMD_ARRAY_SIZE(computePipelineInfo), + computePipelineInfo, nullptr, pipelines)); + + m_CSIntegrationAndGlobalShapeConstraints = pipelines[0]; + m_CSApplyHairTransformGlobally = pipelines[1]; + m_CSComputeTangents = pipelines[2]; + m_CSLocalShapeConstraints = pipelines[3]; + m_CSLocalShapeConstraintsSingleDispatch = pipelines[4]; + m_CSLengthConstriantsWindAndCollision = pipelines[5]; + m_CSUpdateFollowHairVertices = pipelines[6]; + m_CSPrepareFollowHairBeforeTurningIntoGuide = pipelines[7]; + m_CSGenerateTransforms = pipelines[8]; + + //------------------------- + // Create constant buffers + //------------------------- + AMD_V_RETURN(CreateComputeShaderConstantBuffers( + pvkDevice, pCollision, maxUniformCount, cpu_memory_index, gpu_memory_index)); + + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// GenerateTransforms +// +// Create an array of transformation matrices, one for each hair strand, and an associated +// quaternion for the rotation. The transformations generated are based on the position +// of the skinned (deformed) model that the hair strands are on. These transformations +// can be used for simulating the positions and orientations of fur strands on an +// animated mesh. +// +//-------------------------------------------------------------------------------------- +// VkResult TressFXSimulation::GenerateTransforms(ID3D11DeviceContext* pd3dContext, +// TressFX_SceneMesh sceneMesh, +// ID3D11UnorderedAccessView** +// ppSkinningTransformationsUAV, +// XMMATRIX *pModelTransformForHead) +//{ +// VkResult vr = VK_SUCCESS; +// +// // update the constant buffers +// D3D11_MAPPED_SUBRESOURCE MappedResource; +// +// pd3dContext->Map(m_pCBCSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource); +// { +// ConstBufferCS_Per_Frame* pCSPerFrame = +// (ConstBufferCS_Per_Frame*)MappedResource.pData; +// +// int numOfStrandsPerThreadGroup = THREAD_GROUP_SIZE / +// m_pTressFXMesh->m_HairAsset.m_NumOfVerticesInStrand; +// pCSPerFrame->NumOfStrandsPerThreadGroup = numOfStrandsPerThreadGroup; +// pCSPerFrame->NumFollowHairsPerGuideHair = (m_bGuideFollowHairPrev ? +// m_pTressFXMesh->m_HairAsset.m_NumFollowHairsPerGuideHair : 0); +// } +// pd3dContext->Unmap(m_pCBCSPerFrame, 0); +// pd3dContext->CSSetConstantBuffers(0, 1, &m_pCBCSPerFrame); +// +// pd3dContext->Map(m_pCBGenerateTransforms, 0, D3D11_MAP_WRITE_DISCARD, 0, +// &MappedResource); +// { +// TransformConstantBuffer* pCSTransformCB = +// (TransformConstantBuffer*)MappedResource.pData; +// pCSTransformCB->ModelTransformForHead = *pModelTransformForHead; +// } +// pd3dContext->Unmap(m_pCBGenerateTransforms, 0); +// pd3dContext->CSSetConstantBuffers(4, 1, &m_pCBGenerateTransforms); +// +// //Set the shader resources +// ID3D11ShaderResourceView* ppSRV[3] = {sceneMesh.pMeshVertices, +// sceneMesh.pTransformedVerts, m_pTressFXMesh->m_HairSkinMappingSRV}; +// +// pd3dContext->CSSetShaderResources( 4, 3, ppSRV); +// +// //Bind unordered access views +// ID3D11UnorderedAccessView* ppUAV[4] = {m_pTressFXMesh->m_InitialHairPositionsUAV, 0, +// 0, m_pTressFXMesh->m_HairTransformsUAV}; +// pd3dContext->CSSetUnorderedAccessViews( 3, 4, ppUAV, NULL ); +// +// // execute the shader +// int numOfGroupsForCS_StrandLevel = (m_bGuideFollowHairPrev ? +// m_pTressFXMesh->m_HairAsset.m_NumGuideHairStrands : +// m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands); +// +// pd3dContext->CSSetShader(m_CSGenerateTransforms, NULL, 0 ); +// pd3dContext->Dispatch(numOfGroupsForCS_StrandLevel, 1, 1); +// +// *ppSkinningTransformationsUAV = m_pTressFXMesh->m_HairTransformsUAV; +// +// // unbind the resources +// ppSRV [0] = NULL; +// ppSRV [1] = NULL; +// ppSRV [2] = NULL; +// pd3dContext->CSSetShaderResources( 4, 3, ppSRV); +// +// ID3D11UnorderedAccessView* ppUAVNULL[4] = {NULL, NULL, NULL, NULL}; +// pd3dContext->CSSetUnorderedAccessViews( 3, 4, ppUAVNULL, NULL ); +// +// return vr; +//} + +//// Applies skin transforms to all hair so that hair would do rigid transform +// HRESULT TressFXSimulation::ApplyTransformGlobally(ID3D11DeviceContext* pd3dContext, +// ID3D11UnorderedAccessView* pSkinningTransforms, float density, bool +// singleHeadTransform, XMMATRIX *pModelTransformForHead) +//{ +// int numOfStrandsPerThreadGroup = THREAD_GROUP_SIZE / +// m_pTressFXMesh->m_HairAsset.m_NumOfVerticesInStrand; +// +// // ConstBufferCS_Per_Frame +// D3D11_MAPPED_SUBRESOURCE MappedResource; +// +// pd3dContext->Map(m_pCBCSPerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource); +// { +// ConstBufferCS_Per_Frame* pCSPerFrame = +// (ConstBufferCS_Per_Frame*)MappedResource.pData; +// pCSPerFrame->NumOfStrandsPerThreadGroup = numOfStrandsPerThreadGroup; +// pCSPerFrame->NumFollowHairsPerGuideHair = (m_bGuideFollowHairPrev ? +// m_pTressFXMesh->m_HairAsset.m_NumFollowHairsPerGuideHair : 0); +// pCSPerFrame->TipSeparationFactor = +// m_pTressFXMesh->m_HairAsset.m_TipSeparationFactor; +// pCSPerFrame->NumVerticesPerStrand = g_TressFXNumVerticesPerStrand; +// } +// pd3dContext->Unmap(m_pCBCSPerFrame, 0); +// +// // ConstBufferCS_HeadTransform +// pd3dContext->Map(m_pCBHeadTransforms, 0, D3D11_MAP_WRITE_DISCARD, 0, +// &MappedResource); +// { +// ConstBufferCS_HeadTransform* pCSHeadTransform = +// (ConstBufferCS_HeadTransform*)MappedResource.pData; +// pCSHeadTransform->bSingleHeadTransform = singleHeadTransform; +// pCSHeadTransform->ModelRotateForHead = +// XMQuaternionRotationMatrix(*pModelTransformForHead); +// pCSHeadTransform->ModelTransformForHead = *pModelTransformForHead; +// } +// pd3dContext->Unmap(m_pCBHeadTransforms, 0); +// +// // set const buffers +// pd3dContext->CSSetConstantBuffers(0, 1, &m_pCBCSPerFrame); +// pd3dContext->CSSetConstantBuffers(5, 1, &m_pCBHeadTransforms); +// +// //Set the shader resources +// ID3D11ShaderResourceView* ppSRV[4] = { NULL, NULL, NULL, +// m_pTressFXMesh->m_FollowHairRootOffsetSRV }; +// pd3dContext->CSSetShaderResources(0, 4, ppSRV); +// +// //Bind unordered access views +// ID3D11UnorderedAccessView* ppUAV[8] = +// { +// m_pTressFXMesh->m_HairVertexPositionsUAV, +// m_pTressFXMesh->m_HairVertexPositionsPrevUAV, +// m_pTressFXMesh->m_HairVertexTangentsUAV, +// m_pTressFXMesh->m_InitialHairPositionsUAV, +// m_pTressFXMesh->m_GlobalRotationsUAV, +// m_pTressFXMesh->m_LocalRotationsUAV, +// pSkinningTransforms +// }; +// +// UINT initCounts = 0; +// pd3dContext->CSSetUnorderedAccessViews(0, 8, ppUAV, &initCounts); +// +// //======= Run the compute shader ======= +// int numOfGroupsForCS_VertexLevel = (int)(((float)(m_bGuideFollowHairPrev ? +// m_pTressFXMesh->m_HairAsset.m_NumGuideHairVertices : +// m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices) / +//(float)THREAD_GROUP_SIZE)*density); +// +// // One thread computes one vertex +// pd3dContext->CSSetShader(m_CSApplyHairTransformGlobally, NULL, 0); +// pd3dContext->Dispatch(numOfGroupsForCS_VertexLevel, 1, 1); +// +// // Update follow hair vertices +// // One thread computes one vertex +// if (m_bGuideFollowHairPrev) +// { +// pd3dContext->CSSetShader(m_CSUpdateFollowHairVertices, NULL, 0); +// pd3dContext->Dispatch(numOfGroupsForCS_VertexLevel, 1, 1); +// } +// +// // Compute tangents for every vertex (guide + follow) +// int numOfGroupsForCS_TotalVertexLevel = +//(int)(((float)(m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices) / +//(float)THREAD_GROUP_SIZE)*density); +// pd3dContext->CSSetShader(m_CSComputeTangents, NULL, 0); +// pd3dContext->Dispatch(numOfGroupsForCS_TotalVertexLevel, 1, 1); +// +// // Unbind resources for CS +// ID3D11UnorderedAccessView* ppUAViewNULL[8] = { NULL, NULL, NULL, NULL, NULL, NULL, +// NULL, NULL }; +// pd3dContext->CSSetUnorderedAccessViews(0, 8, ppUAViewNULL, &initCounts); +// +// ID3D11ShaderResourceView* ppSRVNULL[4] = { NULL, NULL, NULL, NULL }; +// pd3dContext->CSSetShaderResources(0, 4, ppSRVNULL); +// +// return S_OK; +//} + +const float MATH_PI2 = 3.14159265359f; +#define DEG_TO_RAD2(d) (d * MATH_PI2 / 180) + +//-------------------------------------------------------------------------------------- +// +// ComputeWindPyramid +// +// Wind noise is generated using blends of four vectors. The four vectors are +// generated from some angle around winDir. This code generates the four vectors. +// Shader code generates the per-strand noise from these vectors. +// +// This function currently has some hard coded constants, including a hard-coded +// sin function for magnitude based on frame count. This will be changed in the next +// major update, but we maintain it in 3.1 for compatibility. +// +//-------------------------------------------------------------------------------------- +void ComputeWindPyramid(float4 &wind, float4 &wind1, float4 &wind2, float4 &wind3, + const float windMag, const tressfx_vec3 &windDir) +{ + static int frame = 0; + + float wM = windMag * (pow(sin(frame * 0.05f), 2.0f) + 0.5f); + + tressfx_vec3 windDirN(windDir); + windDirN.Normalize(); + + tressfx_vec3 XAxis(1.0f, 0, 0); + tressfx_vec3 xCrossW = XAxis.Cross(windDirN); + + tressfx_quat rotFromXAxisToWindDir; + rotFromXAxisToWindDir.SetIdentity(); + + float angle = asin(xCrossW.Length()); + + if (angle > 0.001) + { + rotFromXAxisToWindDir.SetRotation(xCrossW.Normalize(), angle); + } + + float angleToWideWindCone = DEG_TO_RAD2(40.f); + + { + tressfx_vec3 rotAxis(0, 1.0f, 0); + + tressfx_quat rot(rotAxis, angleToWideWindCone); + tressfx_vec3 windVec = rotFromXAxisToWindDir * rot * XAxis * wM; + wind = float4(windVec.x, windVec.y, windVec.z, (float)frame); + } + + { + tressfx_vec3 rotAxis(0, -1.0f, 0); + tressfx_quat rot(rotAxis, angleToWideWindCone); + tressfx_vec3 windVec = rotFromXAxisToWindDir * rot * XAxis * wM; + wind1 = float4(windVec.x, windVec.y, windVec.z, (float)frame); + } + + { + tressfx_vec3 rotAxis(0, 0, 1.0f); + tressfx_quat rot(rotAxis, angleToWideWindCone); + tressfx_vec3 windVec = rotFromXAxisToWindDir * rot * XAxis * wM; + wind2 = float4(windVec.x, windVec.y, windVec.z, (float)frame); + } + + { + tressfx_vec3 rotAxis(0, 0, -1.0f); + tressfx_quat rot(rotAxis, angleToWideWindCone); + tressfx_vec3 windVec = rotFromXAxisToWindDir * rot * XAxis * wM; + wind3 = float4(windVec.x, windVec.y, windVec.z, (float)frame); + } + + frame++; +} + +// scale the stiffness value based on current and target frames rates and minimum +// stiffness value. +float getScaledStiffness(float s0, float s_min_scale, float h, float h0) +{ + float s_min = s0 * s_min_scale; + float s = ((s0 - s_min) / h0) * h + s_min; + return s; +} + +//-------------------------------------------------------------------------------------- +// +// Simulate +// +// Runs the hair simulation which will animate the hair vertices. This function calls +// Dispatch to execute compute shaders that implement the simulation. +// +////-------------------------------------------------------------------------------------- +VkResult TressFXSimulation::Simulate(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + float fElapsedTime, float density, + tressfx_vec3 &windDir, float windMag, + XMMATRIX *pModelTransformForHead, + ID3D11UnorderedAccessView *pSkinningTransforms, + float targetFrameRate, bool singleHeadTransform, + bool warp, uint32_t uniformBufferIndex) +{ + (void)pSkinningTransforms; + m_elapsedTimeSinceLastSim += fElapsedTime; + bool bFullSimulate = true; + + // Simulation is sensitive to frame rate. So, we set the target frame rate (defaulted + // to 1/60) + // and if the current elapsed time since the last simulation is too early, + // we run the simulation with lower iterations and stiffness values. + if ((m_elapsedTimeSinceLastSim < targetFrameRate) && !warp) + { + bFullSimulate = false; + } + else + { + m_elapsedTimeSinceLastSim = 0; + } + + VkResult vr = VK_SUCCESS; + + int numOfStrandsPerThreadGroup = + THREAD_GROUP_SIZE / m_pTressFXMesh->m_HairAsset.m_NumOfVerticesInStrand; + + ConstBufferCS_Per_Frame *pCSPerFrame; + vkMapMemory(pvkDevice, m_pCBCSPerFrameMemory, + uniformBufferIndex * sizeof(ConstBufferCS_Per_Frame), + sizeof(ConstBufferCS_Per_Frame), 0, + reinterpret_cast(&pCSPerFrame)); + + { + pCSPerFrame->bWarp = warp; + + if (bFullSimulate) + { + pCSPerFrame->NumLengthConstraintIterations = + m_simParams.numLengthConstraintIterations; + } + else + { + pCSPerFrame->NumLengthConstraintIterations = 1; + } + + pCSPerFrame->bCollision = (m_simParams.bCollision == true) ? 1 : 0; + + pCSPerFrame->GravityMagnitude = m_simParams.gravityMagnitude; + + pCSPerFrame->timeStep = targetFrameRate; + + pCSPerFrame->NumOfStrandsPerThreadGroup = numOfStrandsPerThreadGroup; + pCSPerFrame->NumFollowHairsPerGuideHair = + (m_bGuideFollowHairPrev + ? m_pTressFXMesh->m_HairAsset.m_NumFollowHairsPerGuideHair + : 0); + pCSPerFrame->TipSeparationFactor = + m_pTressFXMesh->m_HairAsset.m_TipSeparationFactor; + + ComputeWindPyramid(pCSPerFrame->Wind, pCSPerFrame->Wind1, pCSPerFrame->Wind2, + pCSPerFrame->Wind3, windMag, windDir); + + int numSections = m_simParams.numHairSections; + + // hair section 0 + if (numSections > 0) + { + pCSPerFrame->Damping0 = m_simParams.perSectionShapeParams[0].damping; + pCSPerFrame->StiffnessForLocalShapeMatching0 = + m_simParams.perSectionShapeParams[0].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching0 = + m_simParams.perSectionShapeParams[0].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange0 = + m_simParams.perSectionShapeParams[0].globalShapeMatchingEffectiveRange; + } + + // hair section 1 + if (numSections > 1) + { + pCSPerFrame->Damping1 = m_simParams.perSectionShapeParams[1].damping; + pCSPerFrame->StiffnessForLocalShapeMatching1 = + m_simParams.perSectionShapeParams[1].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching1 = + m_simParams.perSectionShapeParams[1].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange1 = + m_simParams.perSectionShapeParams[1].globalShapeMatchingEffectiveRange; + } + + // hair section 2 + if (numSections > 2) + { + pCSPerFrame->Damping2 = m_simParams.perSectionShapeParams[2].damping; + pCSPerFrame->StiffnessForLocalShapeMatching2 = + m_simParams.perSectionShapeParams[2].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching2 = + m_simParams.perSectionShapeParams[2].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange2 = + m_simParams.perSectionShapeParams[2].globalShapeMatchingEffectiveRange; + } + + // hair section 3 + if (numSections > 3) + { + pCSPerFrame->Damping3 = m_simParams.perSectionShapeParams[3].damping; + pCSPerFrame->StiffnessForLocalShapeMatching3 = + m_simParams.perSectionShapeParams[3].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching3 = + m_simParams.perSectionShapeParams[3].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange3 = + m_simParams.perSectionShapeParams[3].globalShapeMatchingEffectiveRange; + } + + if (!bFullSimulate) + { + float h = fElapsedTime; + float h0 = targetFrameRate; + float s_min_scale = + 0.3f; // minimum stiffness = s_min_scale * current stiffness + + pCSPerFrame->StiffnessForLocalShapeMatching0 = getScaledStiffness( + m_simParams.perSectionShapeParams[0].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + pCSPerFrame->StiffnessForLocalShapeMatching1 = getScaledStiffness( + m_simParams.perSectionShapeParams[1].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + pCSPerFrame->StiffnessForLocalShapeMatching2 = getScaledStiffness( + m_simParams.perSectionShapeParams[2].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + pCSPerFrame->StiffnessForLocalShapeMatching3 = getScaledStiffness( + m_simParams.perSectionShapeParams[3].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + } + + if (bFullSimulate) + { + pCSPerFrame->NumLocalShapeMatchingIterations = + m_simParams.numLocalShapeMatchingIterations; + } + else + { + pCSPerFrame->NumLocalShapeMatchingIterations = 1; + } + + pCSPerFrame->NumVerticesPerStrand = g_TressFXNumVerticesPerStrand; + } + vkUnmapMemory(pvkDevice, m_pCBCSPerFrameMemory); + + // ConstBufferCS_HeadTransform + ConstBufferCS_HeadTransform *pCSHeadTransform; + AMD_V_RETURN(vkMapMemory(pvkDevice, m_pCBHeadTransformsMemory, 0, + sizeof(ConstBufferCS_HeadTransform), 0, + reinterpret_cast(&pCSHeadTransform))); + { + pCSHeadTransform->bSingleHeadTransform = singleHeadTransform; + pCSHeadTransform->ModelRotateForHead = + XMQuaternionRotationMatrix(*pModelTransformForHead); + pCSHeadTransform->ModelTransformForHead = *pModelTransformForHead; + } + vkUnmapMemory(pvkDevice, m_pCBHeadTransformsMemory); + + VkBufferMemoryBarrier bufferBarrier[] = { + getBufferBarrier(m_pCBCSPerFrame, VK_ACCESS_HOST_WRITE_BIT, + VK_ACCESS_UNIFORM_READ_BIT), + getBufferBarrier(m_pCBHeadTransforms, VK_ACCESS_HOST_WRITE_BIT, + VK_ACCESS_UNIFORM_READ_BIT), + }; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(bufferBarrier), bufferBarrier, 0, nullptr); + + //======= Run the compute shader ======= + + // Increase density a little bit (0.05) to hide popping. This allows simulation to + // take more hair than rendering and gives a chance + // to simulate hairs before they get rendered so that there will be enough time for + // popping to disappear. + density += 0.05f; + + if (density > 1.0f) + { + density = 1.0f; + } + + int numOfGroupsForCS_VertexLevel = + (int)(((float)(m_bGuideFollowHairPrev + ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairVertices + : m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices) / + (float)THREAD_GROUP_SIZE) * + density); + + uint32_t descriptorOffset[] = {uniformBufferIndex * sizeof(ConstBufferCS_Per_Frame)}; + + // Prepare follow hair vertices before they are turning into guide ones. + // One thread computes one vertex + if (m_bGuideFollowHairPrev && !m_simParams.bGuideFollowSimulation) + { + VkDescriptorSet prepareFollowHairSets[] = { + m_configSet, m_pTressFXMesh->m_PrepareFollowHairSet}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSPrepareFollowHairBeforeTurningIntoGuideLayout, 0, + AMD_ARRAY_SIZE(prepareFollowHairSets), + prepareFollowHairSets, AMD_ARRAY_SIZE(descriptorOffset), + descriptorOffset); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSPrepareFollowHairBeforeTurningIntoGuide); + vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); + + VkBufferMemoryBarrier flushPrevPositionBarrier[] = {getBufferBarrier( + m_pTressFXMesh->m_HairVertexPositionsPrevBuffer, VK_ACCESS_MEMORY_WRITE_BIT, + VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(flushPrevPositionBarrier), + flushPrevPositionBarrier, 0, nullptr); + } + + // Integrate and global shape constraints + // One thread computes one vertex + VkDescriptorSet globalConstraintSets[] = {m_configSet, + m_pTressFXMesh->m_GlobalConstraintsSet}; + + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSIntegrationAndGlobalShapeConstraintsLayout, 0, + AMD_ARRAY_SIZE(globalConstraintSets), globalConstraintSets, + AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSIntegrationAndGlobalShapeConstraints); + vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); + + VkBufferMemoryBarrier globalConstraintsBarriers[] = { + getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsPrevBuffer, + VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(globalConstraintsBarriers), + globalConstraintsBarriers, 0, nullptr); + + // Local shape constraints. If the hair is very curly, increase the iteration so that + // hair style can be preserved well. + // One thread computes one strand + + // If more than 16 vertices per strand, iterate on the CPU + if (g_TressFXNumVerticesPerStrand >= 16) + { + for (int iteration = 0; iteration < m_simParams.numLocalShapeMatchingIterations; + iteration++) + { + int numOfGroupsForCS_StrandLevel = + (int)(((float)(m_bGuideFollowHairPrev + ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairStrands + : m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands) / + (float)THREAD_GROUP_SIZE) * + density); + VkDescriptorSet localConstraintSets[] = { + m_configSet, m_pTressFXMesh->m_LocalConstraintsSet}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSLocalShapeConstraintsSingleDispatchLayout, 0, + AMD_ARRAY_SIZE(localConstraintSets), + localConstraintSets, AMD_ARRAY_SIZE(descriptorOffset), + descriptorOffset); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSLocalShapeConstraints); + vkCmdDispatch(commandBuffer, numOfGroupsForCS_StrandLevel, 1, 1); + + VkBufferMemoryBarrier localBarrier[] = { + getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(localBarrier), localBarrier, 0, nullptr); + } + } + else + { + int numOfGroupsForCS_StrandLevel = + (int)(((float)(m_bGuideFollowHairPrev + ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairStrands + : m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands) / + (float)THREAD_GROUP_SIZE) * + density); + VkDescriptorSet localConstraintSets[] = {m_configSet, + m_pTressFXMesh->m_LocalConstraintsSet}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSLocalShapeConstraintsSingleDispatchLayout, 0, + AMD_ARRAY_SIZE(localConstraintSets), localConstraintSets, + AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSLocalShapeConstraintsSingleDispatch); + vkCmdDispatch(commandBuffer, numOfGroupsForCS_StrandLevel, 1, 1); + + VkBufferMemoryBarrier localBarrier[] = { + getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(localBarrier), localBarrier, 0, nullptr); + } + + // Edge length constraints, wind and collisions + // One thread computes one vertex + VkDescriptorSet lengthWindCollisionSets[] = { + m_configSet, m_pTressFXMesh->m_LenghtWindCollisionSet}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSLengthConstriantsWindAndCollisionLayout, 0, + AMD_ARRAY_SIZE(lengthWindCollisionSets), + lengthWindCollisionSets, AMD_ARRAY_SIZE(descriptorOffset), + descriptorOffset); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSLengthConstriantsWindAndCollision); + vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); + + VkBufferMemoryBarrier lengthWindCollisionBarriers[] = { + getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(lengthWindCollisionBarriers), + lengthWindCollisionBarriers, 0, nullptr); + + // Update follow hair vertices + // One thread computes one vertex + if (m_bGuideFollowHairPrev) + { + VkDescriptorSet updateFollowHairSets[] = {m_configSet, + m_pTressFXMesh->m_UpdateFollowHairSet}; + vkCmdBindDescriptorSets( + commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSUpdateFollowHairVerticesLayout, 0, AMD_ARRAY_SIZE(updateFollowHairSets), + updateFollowHairSets, AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSUpdateFollowHairVertices); + vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); + + VkBufferMemoryBarrier updateFollowHairBarriers[] = { + getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT), + }; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(updateFollowHairBarriers), + updateFollowHairBarriers, 0, nullptr); + } + + VkBufferMemoryBarrier makeTangentBarrier[] = {getBufferBarrier( + m_pTressFXMesh->m_HairVertexTangentsBuffer, VK_ACCESS_MEMORY_READ_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(makeTangentBarrier), makeTangentBarrier, 0, + nullptr); + + // Compute tangents for every vertex (guide + follow) + { + int numOfGroupsForCS_TotalVertexLevel = + (int)(((float)(m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices) / + (float)THREAD_GROUP_SIZE) * + density); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSComputeTangents); + VkDescriptorSet computeTangentSet[] = {m_configSet, + m_pTressFXMesh->m_ComputeTangentSet}; + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + m_CSComputeTangentsLayout, 0, + AMD_ARRAY_SIZE(computeTangentSet), computeTangentSet, + AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); + vkCmdDispatch(commandBuffer, numOfGroupsForCS_TotalVertexLevel, 1, 1); + + VkBufferMemoryBarrier computeTangentBarrier[] = { + getBufferBarrier(m_pTressFXMesh->m_HairVertexTangentsBuffer, + VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT)}; + + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(computeTangentBarrier), computeTangentBarrier, + 0, nullptr); + } + + return vr; +} + +//-------------------------------------------------------------------------------------- +// +// CreateComputeShaderConstantBuffers +// +// Called by OnCreateDevice to allocate a constant buffer used by the compute shader code +// +//-------------------------------------------------------------------------------------- +VkResult TressFXSimulation::CreateComputeShaderConstantBuffers( + VkDevice pvkDevice, TressFX_CollisionCapsule *pCollision, + uint32_t maxUniformBufferCount, uint32_t cpu_memory_index, + uint32_t texture_memory_index) +{ + (void)pCollision; + VkResult vr = VK_SUCCESS; + // const buffer for per frame data + VkBufferCreateInfo Desc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + // FIXME: Uniform buffer + compute shader crash nvidia driver + Desc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + Desc.size = maxUniformBufferCount * sizeof(ConstBufferCS_Per_Frame); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBCSPerFrame)); + m_pCBCSPerFrameMemory = + allocBufferMemory(pvkDevice, m_pCBCSPerFrame, cpu_memory_index); + + // const buffer for capsule collision + Desc.size = sizeof(TressFX_CollisionCapsule); + // data.pSysMem = (void *)pCollision; + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBCSCollisionCapsule)); + m_pCBCSCollisionCapsuleMemory = + allocBufferMemory(pvkDevice, m_pCBCSCollisionCapsule, texture_memory_index); + + /* void* scratch_buffer_mapped_memory; + vkMapMemory(pvkDevice, ..., 0, sizeof(TressFX_CollisionCapsule), 0, + &scratch_buffer_mapped_memory); + memcpy(scratch_buffer_mapped_memory, pCollision, + sizeof(TressFX_CollisionCapsule)); + vkUnmapMemory(pvkDevice, ...); + vkCmdCopyBuffer(..., ..., m_pCBCSCollisionCapsule, 1, );*/ + + // const buffer for hair root transformation + Desc.size = sizeof(TransformConstantBuffer); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBGenerateTransforms)); + m_pCBGenerateTransformsMemory = + allocBufferMemory(pvkDevice, m_pCBGenerateTransforms, cpu_memory_index); + + // const buffer for head transformation + Desc.size = sizeof(ConstBufferCS_HeadTransform); + AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBHeadTransforms)); + m_pCBHeadTransformsMemory = + allocBufferMemory(pvkDevice, m_pCBHeadTransforms, cpu_memory_index); + + VkDescriptorBufferInfo perFrameCBCS{m_pCBCSPerFrame, 0, + sizeof(ConstBufferCS_Per_Frame)}; + VkDescriptorBufferInfo headTransform{m_pCBHeadTransforms, 0, + sizeof(ConstBufferCS_HeadTransform)}; + VkWriteDescriptorSet writeSet[] = { + getWriteDescriptor(m_configSet, IDSRV_CONSTANTS_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, &perFrameCBCS), + getWriteDescriptor(m_configSet, IDSRV_HEAD_TRANSFORM, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &headTransform), + }; + vkUpdateDescriptorSets(pvkDevice, AMD_ARRAY_SIZE(writeSet), writeSet, 0, nullptr); + return VK_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// OnDestroy +// +// Called when the D3D device is being destroyed +// +//-------------------------------------------------------------------------------------- +void TressFXSimulation::OnDestroy(VkDevice pvkDevice) +{ + { + AMD_SAFE_RELEASE(m_CSIntegrationAndGlobalShapeConstraints, vkDestroyPipeline, + pvkDevice); + AMD_SAFE_RELEASE(m_CSApplyHairTransformGlobally, vkDestroyPipeline, pvkDevice); + AMD_SAFE_RELEASE(m_CSComputeTangents, vkDestroyPipeline, pvkDevice); + AMD_SAFE_RELEASE(m_CSLocalShapeConstraints, vkDestroyPipeline, pvkDevice); + AMD_SAFE_RELEASE(m_CSLocalShapeConstraintsSingleDispatch, vkDestroyPipeline, + pvkDevice); + AMD_SAFE_RELEASE(m_CSLengthConstriantsWindAndCollision, vkDestroyPipeline, + pvkDevice); + AMD_SAFE_RELEASE(m_CSUpdateFollowHairVertices, vkDestroyPipeline, pvkDevice); + AMD_SAFE_RELEASE(m_CSPrepareFollowHairBeforeTurningIntoGuide, vkDestroyPipeline, + pvkDevice); + AMD_SAFE_RELEASE(m_CSGenerateTransforms, vkDestroyPipeline, pvkDevice); + + AMD_SAFE_RELEASE(m_CSIntegrationAndGlobalShapeConstraintsLayout, + vkDestroyPipelineLayout, pvkDevice); + // AMD_SAFE_RELEASE(m_CSApplyHairTransformGloballyLayout, vkDestroyPipelineLayout, + // pvkDevice); + AMD_SAFE_RELEASE(m_CSComputeTangentsLayout, vkDestroyPipelineLayout, pvkDevice); + AMD_SAFE_RELEASE(m_CSLocalShapeConstraintsLayout, vkDestroyPipelineLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_CSLocalShapeConstraintsSingleDispatchLayout, + vkDestroyPipelineLayout, pvkDevice); + AMD_SAFE_RELEASE(m_CSLengthConstriantsWindAndCollisionLayout, + vkDestroyPipelineLayout, pvkDevice); + AMD_SAFE_RELEASE(m_CSUpdateFollowHairVerticesLayout, vkDestroyPipelineLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_CSPrepareFollowHairBeforeTurningIntoGuideLayout, + vkDestroyPipelineLayout, pvkDevice); + // AMD_SAFE_RELEASE(m_CSGenerateTransformsLayout, vkDestroyPipelineLayout, + // pvkDevice); + + AMD_SAFE_RELEASE(m_GlobalConstraintsSetLayout, vkDestroyDescriptorSetLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_LocalConstraintsSetLayout, vkDestroyDescriptorSetLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_LenghtWindTangentSetLayout, vkDestroyDescriptorSetLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_PrepareFollowHairSetLayout, vkDestroyDescriptorSetLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_UpdateFollowHaitSetLayout, vkDestroyDescriptorSetLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_ComputeTangentSetLayout, vkDestroyDescriptorSetLayout, + pvkDevice); + AMD_SAFE_RELEASE(m_configSetLayout, vkDestroyDescriptorSetLayout, pvkDevice); + } + AMD_SAFE_RELEASE(m_descriptorPool, vkDestroyDescriptorPool, pvkDevice); + AMD_SAFE_RELEASE(m_pCBCSPerFrame, vkDestroyBuffer, pvkDevice); + AMD_SAFE_RELEASE(m_pCBCSPerFrameMemory, vkFreeMemory, pvkDevice); + AMD_SAFE_RELEASE(m_pCBCSCollisionCapsule, vkDestroyBuffer, pvkDevice); + AMD_SAFE_RELEASE(m_pCBCSCollisionCapsuleMemory, vkFreeMemory, pvkDevice); + AMD_SAFE_RELEASE(m_pCBGenerateTransforms, vkDestroyBuffer, pvkDevice); + AMD_SAFE_RELEASE(m_pCBGenerateTransformsMemory, vkFreeMemory, pvkDevice); + AMD_SAFE_RELEASE(m_pCBHeadTransforms, vkDestroyBuffer, pvkDevice); + AMD_SAFE_RELEASE(m_pCBHeadTransformsMemory, vkFreeMemory, pvkDevice); +} + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXSimulationVulkan.h b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.h new file mode 100644 index 0000000..da6aec3 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.h @@ -0,0 +1,133 @@ +//-------------------------------------------------------------------------------------- +// File: TressFXSimulation.h +// +// Hair physics simulation header +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//-------------------------------------------------------------------------------------- + +#pragma once + +#include "AMD_TressFX.h" +#include "Math\vector3D.h" +#include "TressFXMeshVulkan.h" +#include "Util.h" +#include +#include + +typedef DirectX::XMFLOAT4 float4; +typedef DirectX::XMFLOAT3 float3; + +namespace AMD +{ + +class TressFXSimulation +{ + public: + TressFXSimulation(void); + ~TressFXSimulation(void); + + VkResult OnCreateDevice(VkDevice pvkDevice, TressFX_CollisionCapsule *pCollision, + uint32_t maxUniformCount, uint32_t cpu_memory_index, + uint32_t gpu_memory_index); + VkResult Simulate(VkDevice pvkContext, VkCommandBuffer commandBuffer, + float fElapsedTime, float density, tressfx_vec3 &windDir, + float windMag, DirectX::XMMATRIX *pModelTransformForHead, + ID3D11UnorderedAccessView *pSkinningTransforms, + float targetFrameRate, bool singleHeadTransform, bool warp, + uint32_t uniformBufferIndex); + VkResult GenerateTransforms(VkDevice pvkContext, TressFX_SceneMesh sceneMesh, + ID3D11UnorderedAccessView **ppSkinningTransformationsUAV, + DirectX::XMMATRIX *pModelTransformForHead); + VkResult ApplyTransformGlobally(VkDevice pvkContext, + ID3D11UnorderedAccessView *pSkinningTransforms, + float density, bool singleHeadTransform, + DirectX::XMMATRIX *pModelTransformForHead); + void OnDestroy(VkDevice pvkDevice); + TressFXMesh *m_pTressFXMesh; + float m_elapsedTimeSinceLastSim; + + // Descriptors set layout + VkDescriptorSetLayout m_GlobalConstraintsSetLayout; + VkDescriptorSetLayout m_LocalConstraintsSetLayout; + VkDescriptorSetLayout m_LenghtWindTangentSetLayout; + VkDescriptorSetLayout m_PrepareFollowHairSetLayout; + VkDescriptorSetLayout m_UpdateFollowHaitSetLayout; + VkDescriptorSetLayout m_ComputeTangentSetLayout; + + private: + bool m_bGuideFollowHairPrev; + + // hair simulation params + TressFX_SimulationParams m_simParams; + + VkDescriptorPool m_descriptorPool; + VkDescriptorSetLayout m_configSetLayout; + VkDescriptorSet m_configSet; + + // Compute Shader + // data for compute shaders + VkPipelineLayout m_CSIntegrationAndGlobalShapeConstraintsLayout; + VkPipeline m_CSIntegrationAndGlobalShapeConstraints; + VkPipelineLayout m_CSApplyHairTransformGloballyLayout; + VkPipeline m_CSApplyHairTransformGlobally; + VkPipelineLayout m_CSComputeTangentsLayout; + VkPipeline m_CSComputeTangents; + VkPipelineLayout m_CSLocalShapeConstraintsLayout; + VkPipeline m_CSLocalShapeConstraints; + VkPipelineLayout m_CSLocalShapeConstraintsSingleDispatchLayout; + VkPipeline m_CSLocalShapeConstraintsSingleDispatch; + VkPipelineLayout m_CSLengthConstriantsWindAndCollisionLayout; + VkPipeline m_CSLengthConstriantsWindAndCollision; + VkPipelineLayout m_CSUpdateFollowHairVerticesLayout; + VkPipeline m_CSUpdateFollowHairVertices; + VkPipelineLayout m_CSPrepareFollowHairBeforeTurningIntoGuideLayout; + VkPipeline m_CSPrepareFollowHairBeforeTurningIntoGuide; + VkPipelineLayout m_CSGenerateTransformsLayout; + VkPipeline m_CSGenerateTransforms; + + // const buffers for CS + VkBuffer m_pCBCSPerFrame; + VkDeviceMemory m_pCBCSPerFrameMemory; + VkBuffer m_pCBCSCollisionCapsule; + VkDeviceMemory m_pCBCSCollisionCapsuleMemory; + VkBuffer m_pCBGenerateTransforms; + VkDeviceMemory m_pCBGenerateTransformsMemory; + VkBuffer m_pCBHeadTransforms; + VkDeviceMemory m_pCBHeadTransformsMemory; + + VkResult CreateComputeShaderConstantBuffers(VkDevice pvkDevice, + TressFX_CollisionCapsule *pCollision, + uint32_t maxUniformBufferCount, + uint32_t memoryIndexCPU, + uint32_t memoryIndexGPU); + VkResult CreateDescriptorSet(VkDevice pvkDevice); + + public: + void SetSimulationParams(const TressFX_SimulationParams &simParams) + { + m_simParams = simParams; + } +}; + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXVulkan.cpp b/amd_tressfx_vulkan/src/TressFXVulkan.cpp new file mode 100644 index 0000000..5faf793 --- /dev/null +++ b/amd_tressfx_vulkan/src/TressFXVulkan.cpp @@ -0,0 +1,319 @@ +//-------------------------------------------------------------------------------------- +// File: TresssFX.cpp +// +// Hair asset structure +// +// +// Copyright (c) 2016 Advanced Micro Devices, Inc. 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. +// +//-------------------------------------------------------------------------------------- + +#if AMD_TRESSFX_COMPILE_DYNAMIC_LIB +#define AMD_DLL_EXPORTS +#endif +#include "TressFXOpaqueVulkan.h" + +static AMD::TressFX_OpaqueDesc gTressFXOpaqueDesc; + +int g_TressFXNumVerticesPerStrand = 16; // must be 2^n (n is integer and greater and 3) + // and less than or equal to THREAD_GROUP_SIZE. + // i.e. 8, 16, 32 or 64 + +namespace AMD +{ +//-------------------------------------------------------------------------------------- +// +// TressFX_GetVersion +// +// Gets the TressFX library version number. +// This can be called before TressFX_Initialize. +// +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_GetVersion(uint *major, uint *minor, + uint *patch) +{ + if (major == NULL || minor == NULL || patch == NULL) + { + return TRESSFX_RETURN_CODE_INVALID_POINTER; + } + + *major = AMD_TRESSFX_VERSION_MAJOR; + *minor = AMD_TRESSFX_VERSION_MINOR; + *patch = AMD_TRESSFX_VERSION_PATCH; + + return TRESSFX_RETURN_CODE_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_Initialize +// +// Initializes TressFX rendering and simulation. Allocates the needed resources. +// The opaque initialization happens only once for the lifetime of the program, and +// descriptors share the same opaque pointer. +// +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API +TressFX_Initialize(TressFX_Desc &desc, VkImageView depthTexture, VkImageView colorTexture, + VkCommandBuffer commandBuffer, VkDeviceMemory scratchMemory, + VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) +{ + desc.pOpaque = &gTressFXOpaqueDesc; + desc.pOpaque->Initialize(desc, depthTexture, colorTexture, commandBuffer, + scratchMemory, scratchBuffer, offsetInScratchBuffer, + desc.memoryIndexHostVisible, desc.memoryIndexDeviceLocal); + + desc.pTressFXMesh = NULL; + desc.groupID = 0; + desc.tressFXHair.pHair = NULL; + desc.tressFXHair.size = 0; + + return TRESSFX_RETURN_CODE_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_LoadRawAsset +// +// Reads the contents of a binary .tfx file. The data in pRawHairBlob is what was +// read from the .tfx file without any processing. Data from multiple .tfx files +// can be loaded by calling TressFXLoadRawAsset multiple times. +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_LoadRawAsset( + TressFX_Desc &desc, const TressFX_GuideFollowParams &guideFollowParams, + TressFX_HairBlob *pRawHairBlob) +{ + bool success = + desc.pOpaque->LoadAppendAsset(pRawHairBlob, guideFollowParams, desc.groupID); + if (success) + { + desc.groupID++; + } + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_LoadProcessedAsset +// +// Loads a processed hair asset. The data in pHairBlob was created by calling +// TressFX_CreateProcessedAsset(). Since it's a preprocessed asset it loads faster +// than a raw asset. +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_LoadProcessedAsset( + TressFX_Desc &desc, TressFX_HairBlob *pHairBlob, TressFX_SceneMesh *sceneMesh, + VkImageView pTressFXTexture, VkCommandBuffer uploadCmdBuffer, VkBuffer scratchBuffer, + VkDeviceMemory scratchMemory) +{ + TressFXMesh *pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + if (pTressFXMesh != NULL) + { + delete pTressFXMesh; + } + pTressFXMesh = new TressFXMesh(); + memcpy(desc.tressFXHair.pHair, pHairBlob->pHair, pHairBlob->size); + desc.tressFXHair.size = pHairBlob->size; + pTressFXMesh->OnCreate(desc.pvkDevice, &desc.tressFXHair, sceneMesh, pTressFXTexture, + desc.memoryIndexDeviceLocal, uploadCmdBuffer, scratchBuffer, + scratchMemory, + desc.pOpaque->tressFXSimulation.m_GlobalConstraintsSetLayout, + desc.pOpaque->tressFXSimulation.m_LocalConstraintsSetLayout, + desc.pOpaque->tressFXSimulation.m_LenghtWindTangentSetLayout, + desc.pOpaque->tressFXSimulation.m_PrepareFollowHairSetLayout, + desc.pOpaque->tressFXSimulation.m_UpdateFollowHaitSetLayout, + desc.pOpaque->tressFXSimulation.m_ComputeTangentSetLayout, + desc.pOpaque->tressFXRenderer.m_pass1_hair_set_layout, + desc.pOpaque->tressFXRenderer.m_shadow_pass_hair_set_layout); + desc.numTotalHairStrands = pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; + desc.numTotalHairVertices = pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; + desc.pTressFXMesh = (void *)pTressFXMesh; + + return TRESSFX_RETURN_CODE_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_CreateProcessedAsset +// +// Creates a processed hair asset from previous loads of raw hair asset data. +// A pointer to the processed hair asset is returned in pHairBlob. The caller of this +// function should copy the contents of pHairBlob instead of using it directly, since +// the memory for it will be released when a new file is loaded. +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_CreateProcessedAsset( + TressFX_Desc &desc, TressFX_HairBlob **ppHairBlob, TressFX_SceneMesh *sceneMesh, + VkImageView hairTexture, VkCommandBuffer uploadCmdBuffer, VkBuffer scratchBuffer, + VkDeviceMemory scratchMemory) +{ + bool success = desc.pOpaque->CreateProcessedAsset( + desc, ppHairBlob, sceneMesh, hairTexture, desc.memoryIndexDeviceLocal, + uploadCmdBuffer, scratchBuffer, scratchMemory); + desc.groupID = 0; + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_Simulate +// +// Runs the hair simulation +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_Simulate(TressFX_Desc &desc, + VkCommandBuffer commandBuffer, + float elapsedTime, + uint32_t uniformBufferIndex) +{ + bool success = + desc.pOpaque->Simulate(desc, commandBuffer, elapsedTime, uniformBufferIndex); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_Begin +// +// Indicates that hair simulation and rendering will begin +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_Begin(TressFX_Desc &desc, + uint32_t uniformBufferIndex) +{ + bool success = desc.pOpaque->Begin(desc, uniformBufferIndex); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_RenderShadowMap +// +// Render the hair into a shadow map. Returns the shadow map in the descriptor +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_RenderShadowMap( + TressFX_Desc &desc, VkCommandBuffer commandBuffer, uint32_t uniformBufferIndex) +{ + bool success = desc.pOpaque->RenderShadowMap(desc, commandBuffer, uniformBufferIndex); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_Render +// +// Render the hair model. Multiple render calls can be made for different hair models +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_Render(TressFX_Desc &desc, + VkCommandBuffer commandBuffer, + uint32_t uniformBufferIndex) +{ + bool success = desc.pOpaque->RenderHair(desc, commandBuffer, uniformBufferIndex); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_End +// +// Indicates that hair rendering is finished. Final post-process rendering can be +// done at this point +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_End(TressFX_Desc &desc) +{ + bool success = desc.pOpaque->End(desc); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_Resize +// +// Called when the back buffer is resized so internal buffers can also be resized +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_Resize(TressFX_Desc &desc, + uint32_t texture_memory_index) +{ + bool success = desc.pOpaque->Resize(desc, texture_memory_index); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_Release +// +// Releases any memory allocated by the library +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_Release(TressFX_Desc &desc) +{ + if (!desc.pOpaque) + { + return TRESSFX_RETURN_CODE_SUCCESS; + } + + desc.pOpaque->Release(desc.pvkDevice); + TressFXMesh *pTressFXMesh = (TressFXMesh *)desc.pTressFXMesh; + delete pTressFXMesh; + delete desc.tressFXHair.pHair; + desc.tressFXHair.pHair = NULL; + desc.tressFXHair.size = 0; + return TRESSFX_RETURN_CODE_SUCCESS; +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_GenerateTransforms +// +// Calculates the transformations for each strand. +// Used for fur skinning. +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API +TressFX_GenerateTransforms(TressFX_Desc &desc, TressFX_SceneMesh &sceneMesh) +{ + bool success = desc.pOpaque->GenerateTransforms(desc, sceneMesh); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +//-------------------------------------------------------------------------------------- +// +// TressFX_ApplyRigidTransforms +// +// Apply skin transforms to all hair vertices so that hair would be transformed in a rigid +// motion. +// Used for fur skinning. +// +//-------------------------------------------------------------------------------------- +TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_ApplyRigidTransforms(TressFX_Desc &desc) +{ + bool success = desc.pOpaque->ApplyRigidTransforms(desc); + return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); +} + +} // namespace AMD diff --git a/amd_tressfx_vulkan/src/UtilVulkan.cpp b/amd_tressfx_vulkan/src/UtilVulkan.cpp new file mode 100644 index 0000000..d39b907 --- /dev/null +++ b/amd_tressfx_vulkan/src/UtilVulkan.cpp @@ -0,0 +1,375 @@ +#include "UtilVulkan.h" + +namespace AMD +{ +ShaderModule::ShaderModule(VkDevice dev, const std::vector &code) + : m_pvkDevice(dev) +{ + VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + nullptr, 0, code.size() * sizeof(uint32_t), + code.data()}; + + vkCreateShaderModule(m_pvkDevice, &moduleInfo, nullptr, &m_shaderModule); +} + +ShaderModule::~ShaderModule() +{ + vkDestroyShaderModule(m_pvkDevice, m_shaderModule, nullptr); +} + +VkDeviceMemory allocBufferMemory(VkDevice dev, VkBuffer buffer, + uint32_t texture_memory_index) +{ + VkMemoryRequirements memReqs; + vkGetBufferMemoryRequirements(dev, buffer, &memReqs); + + VkMemoryAllocateInfo allocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; + allocateInfo.allocationSize = memReqs.size; + allocateInfo.memoryTypeIndex = texture_memory_index; + VkDeviceMemory result; + vkAllocateMemory(dev, &allocateInfo, nullptr, &result); + vkBindBufferMemory(dev, buffer, result, 0); + return result; +} + +VkDeviceMemory allocImageMemory(VkDevice dev, VkImage image, + uint32_t texture_memory_index) +{ + VkMemoryRequirements memReqs; + vkGetImageMemoryRequirements(dev, image, &memReqs); + + VkMemoryAllocateInfo allocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; + allocateInfo.allocationSize = memReqs.size; + allocateInfo.memoryTypeIndex = texture_memory_index; + VkDeviceMemory result; + vkAllocateMemory(dev, &allocateInfo, nullptr, &result); + vkBindImageMemory(dev, image, result, 0); + return result; +} + +VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkBufferView *texelBufferView) +{ + VkWriteDescriptorSet result{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET}; + result.descriptorCount = 1; + result.dstSet = dstSet; + result.dstBinding = dstBinding; + result.descriptorType = descriptorType; + result.pTexelBufferView = texelBufferView; + return result; +} + +VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkDescriptorBufferInfo *Bufferdescriptor) +{ + VkWriteDescriptorSet result{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET}; + result.descriptorCount = 1; + result.dstSet = dstSet; + result.dstBinding = dstBinding; + result.descriptorType = descriptorType; + result.pBufferInfo = Bufferdescriptor; + return result; +} + +VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkDescriptorImageInfo *descriptor) +{ + VkWriteDescriptorSet result{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET}; + result.descriptorCount = 1; + result.dstSet = dstSet; + result.dstBinding = dstBinding; + result.descriptorType = descriptorType; + result.pImageInfo = descriptor; + return result; +} + +void fillInitialData(VkCommandBuffer commandBuffer, VkBuffer scratchBuffer, + void *pScratchBuffer, void *pDataToUpload, VkBuffer destBuffer, + size_t &offsetInScratchBuffer, VkDeviceSize size) +{ + memcpy(reinterpret_cast(pScratchBuffer) + offsetInScratchBuffer, + pDataToUpload, size); + VkBufferCopy copyInfo{offsetInScratchBuffer, 0, static_cast(size)}; + vkCmdCopyBuffer(commandBuffer, scratchBuffer, destBuffer, 1, ©Info); + offsetInScratchBuffer += size; +} + +VkResult getDescriptorLayout(VkDevice pvkDevice, const VkDescriptorSetLayoutBinding *ptr, + size_t count, VkDescriptorSetLayout &result) +{ + VkDescriptorSetLayoutCreateInfo info{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}; + info.bindingCount = static_cast(count); + info.pBindings = ptr; + + VkResult vr; + AMD_V_RETURN(vkCreateDescriptorSetLayout(pvkDevice, &info, nullptr, &result)); + return VK_SUCCESS; +} + +VkBufferMemoryBarrier getBufferBarrier(VkBuffer buffer, VkAccessFlags srcAccess, + VkAccessFlags dstAccess, size_t offset, + size_t size) +{ + VkBufferMemoryBarrier result{VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER}; + result.buffer = buffer; + result.srcAccessMask = srcAccess; + result.dstAccessMask = dstAccess; + result.offset = offset; + result.size = size; + return result; +} + +VkPipelineShaderStageCreateInfo getShaderStageCreateInfo(VkShaderModule module, + VkShaderStageFlagBits stage, + const char *shaderName) +{ + VkPipelineShaderStageCreateInfo shaderStageInfo{ + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO}; + shaderStageInfo.module = module; + shaderStageInfo.pName = shaderName; + shaderStageInfo.stage = stage; + return shaderStageInfo; +} + +// No tesselation +const VkPipelineTessellationStateCreateInfo CommonPipelineState::tessellationState{ + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO}; +const VkDynamicState CommonPipelineState::dynamicStates[] = {VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR}; +const VkPipelineDynamicStateCreateInfo CommonPipelineState::dynamicState{ + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, 2, dynamicStates}; +// One sample +const VkPipelineMultisampleStateCreateInfo CommonPipelineState::multisampleState{ + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, nullptr, 0, + VK_SAMPLE_COUNT_1_BIT}; +// One viewport and scissor +const VkPipelineViewportStateCreateInfo CommonPipelineState::viewportState{ + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + nullptr, + 0, + 1, + nullptr, + 1, + nullptr}; +const VkPipelineRasterizationStateCreateInfo + CommonPipelineState::rasterizationCreateInfo = { + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + nullptr, + 0, + VK_FALSE, + VK_FALSE, + VK_POLYGON_MODE_FILL, + VK_CULL_MODE_NONE, + VK_FRONT_FACE_CLOCKWISE, + VK_FALSE, + 0., + 0., + 0., + 1.}; + +const VkPipelineInputAssemblyStateCreateInfo CommonPipelineState::inputAssemblyTriangle = + {VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false}; + +const VkPipelineInputAssemblyStateCreateInfo CommonPipelineState::inputAssemblyLine = { + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST, false}; + +const VkPipelineVertexInputStateCreateInfo CommonPipelineState::m_pLayoutHair{ + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO}; + +VkGraphicsPipelineCreateInfo CommonPipelineState::getBasePipelineCreateInfo( + const VkPipelineVertexInputStateCreateInfo *vertex_input_state, + const VkPipelineDepthStencilStateCreateInfo *depth_stencil_state, + const VkPipelineColorBlendStateCreateInfo *color_blend_state, + const VkPipelineInputAssemblyStateCreateInfo *input_assembly, + const VkPipelineShaderStageCreateInfo *stages, VkPipelineLayout layout, + VkRenderPass render_pass, uint32_t subpass) +{ + VkGraphicsPipelineCreateInfo pipelineCreateInfo{ + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}; + pipelineCreateInfo.pTessellationState = &tessellationState; + pipelineCreateInfo.pMultisampleState = &multisampleState; + pipelineCreateInfo.pVertexInputState = vertex_input_state; + pipelineCreateInfo.pViewportState = &viewportState; + pipelineCreateInfo.pDynamicState = &dynamicState; + pipelineCreateInfo.pDepthStencilState = depth_stencil_state; + pipelineCreateInfo.pColorBlendState = color_blend_state; + pipelineCreateInfo.stageCount = 2; + pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; + pipelineCreateInfo.basePipelineIndex = -1; + pipelineCreateInfo.pRasterizationState = &rasterizationCreateInfo; + pipelineCreateInfo.pInputAssemblyState = input_assembly; + pipelineCreateInfo.pStages = stages; + pipelineCreateInfo.layout = layout; + pipelineCreateInfo.renderPass = render_pass; + pipelineCreateInfo.subpass = subpass; + return pipelineCreateInfo; +} + +namespace +{ +VkPipelineDepthStencilStateCreateInfo +getSpecializedDSS(bool depth_test_enable, bool depth_write_enable, + bool stencil_test_enable, VkCompareOp stencil_op, VkStencilOp pass_op, + uint32_t write_mask) +{ + VkPipelineDepthStencilStateCreateInfo DSS{ + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO}; + DSS.depthTestEnable = depth_test_enable; + DSS.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + DSS.depthWriteEnable = depth_write_enable; + DSS.stencilTestEnable = stencil_test_enable; + DSS.front.compareMask = 0xff; + DSS.front.writeMask = write_mask; + DSS.front.failOp = VK_STENCIL_OP_KEEP; + DSS.front.depthFailOp = VK_STENCIL_OP_KEEP; + DSS.front.passOp = pass_op; + DSS.front.compareOp = stencil_op; + DSS.back.compareMask = 0xff; + DSS.back.writeMask = write_mask; + DSS.back.failOp = VK_STENCIL_OP_KEEP; + DSS.back.depthFailOp = VK_STENCIL_OP_KEEP; + DSS.back.passOp = pass_op; + DSS.back.compareOp = stencil_op; + return DSS; +} + +const VkPipelineColorBlendAttachmentState BlendStateBlendToBg_render_target_0{ + true, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_OP_ADD, + VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_G_BIT}; + +const VkPipelineColorBlendAttachmentState m_pDepthWritesToColor_BS_render_target_0{ + true, + VK_BLEND_FACTOR_ZERO, + VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_OP_ADD, + VK_BLEND_FACTOR_ZERO, + VK_BLEND_FACTOR_SRC_ALPHA, + VK_BLEND_OP_ADD, + VK_COLOR_COMPONENT_R_BIT}; + +const VkPipelineColorBlendAttachmentState m_pResolveColor_BS_BS_render_target_0{ + true, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_OP_ADD, + VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT}; + +const VkPipelineColorBlendAttachmentState m_pSum_BS_render_target_0{ + true, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE, + VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT}; + +// Full screen quad layout structure +const VkVertexInputBindingDescription layout_quad_bindings[1] = { + {0, 32, VK_VERTEX_INPUT_RATE_VERTEX}}; +const VkVertexInputAttributeDescription layout_quad[3] = { + {0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0}, // POSITION + {1, 0, VK_FORMAT_R32G32B32_SFLOAT, 12}, // TANGENT + {2, 0, VK_FORMAT_R32G32_SFLOAT, 24}, // TEXCOORD +}; +} + +const VkPipelineDepthStencilStateCreateInfo CommonPipelineState::DepthTestEnabledDesc = + getSpecializedDSS(true, true, false, VK_COMPARE_OP_NEVER, VK_STENCIL_OP_KEEP, 0xff); +const VkPipelineDepthStencilStateCreateInfo + CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc = + getSpecializedDSS(true, false, true, VK_COMPARE_OP_ALWAYS, + VK_STENCIL_OP_INCREMENT_AND_WRAP, 0xff); +const VkPipelineDepthStencilStateCreateInfo + CommonPipelineState::DepthTestDisabledStencilTestLessDSS = getSpecializedDSS( + false, false, true, VK_COMPARE_OP_LESS, VK_STENCIL_OP_KEEP, 0x00); +const VkPipelineDepthStencilStateCreateInfo + CommonPipelineState::m_pDepthWriteEnabledStencilTestLess_DSS = + getSpecializedDSS(true, true, true, VK_COMPARE_OP_LESS, VK_STENCIL_OP_KEEP, 0x0); + +// disable color write if there is no need for fragments counting +const VkPipelineColorBlendStateCreateInfo CommonPipelineState::ColorWritesOff{ + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO}; + +const VkPipelineColorBlendStateCreateInfo CommonPipelineState::BlendStateBlendToBg{ + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + nullptr, + 0, + VK_FALSE, + VK_LOGIC_OP_NO_OP, + 1, + &BlendStateBlendToBg_render_target_0}; + +const VkPipelineColorBlendStateCreateInfo CommonPipelineState::m_pDepthWritesToColor_BS{ + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + nullptr, + 0, + VK_FALSE, + VK_LOGIC_OP_NO_OP, + 1, + &m_pDepthWritesToColor_BS_render_target_0}; + +const VkPipelineColorBlendStateCreateInfo CommonPipelineState::m_pResolveColor_BS{ + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + nullptr, + 0, + VK_FALSE, + VK_LOGIC_OP_NO_OP, + 1, + &m_pResolveColor_BS_BS_render_target_0}; + +const VkPipelineColorBlendStateCreateInfo CommonPipelineState::m_pSum_BS{ + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + nullptr, + 0, + VK_FALSE, + VK_LOGIC_OP_NO_OP, + 1, + &m_pSum_BS_render_target_0}; + +const VkPipelineVertexInputStateCreateInfo CommonPipelineState::m_pLayoutQuad{ + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + nullptr, + 0, + 1, + layout_quad_bindings, + 3, + layout_quad}; + +VkImageMemoryBarrier getImageMemoryBarrier(VkImage image, VkAccessFlags srcMask, + VkAccessFlags dstMask, VkImageLayout oldLayout, + VkImageLayout newLayout, + VkImageAspectFlags aspect) +{ + VkImageMemoryBarrier memoryBarrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER}; + memoryBarrier.srcAccessMask = srcMask; + memoryBarrier.dstAccessMask = dstMask; + memoryBarrier.oldLayout = oldLayout; + memoryBarrier.newLayout = newLayout; + memoryBarrier.image = image; + memoryBarrier.subresourceRange.aspectMask = aspect; + memoryBarrier.subresourceRange.levelCount = + memoryBarrier.subresourceRange.layerCount = 1; + return memoryBarrier; +} + +VkImageCreateInfo getImageCreateInfo(VkFormat format, uint32_t width, uint32_t height, + VkImageUsageFlags usage, uint32_t layers) +{ + VkImageCreateInfo tex2D_desc{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO}; + tex2D_desc.extent.width = width; + tex2D_desc.extent.height = height; + tex2D_desc.extent.depth = 1; + tex2D_desc.arrayLayers = layers; + tex2D_desc.mipLevels = 1; + tex2D_desc.format = format; + tex2D_desc.usage = usage; + tex2D_desc.samples = VK_SAMPLE_COUNT_1_BIT; + tex2D_desc.imageType = VK_IMAGE_TYPE_2D; + tex2D_desc.tiling = VK_IMAGE_TILING_OPTIMAL; + return tex2D_desc; +} +} diff --git a/amd_tressfx_vulkan/src/UtilVulkan.h b/amd_tressfx_vulkan/src/UtilVulkan.h new file mode 100644 index 0000000..046f58b --- /dev/null +++ b/amd_tressfx_vulkan/src/UtilVulkan.h @@ -0,0 +1,114 @@ +#pragma once + +#include +#include + +#define AMD_V_RETURN(x) \ + { \ + vr = (x); \ + if (vr != VK_SUCCESS) \ + { \ + return vr; \ + } \ + } + +namespace AMD +{ +struct ShaderModule +{ + VkShaderModule m_shaderModule; + + ShaderModule(VkDevice dev, const std::vector &code); + ~ShaderModule(); + + private: + VkDevice m_pvkDevice; +}; + +VkDeviceMemory allocBufferMemory(VkDevice dev, VkBuffer buffer, + uint32_t texture_memory_index); +VkDeviceMemory allocImageMemory(VkDevice dev, VkImage image, + uint32_t texture_memory_index); + +VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkBufferView *texelBufferView); + +VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkDescriptorBufferInfo *Bufferdescriptor); + +VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkDescriptorImageInfo *descriptor); + +void fillInitialData(VkCommandBuffer commandBuffer, VkBuffer scratchBuffer, + void *pScratchBuffer, void *pDataToUpload, VkBuffer destBuffer, + size_t &offsetInScratchBuffer, VkDeviceSize size); + +VkResult getDescriptorLayout(VkDevice pvkDevice, const VkDescriptorSetLayoutBinding *ptr, + size_t count, VkDescriptorSetLayout &result); +VkBufferMemoryBarrier getBufferBarrier(VkBuffer buffer, VkAccessFlags srcAccess, + VkAccessFlags dstAccess, size_t offset = 0, + size_t size = VK_WHOLE_SIZE); + +VkPipelineShaderStageCreateInfo getShaderStageCreateInfo(VkShaderModule module, + VkShaderStageFlagBits stage, + const char *shaderName); + +VkImageCreateInfo getImageCreateInfo(VkFormat format, uint32_t width, uint32_t height, + VkImageUsageFlags usage, uint32_t layers = 1); + +struct CommonPipelineState +{ + // No tesselation + static const VkPipelineTessellationStateCreateInfo tessellationState; + // One viewport and scissor + static const VkDynamicState dynamicStates[2]; + static const VkPipelineDynamicStateCreateInfo dynamicState; + // One sample + static const VkPipelineMultisampleStateCreateInfo multisampleState; + // One viewport + static const VkPipelineViewportStateCreateInfo viewportState; + static const VkPipelineRasterizationStateCreateInfo rasterizationCreateInfo; + + static const VkPipelineVertexInputStateCreateInfo m_pLayoutHair; + // Full screen quad layout structure + static const VkPipelineVertexInputStateCreateInfo m_pLayoutQuad; + + // Triangles list + static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyTriangle; + // Lines list + static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyLine; + + static VkGraphicsPipelineCreateInfo getBasePipelineCreateInfo( + const VkPipelineVertexInputStateCreateInfo *vertex_input_state, + const VkPipelineDepthStencilStateCreateInfo *depth_stencil_state, + const VkPipelineColorBlendStateCreateInfo *color_blend_state, + const VkPipelineInputAssemblyStateCreateInfo *input_assembly, + const VkPipelineShaderStageCreateInfo *stages, VkPipelineLayout layout, + VkRenderPass render_pass, uint32_t subpass); + + static const VkPipelineDepthStencilStateCreateInfo DepthTestEnabledDesc; + // Enable depth test to use early z, disable depth write to make sure required layers + // won't be clipped out in early z + static const VkPipelineDepthStencilStateCreateInfo + DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc; + static const VkPipelineDepthStencilStateCreateInfo + DepthTestDisabledStencilTestLessDSS; + static const VkPipelineDepthStencilStateCreateInfo + m_pDepthWriteEnabledStencilTestLess_DSS; + + // disable color write if there is no need for fragments counting + static const VkPipelineColorBlendStateCreateInfo ColorWritesOff; + static const VkPipelineColorBlendStateCreateInfo BlendStateBlendToBg; + static const VkPipelineColorBlendStateCreateInfo m_pDepthWritesToColor_BS; + static const VkPipelineColorBlendStateCreateInfo m_pResolveColor_BS; + static const VkPipelineColorBlendStateCreateInfo m_pSum_BS; +}; + +VkImageMemoryBarrier +getImageMemoryBarrier(VkImage image, VkAccessFlags srcMask, VkAccessFlags dstMask, + VkImageLayout oldLayout, VkImageLayout newLayout, + VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT); +} \ No newline at end of file From 83678bf6a946ecbdd9643965e79ed20b35039f77 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 31 Dec 2016 19:11:47 +0100 Subject: [PATCH 2/2] Fixes: * Merge PPLL buffer/image memory allocation if possible. * Merge thickness, index and triangle index memory allocation. * Use provided color/depth stencil format for renderpasses. * Remove fullscreen quad. * Various code rewriting. * Add debug marker. * Stylistic styles. --- amd_lib/shared/common/inc/AMD_Types.h | 4 - amd_tressfx/inc/AMD_TressFX.h | 91 +- .../build/AMD_TressFX_Vulkan_2012.vcxproj | 20 +- .../build/AMD_TressFX_Vulkan_2013.vcxproj | 20 +- .../build/AMD_TressFX_Vulkan_2015.vcxproj | 20 +- amd_tressfx_vulkan/premake/premake5.lua | 2 +- .../shader_builder/shader_builder.py | 3 +- .../src/Shaders/TressFXRender_pass2.vert | 29 +- amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp | 301 +- amd_tressfx_vulkan/src/TressFXMeshVulkan.h | 37 +- .../src/TressFXOpaqueVulkan.cpp | 76 +- amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h | 22 +- .../src/TressFXPrecompiledShadersVulkan.h | 18376 ++++++++-------- .../src/TressFXRendererVulkan.cpp | 366 +- .../src/TressFXRendererVulkan.h | 41 +- .../src/TressFXShortCutVulkan.cpp | 81 +- .../src/TressFXShortCutVulkan.h | 22 +- .../src/TressFXSimulationVulkan.cpp | 762 +- .../src/TressFXSimulationVulkan.h | 43 +- amd_tressfx_vulkan/src/TressFXVulkan.cpp | 25 +- amd_tressfx_vulkan/src/UtilVulkan.cpp | 73 +- amd_tressfx_vulkan/src/UtilVulkan.h | 278 +- 22 files changed, 10563 insertions(+), 10129 deletions(-) diff --git a/amd_lib/shared/common/inc/AMD_Types.h b/amd_lib/shared/common/inc/AMD_Types.h index 18643a9..3bb5b42 100644 --- a/amd_lib/shared/common/inc/AMD_Types.h +++ b/amd_lib/shared/common/inc/AMD_Types.h @@ -156,11 +156,7 @@ namespace AMD #define AMD_SAFE_DELETE_ARRAY(p) { delete [] (p); (p) = nullptr; } #endif #ifndef AMD_SAFE_RELEASE -#ifndef VULKAN #define AMD_SAFE_RELEASE(p) { if (p) { (p)->Release(); } (p) = nullptr; } -#else -#define AMD_SAFE_RELEASE(object, releaseFunction, device) if (object != nullptr) releaseFunction(device, object, nullptr); -#endif #endif #define AMD_FUNCTION_WIDEN2(x) L ## x diff --git a/amd_tressfx/inc/AMD_TressFX.h b/amd_tressfx/inc/AMD_TressFX.h index 3de38ff..dd194c2 100644 --- a/amd_tressfx/inc/AMD_TressFX.h +++ b/amd_tressfx/inc/AMD_TressFX.h @@ -24,8 +24,12 @@ #define AMD_TRESSFX_H #include -#ifdef VULKAN +#if AMD_TRESSFX_VULKAN #include +#elif AMD_TRESSFX_DIRECT3D11 +#include +#else +#error #endif #include @@ -184,18 +188,17 @@ struct TressFX_HairBlob struct TressFX_SceneMesh { -#ifndef VULKAN +#if AMD_TRESSFX_VULKAN + VkBufferView pMeshVertices; // untransformed vertices + VkBufferView pTransformedVerts; // untransformed vertices +#elif AMD_TRESSFX_DIRECT3D11 ID3D11ShaderResourceView* pMeshVertices; // untransformed vertices + ID3D11ShaderResourceView* pTransformedVerts; // transformed vertices #else - VkBufferView pMeshVertices; // untransformed vertices +#error #endif unsigned numMeshes; // number of meshes unsigned* meshOffsets; // offset to the start of each mesh -#ifndef VULKAN - ID3D11ShaderResourceView* pTransformedVerts; // transformed vertices -#else - VkBufferView pTransformedVerts; // untransformed vertices -#endif }; struct TressFX_HairTransform @@ -252,52 +255,42 @@ struct TressFX_Desc // Buffer of transformations (one transform per strand) for hair skinning // This UAV is used as a structured buffer where each element is a TressFX_HairTransform. // The number of elements in the buffer is numTotalHairStrands. -#ifndef VULKAN - ID3D11UnorderedAccessView* pSkinningTransformationsUAV; -#else +#if AMD_TRESSFX_VULKAN VkBufferView pSkinningTransformationsUAV; -#endif - // hair shadow map -#ifndef VULKAN - ID3D11ShaderResourceView* pHairShadowMapSRV; -#else VkImageView pHairShadowMapSRV; -#endif - -#ifndef VULKAN + VkDevice pvkDevice; + VkPhysicalDeviceMemoryProperties memoryProperties; + VkImageView pvkDepthSRV; + uint32_t maxConstantBuffers; + VkFormat depthStencilFormat; + VkFormat colorFormat; +#elif AMD_TRESSFX_DIRECT3D11 + ID3D11UnorderedAccessView* pSkinningTransformationsUAV; + // hair shadow map + ID3D11ShaderResourceView* pHairShadowMapSRV; ID3D11Device* pd3dDevice; ID3D11DeviceContext* pd3dDeviceContext; ID3D11ShaderResourceView* pd3dDepthSRV; ID3D11RenderTargetView* pd3dOutputRTV; #else - VkDevice pvkDevice; - uint32_t memoryIndexDeviceLocal; - uint32_t memoryIndexHostVisible; - VkImageView pvkDepthSRV; - uint32_t maxConstantBuffers; - VkFormat depthStencilFormat; - VkFormat colorFormat; -#endif // !VULKAN +#error +#endif }; extern "C" { AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_GetVersion(uint* major, uint* minor, uint* patch); -#ifdef VULKAN + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadRawAsset(TressFX_Desc & desc, const TressFX_GuideFollowParams& guideFollowParams, TressFX_HairBlob *pRawHairBlob); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_End(TressFX_Desc & desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_GenerateTransforms(TressFX_Desc & desc, TressFX_SceneMesh &sceneMesh); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_ApplyRigidTransforms(TressFX_Desc & desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Release(TressFX_Desc & desc); +#if AMD_TRESSFX_VULKAN AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Initialize( TressFX_Desc &desc, VkImageView depthTexture, VkImageView colorTexture, VkCommandBuffer commandBuffer, VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer); -#else - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Initialize(TressFX_Desc &desc); -#endif - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadRawAsset(TressFX_Desc & desc, const TressFX_GuideFollowParams& guideFollowParams, TressFX_HairBlob *pRawHairBlob); -#ifndef VULKAN - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadProcessedAsset(TressFX_Desc & desc, TressFX_HairBlob *pHairBlob, TressFX_SceneMesh *sceneMesh, ID3D11ShaderResourceView *pTextureSRV); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_CreateProcessedAsset(TressFX_Desc & desc, TressFX_HairBlob **ppHairBlob, TressFX_SceneMesh *sceneMesh, ID3D11ShaderResourceView *pTextureSRV); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Begin(TressFX_Desc & desc); -#else AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadProcessedAsset( TressFX_Desc &desc, TressFX_HairBlob *pHairBlob, TressFX_SceneMesh *sceneMesh, VkImageView pTextureSRV, @@ -309,24 +302,24 @@ extern "C" VkCommandBuffer uploadCmdBuffer, VkBuffer scratchBuffer, VkDeviceMemory scratchMemory); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Begin(TressFX_Desc & desc, uint32_t uniformBufferIndex); -#endif - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_End(TressFX_Desc & desc); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_GenerateTransforms(TressFX_Desc & desc, TressFX_SceneMesh &sceneMesh); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_ApplyRigidTransforms(TressFX_Desc & desc); -#ifndef VULKAN - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Simulate(TressFX_Desc & desc, float elapsedTime); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_RenderShadowMap(TressFX_Desc & desc); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Render(TressFX_Desc & desc); - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Resize(TressFX_Desc &desc); -#else AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Simulate(TressFX_Desc & desc, VkCommandBuffer commandBuffer, float elapsedTime, uint32_t uniformBufferIndex); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_RenderShadowMap(TressFX_Desc & desc, VkCommandBuffer commandBuffer, uint32_t uniformBufferIndex); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Render(TressFX_Desc &desc, VkCommandBuffer commandBuffer, uint32_t uniformBufferIndex); AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE - TressFX_Resize(TressFX_Desc &desc, uint32_t texture_memory_index); + TressFX_Resize(TressFX_Desc &desc, VkPhysicalDeviceMemoryProperties memProperties); +#elif AMD_TRESSFX_DIRECT3D11 + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Initialize(TressFX_Desc &desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_LoadProcessedAsset(TressFX_Desc & desc, TressFX_HairBlob *pHairBlob, TressFX_SceneMesh *sceneMesh, ID3D11ShaderResourceView *pTextureSRV); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_CreateProcessedAsset(TressFX_Desc & desc, TressFX_HairBlob **ppHairBlob, TressFX_SceneMesh *sceneMesh, ID3D11ShaderResourceView *pTextureSRV); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Begin(TressFX_Desc & desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Render(TressFX_Desc & desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Resize(TressFX_Desc &desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_RenderShadowMap(TressFX_Desc & desc); + AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Simulate(TressFX_Desc & desc, float elapsedTime); +#else +#error #endif - AMD_TRESSFX_DLL_API TRESSFX_RETURN_CODE TressFX_Release(TressFX_Desc & desc); } } // namespace AMD diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj index 4e7fe13..a8a1c69 100644 --- a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2012.vcxproj @@ -224,7 +224,7 @@ NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) EditAndContinue Disabled @@ -252,7 +252,7 @@ xcopy "..\lib\VS2012\Win32\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) ProgramDatabase Disabled @@ -280,7 +280,7 @@ xcopy "..\lib\VS2012\x64\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nu NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -313,7 +313,7 @@ xcopy "..\lib\VS2012\Win32\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -346,7 +346,7 @@ xcopy "..\lib\VS2012\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) EditAndContinue Disabled @@ -367,7 +367,7 @@ xcopy "..\lib\VS2012\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) ProgramDatabase Disabled @@ -388,7 +388,7 @@ xcopy "..\lib\VS2012\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -414,7 +414,7 @@ xcopy "..\lib\VS2012\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -440,7 +440,7 @@ xcopy "..\lib\VS2012\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -474,7 +474,7 @@ xcopy "..\lib\VS2012\Win32\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj index 85cfdab..9c7fc12 100644 --- a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2013.vcxproj @@ -225,7 +225,7 @@ NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) EditAndContinue Disabled @@ -253,7 +253,7 @@ xcopy "..\lib\VS2013\Win32\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) ProgramDatabase Disabled @@ -281,7 +281,7 @@ xcopy "..\lib\VS2013\x64\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nu NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -314,7 +314,7 @@ xcopy "..\lib\VS2013\Win32\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -347,7 +347,7 @@ xcopy "..\lib\VS2013\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) EditAndContinue Disabled @@ -368,7 +368,7 @@ xcopy "..\lib\VS2013\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) ProgramDatabase Disabled @@ -389,7 +389,7 @@ xcopy "..\lib\VS2013\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -415,7 +415,7 @@ xcopy "..\lib\VS2013\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -441,7 +441,7 @@ xcopy "..\lib\VS2013\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -475,7 +475,7 @@ xcopy "..\lib\VS2013\Win32\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true diff --git a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj index 60a35dc..40fc07b 100644 --- a/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj +++ b/amd_tressfx_vulkan/build/AMD_TressFX_Vulkan_2015.vcxproj @@ -216,7 +216,7 @@ NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) EditAndContinue Disabled @@ -244,7 +244,7 @@ xcopy "..\lib\VS2015\Win32\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) ProgramDatabase Disabled @@ -272,7 +272,7 @@ xcopy "..\lib\VS2015\x64\DLL_Debug\$(TargetName).lib" "..\lib" /H /R /Y > nu NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -305,7 +305,7 @@ xcopy "..\lib\VS2015\Win32\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -338,7 +338,7 @@ xcopy "..\lib\VS2015\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) EditAndContinue Disabled @@ -359,7 +359,7 @@ xcopy "..\lib\VS2015\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) ProgramDatabase Disabled @@ -380,7 +380,7 @@ xcopy "..\lib\VS2015\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -406,7 +406,7 @@ xcopy "..\lib\VS2015\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_LIB;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=0;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -432,7 +432,7 @@ xcopy "..\lib\VS2015\x64\DLL_Release\$(TargetName).lib" "..\lib" /H /R /Y > NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true @@ -466,7 +466,7 @@ xcopy "..\lib\VS2015\Win32\DLL_Release_MT\$(TargetName).lib" "..\lib" /H /R /Y NotUsing Level4 true - VULKAN;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + AMD_TRESSFX_VULKAN=1;_USRDLL;AMD_TRESSFX_COMPILE_DYNAMIC_LIB=1;WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0601;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ..\inc;..\..\amd_lib\shared\common\inc;..\..\amd_tressfx\inc;..\..\amd_tressfx\src;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories) Full true diff --git a/amd_tressfx_vulkan/premake/premake5.lua b/amd_tressfx_vulkan/premake/premake5.lua index 3797848..11efec6 100644 --- a/amd_tressfx_vulkan/premake/premake5.lua +++ b/amd_tressfx_vulkan/premake/premake5.lua @@ -45,7 +45,7 @@ project ("AMD_" .. _AMD_LIBRARY_NAME .. "_Vulkan") -- Specify WindowsTargetPlatformVersion here for VS2015 windowstarget (_AMD_WIN_SDK_VERSION) - defines { "VULKAN"} + defines { "AMD_TRESSFX_VULKAN=1"} files { "../inc/**.h", "../src/**.h", "../src/**.cpp", "../src/Shaders/**.glsl", "../src/Shaders/**.comp", "../src/Shaders/**.vert", "../src/Shaders/**.frag", "../../amd_tressfx/src/TressFXAsset.cpp", "../../amd_tressfx/src/Util.cpp", "../../amd_tressfx/src/Math/**.cpp" } includedirs { "../inc", "../../amd_lib/shared/common/inc", "../../amd_tressfx/inc", "../../amd_tressfx/src", "$(VULKAN_SDK)/Include" } libdirs { "$(VULKAN_SDK)/Bin"} diff --git a/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py b/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py index 1f70c86..f0a4ec3 100644 --- a/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py +++ b/amd_tressfx_vulkan/shader_builder/shader_builder/shader_builder.py @@ -57,7 +57,8 @@ def load_array(name, filename): output.write(load_array("pass2_fragment", "TressFXRender_pass2.frag")) output.write(load_array("global_constraints", "GlobalConstraints.comp")) output.write(load_array("local_constraints", "LocalConstraints.comp")) -output.write(load_array("length_wind_tangent_compute", "LengthWindTangentComputation.comp")) +output.write(load_array("compute_tangents", "ComputeTangents.comp")) +output.write(load_array("length_wind_collision", "LengthWindCollision.comp")) output.write(load_array("prepare_follow_hair", "PrepareFollowHair.comp")) output.write(load_array("update_follow_hair", "UpdateFollowHair.comp")) output.write(load_array("depth_hair_data", "FS_Depth_Hair_Data.frag")) diff --git a/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert b/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert index 946d661..fac5ddd 100644 --- a/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert +++ b/amd_tressfx_vulkan/src/Shaders/TressFXRender_pass2.vert @@ -2,19 +2,36 @@ #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable - -layout(location = 0) in vec4 Position; -layout(location = 1) in vec4 Texcoord; - layout(location = 0) out vec2 vTex; out gl_PerVertex { vec4 gl_Position; }; +vec4 getPosition(uint index) +{ + switch (index) + { + case 0: return vec4(-1, 1, 0, 1); + case 1: return vec4(3, 1, 0, 1); + case 2: return vec4(-1, -3, 0, 1); + default: return vec4(0.); + } +} + +vec2 getTC(uint index) +{ + switch (index) + { + case 0: return vec2(0., 0.); + case 1: return vec2(0., 2.); + case 2: return vec2(2., 0.); + default: return vec2(0.); + } +} void main() { - gl_Position = vec4(Position.xyz, 1.0); - vTex = Texcoord.xy; + gl_Position = getPosition(gl_VertexIndex); + vTex = getTC(gl_VertexIndex); } diff --git a/amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp b/amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp index 12b5b5a..028d453 100644 --- a/amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp +++ b/amd_tressfx_vulkan/src/TressFXMeshVulkan.cpp @@ -33,17 +33,6 @@ #include #include -#ifndef AMD_V_RETURN -#define AMD_V_RETURN(x) \ - { \ - vr = (x); \ - if (vr != VK_SUCCESS) \ - { \ - return vr; \ - } \ - } -#endif - using namespace std; using namespace DirectX; @@ -57,8 +46,8 @@ namespace AMD // Used for initializing member variables to default values. //-------------------------------------------------------------------------------------- TressFXMesh::TressFXMesh(void) - : m_pIndexBuffer(NULL), m_pTriangleIndexBuffer(NULL), m_pThicknessCoeffsBuffer(NULL), - m_pTriangleIndexMemory(NULL), m_pThicknessCoeffsView(NULL) + : m_pIndexBuffer(NULL), m_pTriangleIndexBuffer(NULL), m_pThicknessCoeffsBuffer(NULL), m_pThicknessIndexTriangleIndexMemory(NULL), + m_pThicknessCoeffsView(NULL) { m_HairVertexPositionsBuffer = NULL; m_HairVertexPositionsView = NULL; @@ -129,10 +118,13 @@ TressFXMesh::~TressFXMesh(void) { OnDestroy(); } // and stores the hair data into these resources. // //-------------------------------------------------------------------------------------- -VkResult TressFXMesh::OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, - TressFX_SceneMesh *sceneMesh, VkImageView pTexture, - uint32_t texture_buffer_memory_index, - VkCommandBuffer upload_cmd_buffer, VkBuffer scratchBuffer, +VkResult TressFXMesh::OnCreate(VkDevice pvkDevice, + TressFX_HairBlob *pHairBlob, + TressFX_SceneMesh *sceneMesh, + VkImageView pTexture, + VkPhysicalDeviceMemoryProperties memProperties, + VkCommandBuffer upload_cmd_buffer, + VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, VkDescriptorSetLayout GlobalConstraintsSetLayout, VkDescriptorSetLayout LocalConstraintsSetLayout, @@ -141,9 +133,10 @@ VkResult TressFXMesh::OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, VkDescriptorSetLayout UpdateFollowHaitSetLayout, VkDescriptorSetLayout computeTangentSetLayout, VkDescriptorSetLayout Pass1SetLayout, - VkDescriptorSetLayout ShadowSetLayout) + VkDescriptorSetLayout ShadowSetLayout, const DebugMarkerPointer& markerCallbacks) { VkResult vr; + size_t offsetInUploadBuffer = 0; // load the binary file if (!Deserialize(pHairBlob)) @@ -151,26 +144,71 @@ VkResult TressFXMesh::OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, return VK_ERROR_INITIALIZATION_FAILED; } - size_t sizeToUpload = m_HairAsset.m_NumTotalHairVertices * sizeof(float); - - void *uploadBuffer; - size_t offsetInUploadBuffer = 0; - vkMapMemory(pvkDevice, scratchMemory, 0, sizeToUpload, 0, &uploadBuffer); - - // thickness coeff buffer + // Create Buffers { + // thickness coeff buffer VkBufferCreateInfo bd{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; bd.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; bd.size = sizeof(float) * m_HairAsset.m_NumTotalHairVertices; + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pThicknessCoeffsBuffer)); + + //----------------------------------- + // Index buffer (lines and triangles) + //----------------------------------- + + // Line index buffer + m_TotalIndexCount = (int)m_HairAsset.m_LineIndices.size(); + bd.size = (UINT)(sizeof(unsigned int) * m_TotalIndexCount); + bd.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pIndexBuffer)); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pThicknessCoeffsBuffer)); - m_pThicknessCoeffsMemory = allocBufferMemory(pvkDevice, m_pThicknessCoeffsBuffer, - texture_buffer_memory_index); + // Triangle index buffer + m_TotalTriangleIndexCount = (int)m_HairAsset.m_TriangleIndices.size(); + bd.size = (UINT)(sizeof(unsigned int) * m_TotalTriangleIndexCount); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pTriangleIndexBuffer)); + + VkMemoryRequirements thicknessBufferMemReq; + vkGetBufferMemoryRequirements(pvkDevice, m_pThicknessCoeffsBuffer, &thicknessBufferMemReq); + VkMemoryRequirements indexBufferMemReq; + vkGetBufferMemoryRequirements(pvkDevice, m_pIndexBuffer, &indexBufferMemReq); + VkMemoryRequirements triangleIndexBufferMemReq; + vkGetBufferMemoryRequirements(pvkDevice, m_pTriangleIndexBuffer, &triangleIndexBufferMemReq); + + uint32_t memoryType = getMemoryTypeIndex(indexBufferMemReq.memoryTypeBits & triangleIndexBufferMemReq.memoryTypeBits & thicknessBufferMemReq.memoryTypeBits, + memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + if (memoryType == -1) return VK_ERROR_INITIALIZATION_FAILED; + + VkDeviceSize indexBufferOffset = align(thicknessBufferMemReq.size, indexBufferMemReq.alignment); + VkDeviceSize triangleIndexBufferOffset = align(indexBufferOffset + indexBufferMemReq.size, triangleIndexBufferMemReq.alignment); + VkDeviceSize totalSize = triangleIndexBufferOffset + triangleIndexBufferMemReq.size; + + VkMemoryAllocateInfo allocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; + allocateInfo.allocationSize = totalSize; + allocateInfo.memoryTypeIndex = memoryType; + vkAllocateMemory(pvkDevice, &allocateInfo, nullptr, &m_pThicknessIndexTriangleIndexMemory); + + vkBindBufferMemory(pvkDevice, m_pThicknessCoeffsBuffer, m_pThicknessIndexTriangleIndexMemory, 0); + vkBindBufferMemory(pvkDevice, m_pIndexBuffer, m_pThicknessIndexTriangleIndexMemory, indexBufferOffset); + vkBindBufferMemory(pvkDevice, m_pTriangleIndexBuffer, m_pThicknessIndexTriangleIndexMemory, triangleIndexBufferOffset); + + // Fill them + void *uploadBuffer; + vkMapMemory(pvkDevice, scratchMemory, 0, totalSize, 0, &uploadBuffer); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pThicknessCoeffs, m_pThicknessCoeffsBuffer, - offsetInUploadBuffer, bd.size); + offsetInUploadBuffer, sizeof(float) * m_HairAsset.m_NumTotalHairVertices); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + &m_HairAsset.m_LineIndices[0], m_pIndexBuffer, offsetInUploadBuffer, + sizeof(unsigned int) * m_TotalIndexCount); + + fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, + &m_HairAsset.m_TriangleIndices[0], m_pTriangleIndexBuffer, + offsetInUploadBuffer, sizeof(unsigned int) * m_TotalTriangleIndexCount); + vkUnmapMemory(pvkDevice, scratchMemory); } // thickness coeff buffer srv @@ -180,53 +218,21 @@ VkResult TressFXMesh::OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, SRVDesc.range = m_HairAsset.m_NumTotalHairVertices * sizeof(float); SRVDesc.buffer = m_pThicknessCoeffsBuffer; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &SRVDesc, nullptr, &m_pThicknessCoeffsView)); } - //----------------------------------- - // Index buffer (lines and triangles) - //----------------------------------- - - // Line index buffer - m_TotalIndexCount = (int)m_HairAsset.m_LineIndices.size(); - - VkBufferCreateInfo bd{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; - bd.size = (UINT)(sizeof(unsigned int) * m_HairAsset.m_LineIndices.size()); - bd.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pIndexBuffer)); - m_pIndexMemory = - allocBufferMemory(pvkDevice, m_pIndexBuffer, texture_buffer_memory_index); - - fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, - &m_HairAsset.m_LineIndices[0], m_pIndexBuffer, offsetInUploadBuffer, - bd.size); - - // Triangle index buffer - m_TotalTriangleIndexCount = (int)m_HairAsset.m_TriangleIndices.size(); - bd.size = (UINT)(sizeof(unsigned int) * m_HairAsset.m_TriangleIndices.size()); - - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pTriangleIndexBuffer)); - m_pTriangleIndexMemory = - allocBufferMemory(pvkDevice, m_pTriangleIndexBuffer, texture_buffer_memory_index); - - fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, - &m_HairAsset.m_TriangleIndices[0], m_pTriangleIndexBuffer, - offsetInUploadBuffer, bd.size); - - vkUnmapMemory(pvkDevice, scratchMemory); - m_pHairTextureSRV = pTexture; - vr = CreateBufferAndViews(pvkDevice, sceneMesh, texture_buffer_memory_index, - upload_cmd_buffer, scratchBuffer, scratchMemory, - offsetInUploadBuffer); - vr = - AllocateDescriptorsSets(pvkDevice, GlobalConstraintsSetLayout, + AMD_CHECKED_VULKAN_CALL(CreateBufferAndViews(pvkDevice, sceneMesh, + memProperties, + upload_cmd_buffer, scratchBuffer, + scratchMemory, + offsetInUploadBuffer, markerCallbacks )); + AMD_CHECKED_VULKAN_CALL(AllocateDescriptorsSets(pvkDevice, GlobalConstraintsSetLayout, LocalConstraintsSetLayout, LenghtWindCollisionSetLayout, PrepareFollowHairSetLayout, UpdateFollowHaitSetLayout, - computeTangentSetLayout, Pass1SetLayout, ShadowSetLayout); + computeTangentSetLayout, Pass1SetLayout, ShadowSetLayout)); VkBufferMemoryBarrier bufferBarrier[] = { getBufferBarrier(m_pThicknessCoeffsBuffer, VK_ACCESS_TRANSFER_WRITE_BIT, @@ -268,9 +274,11 @@ VkResult TressFXMesh::OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, // //-------------------------------------------------------------------------------------- VkResult TressFXMesh::CreateBufferAndViews( - VkDevice pvkDevice, TressFX_SceneMesh *sceneMesh, - uint32_t texture_buffer_memory_index, VkCommandBuffer upload_cmd_buffer, - VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, size_t &offsetInUploadBuffer) + VkDevice pvkDevice, + TressFX_SceneMesh *sceneMesh, + VkPhysicalDeviceMemoryProperties memProp, + VkCommandBuffer upload_cmd_buffer, + VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, size_t &offsetInUploadBuffer, const DebugMarkerPointer& markerCallbacks) { VkResult vr; m_pvkDevice = pvkDevice; @@ -307,19 +315,21 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDesc.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; bufferDesc.size = m_HairAsset.m_NumTotalHairStrands * sizeof(int); - // AMD_SAFE_RELEASE(m_HairStrandTypeBuffer); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_HairStrandTypeBuffer)); + markerCallbacks.nameObject(m_HairStrandTypeBuffer, "HairStrandTypeBuffer"); + m_HairStrandTypeMemory = allocBufferMemory(pvkDevice, m_HairStrandTypeBuffer, - texture_buffer_memory_index); + memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_HairStrandTypeMemory, "HairStrandTypeMemory"); VkBufferViewCreateInfo SRVDesc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; SRVDesc.format = VK_FORMAT_R32_SINT; SRVDesc.range = m_HairAsset.m_NumTotalHairStrands * sizeof(int32_t); SRVDesc.buffer = m_HairStrandTypeBuffer; - // AMD_SAFE_RELEASE(m_HairStrandTypeSRV); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &SRVDesc, nullptr, &m_HairStrandTypeView)); + markerCallbacks.nameObject(m_HairStrandTypeView, "HairStrandTypeView"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pHairStrandType, m_HairStrandTypeBuffer, offsetInUploadBuffer, bufferDesc.size); @@ -334,19 +344,20 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDesc.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); bufferDesc.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - // AMD_SAFE_RELEASE(m_InitialHairPositionsBuffer); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_InitialHairPositionsBuffer)); + markerCallbacks.nameObject(m_InitialHairPositionsBuffer, "InitialHairPositionBuffer"); m_InitialHairPositionsMemory = allocBufferMemory( - pvkDevice, m_InitialHairPositionsBuffer, texture_buffer_memory_index); + pvkDevice, m_InitialHairPositionsBuffer, memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_InitialHairPositionsMemory, "InitialHairPositionsMemory"); VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; desc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); desc.buffer = m_InitialHairPositionsBuffer; - // AMD_SAFE_RELEASE(m_InitialHairPositionsSRV); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &desc, nullptr, &m_InitialHairPositionsView)); + markerCallbacks.nameObject(m_InitialHairPositionsView, "InitialHairPositionsView"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pVertices, m_InitialHairPositionsBuffer, offsetInUploadBuffer, bufferDesc.size); @@ -361,17 +372,19 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDescUA.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - // AMD_SAFE_RELEASE(m_HairVertexPositionsUAB); - // AMD_SAFE_RELEASE(m_HairVertexPositionsPrevUAB); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_HairVertexPositionsBuffer)); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + markerCallbacks.nameObject(m_HairVertexPositionsBuffer, "HairVertexPositionsBuffer"); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_HairVertexPositionsPrevBuffer)); + markerCallbacks.nameObject(m_HairVertexPositionsPrevBuffer, "HairVertexPositionsPrevBuffer"); m_HairVertexPositionsMemory = allocBufferMemory( - pvkDevice, m_HairVertexPositionsBuffer, texture_buffer_memory_index); + pvkDevice, m_HairVertexPositionsBuffer, memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_HairVertexPositionsMemory, "HairVertexPositionsMemory"); m_HairVertexPositionsPrevMemory = allocBufferMemory( - pvkDevice, m_HairVertexPositionsPrevBuffer, texture_buffer_memory_index); + pvkDevice, m_HairVertexPositionsPrevBuffer, memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_HairVertexPositionsPrevMemory, "HairVertexPositionsPrevMemory"); // TODO: We could write only once to uploadBuffer and share data between // the // 3 buffers @@ -392,11 +405,12 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDescUA.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - // AMD_SAFE_RELEASE(m_HairVertexTangentsUAB); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_HairVertexTangentsBuffer)); + markerCallbacks.nameObject(m_HairVertexTangentsBuffer, "HairVertexTangentsBuffer"); m_HairVertexTangentsMemory = allocBufferMemory( - pvkDevice, m_HairVertexTangentsBuffer, texture_buffer_memory_index); + pvkDevice, m_HairVertexTangentsBuffer, memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_HairVertexTangentsMemory, "HairVertexTangentsMemory"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pTangents, m_HairVertexTangentsBuffer, offsetInUploadBuffer, bufferDescUA.size); @@ -410,9 +424,9 @@ VkResult TressFXMesh::CreateBufferAndViews( sbSRVDesc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); sbSRVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; sbSRVDesc.buffer = m_HairVertexPositionsBuffer; - // AMD_SAFE_RELEASE(m_HairVertexPositionsSRV); - AMD_V_RETURN(vkCreateBufferView(pvkDevice, &sbSRVDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBufferView(pvkDevice, &sbSRVDesc, nullptr, &m_HairVertexPositionsView)); + markerCallbacks.nameObject(m_HairVertexPositionsView, "HairVertexPositionsView"); } //----------------------- @@ -423,9 +437,9 @@ VkResult TressFXMesh::CreateBufferAndViews( sbSRVDesc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); sbSRVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; sbSRVDesc.buffer = m_HairVertexTangentsBuffer; - // AMD_SAFE_RELEASE(m_HairVertexTangentsSRV); - AMD_V_RETURN(vkCreateBufferView(pvkDevice, &sbSRVDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBufferView(pvkDevice, &sbSRVDesc, nullptr, &m_HairVertexTangentsView)); + markerCallbacks.nameObject(m_HairVertexTangentsView, "HairVertexTangentsView"); } //----------------------- @@ -436,10 +450,9 @@ VkResult TressFXMesh::CreateBufferAndViews( sbUAVDesc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); sbUAVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; sbUAVDesc.buffer = m_HairVertexPositionsPrevBuffer; - // AMD_SAFE_RELEASE(m_HairVertexPositionsUAV); - // AMD_SAFE_RELEASE(m_HairVertexPositionsPrevUAV); - AMD_V_RETURN(vkCreateBufferView(pvkDevice, &sbUAVDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBufferView(pvkDevice, &sbUAVDesc, nullptr, &m_HairVertexPositionsPrevView)); + markerCallbacks.nameObject(m_HairVertexPositionsPrevView, "HairVertexPositionsPrevView"); } //--------------------------- @@ -451,10 +464,12 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDesc.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // AMD_SAFE_RELEASE(m_HairLengthBuffer); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_HairLengthBuffer)); + markerCallbacks.nameObject(m_HairLengthBuffer, "HairLengthBuffer"); m_HairLengthMemory = - allocBufferMemory(pvkDevice, m_HairLengthBuffer, texture_buffer_memory_index); + allocBufferMemory(pvkDevice, m_HairLengthBuffer, memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_HairLengthMemory, "HairLengthMemory"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pRestLengths, m_HairLengthBuffer, @@ -464,8 +479,8 @@ VkResult TressFXMesh::CreateBufferAndViews( desc.format = VK_FORMAT_R32_SFLOAT; desc.range = m_HairAsset.m_NumTotalHairVertices * sizeof(float); desc.buffer = m_HairLengthBuffer; - // AMD_SAFE_RELEASE(m_HairRestLengthSRV); - AMD_V_RETURN(vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairRestLengthSRV)); + AMD_CHECKED_VULKAN_CALL(vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairRestLengthSRV)); + markerCallbacks.nameObject(m_HairRestLengthSRV, "HairRestLengthSRV"); } //----------------------------------- @@ -477,11 +492,12 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDesc.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); bufferDesc.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - // AMD_SAFE_RELEASE(m_HairRefVectorsBuffer); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_HairRefVectorsBuffer)); + markerCallbacks.nameObject(m_HairRefVectorsBuffer, "HairRefVectorsBuffer"); m_HairRefVectorsMemory = allocBufferMemory(pvkDevice, m_HairRefVectorsBuffer, - texture_buffer_memory_index); + memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_HairRefVectorsMemory, "HairRefVectorsMemory"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pRefVectors, m_HairRefVectorsBuffer, @@ -491,9 +507,9 @@ VkResult TressFXMesh::CreateBufferAndViews( desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; desc.range = m_HairAsset.m_NumTotalHairVertices * 4 * sizeof(float); desc.buffer = m_HairRefVectorsBuffer; - // AMD_SAFE_RELEASE(m_HairRefVecsInLocalFrameSRV); - AMD_V_RETURN(vkCreateBufferView(pvkDevice, &desc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairRefVecsInLocalFrameView)); + markerCallbacks.nameObject(m_HairRefVecsInLocalFrameView, "HairRefVecsInLocalFrameView"); } //----------------------------------- @@ -505,10 +521,12 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDesc.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // AMD_SAFE_RELEASE(m_FollowHairRootOffsetBuffer); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_FollowHairRootOffsetBuffer)); + markerCallbacks.nameObject(m_FollowHairRootOffsetBuffer, "FollowHairRootOffsetBuffer"); m_FollowHairRootOffsetMemory = allocBufferMemory( - pvkDevice, m_FollowHairRootOffsetBuffer, texture_buffer_memory_index); + pvkDevice, m_FollowHairRootOffsetBuffer, memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_FollowHairRootOffsetMemory, "FollowHaitRootOffsetMemory"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pFollowRootOffset, m_FollowHairRootOffsetBuffer, @@ -518,9 +536,9 @@ VkResult TressFXMesh::CreateBufferAndViews( desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; desc.range = m_HairAsset.m_NumTotalHairStrands * 4 * sizeof(float); desc.buffer = m_FollowHairRootOffsetBuffer; - // AMD_SAFE_RELEASE(m_FollowHairRootOffsetSRV); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &desc, nullptr, &m_FollowHairRootOffsetView)); + markerCallbacks.nameObject(m_FollowHairRootOffsetView, "FollowHairRootOffsetView"); } // -------------------------------------------- @@ -531,11 +549,12 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDescUA.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); bufferDescUA.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - // AMD_SAFE_RELEASE(m_GlobalRotationsUAB); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_GlobalRotationsBuffer)); + markerCallbacks.nameObject(m_GlobalRotationsBuffer, "GlobalRotationsBuffer"); m_GlobalRotationsMemory = allocBufferMemory(pvkDevice, m_GlobalRotationsBuffer, - texture_buffer_memory_index); + memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_GlobalRotationsMemory, "GlobalRotationsMemory"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pGlobalRotations, m_GlobalRotationsBuffer, @@ -545,9 +564,9 @@ VkResult TressFXMesh::CreateBufferAndViews( sbUAVDesc.range = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); sbUAVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; sbUAVDesc.buffer = m_GlobalRotationsBuffer; - // AMD_SAFE_RELEASE(m_GlobalRotationsUAV); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &sbUAVDesc, nullptr, &m_GlobalRotationsView)); + markerCallbacks.nameObject(m_GlobalRotationsView, "GlobalRotationsView"); } // -------------------------------------------- @@ -558,11 +577,12 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDescUA.size = m_HairAsset.m_NumTotalHairVertices * sizeof(XMFLOAT4); bufferDescUA.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - // AMD_SAFE_RELEASE(m_LocalRotationsUAB); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_LocalRotationsBuffer)); + markerCallbacks.nameObject(m_LocalRotationsBuffer, "LocalROtationsBuffer"); m_LocalRotationsMemory = allocBufferMemory(pvkDevice, m_LocalRotationsBuffer, - texture_buffer_memory_index); + memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_LocalRotationsMemory, "LocalRotationMemory"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pLocalRotations, m_LocalRotationsBuffer, @@ -573,7 +593,7 @@ VkResult TressFXMesh::CreateBufferAndViews( sbUAVDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; sbUAVDesc.buffer = m_LocalRotationsBuffer; // AMD_SAFE_RELEASE(m_LocalRotationsUAV); - // AMD_V_RETURN( + // AMD_CHECKED_VULKAN_CALL( // vkCreateBufferView(pvkDevice, &sbUAVDesc, nullptr, // &m_LocalRotationsView)); } @@ -598,18 +618,18 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDesc.size = m_HairAsset.m_NumTotalHairStrands * sizeof(HairToTriangleMapping); bufferDesc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - // AMD_SAFE_RELEASE(m_HairSkinMappingBuffer); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_HairSkinMappingBuffer)); + markerCallbacks.nameObject(m_HairSkinMappingBuffer, "HairSkinMappingBuffer"); VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; desc.format = VK_FORMAT_UNDEFINED; desc.range = m_HairAsset.m_NumTotalHairStrands * sizeof(HairToTriangleMapping); desc.buffer = m_HairSkinMappingBuffer; - // AMD_SAFE_RELEASE(m_HairSkinMappingSRV); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairSkinMappingView)); + markerCallbacks.nameObject(m_HairSkinMappingView, "HairSkinMappingView"); } // -------------------------------------------- @@ -644,25 +664,22 @@ VkResult TressFXMesh::CreateBufferAndViews( } } - // D3D11_SUBRESOURCE_DATA initialData; - // initialData.pSysMem = (void *)pTransforms; - VkBufferCreateInfo bufferDescUA{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; bufferDescUA.size = m_HairAsset.m_NumTotalHairStrands * sizeof(TressFX_HairTransform); bufferDescUA.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - // AMD_SAFE_RELEASE(m_HairTransformsBuffer); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDescUA, nullptr, &m_HairTransformsBuffer)); + markerCallbacks.nameObject(m_HairTransformsBuffer, "HairTransformsBuffer"); VkBufferViewCreateInfo desc{VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; desc.range = m_HairAsset.m_NumTotalHairStrands * sizeof(TressFX_HairTransform); desc.format = VK_FORMAT_UNDEFINED; desc.buffer = m_HairTransformsBuffer; - // AMD_SAFE_RELEASE(m_HairTransformsSRV); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &desc, nullptr, &m_HairTransformsView)); + markerCallbacks.nameObject(m_HairTransformsView, "HairTransformView"); AMD_SAFE_DELETE_ARRAY(pTransforms); } @@ -678,11 +695,12 @@ VkResult TressFXMesh::CreateBufferAndViews( bufferDesc.size = m_HairAsset.m_NumTotalHairStrands * sizeof(float) * 2; bufferDesc.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - // AMD_SAFE_RELEASE(m_pStrandTexCoordBuffer); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &bufferDesc, nullptr, &m_pStrandTexCoordBuffer)); + markerCallbacks.nameObject(m_pStrandTexCoordBuffer, "StrandTexCoordBuffer"); m_pStrandTexCoordMemory = allocBufferMemory( - pvkDevice, m_pStrandTexCoordBuffer, texture_buffer_memory_index); + pvkDevice, m_pStrandTexCoordBuffer, memProp, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + markerCallbacks.nameObject(m_pStrandTexCoordMemory, "StrandTexCoordMemory"); fillInitialData(upload_cmd_buffer, scratchBuffer, uploadBuffer, m_HairAsset.m_pStrandTexCoords, m_pStrandTexCoordBuffer, @@ -693,8 +711,9 @@ VkResult TressFXMesh::CreateBufferAndViews( desc.range = m_HairAsset.m_NumTotalHairStrands * sizeof(float) * 2; desc.buffer = m_pStrandTexCoordBuffer; // AMD_SAFE_RELEASE(m_pStrandTexCoordSRV); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBufferView(pvkDevice, &desc, nullptr, &m_pStrandTexCoordView)); + markerCallbacks.nameObject(m_pStrandTexCoordView, "StrandTexCoordView"); } } vkUnmapMemory(pvkDevice, scratchMemory); @@ -717,7 +736,7 @@ VkResult TressFXMesh::AllocateDescriptorsSets( info.poolSizeCount = AMD_ARRAY_SIZE(poolSizes); info.pPoolSizes = poolSizes; VkResult vr; - AMD_V_RETURN(vkCreateDescriptorPool(pvkDevice, &info, nullptr, &m_descriptorPool)); + AMD_CHECKED_VULKAN_CALL(vkCreateDescriptorPool(pvkDevice, &info, nullptr, &m_descriptorPool)); const VkDescriptorSetLayout setLayouts[] = {GlobalConstraintsSetLayout, LocalConstraintsSetLayout, @@ -735,7 +754,7 @@ VkResult TressFXMesh::AllocateDescriptorsSets( VkDescriptorSet sets[AMD_ARRAY_SIZE(setLayouts)]{}; - AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &allocateInfo, sets)); + AMD_CHECKED_VULKAN_CALL(vkAllocateDescriptorSets(pvkDevice, &allocateInfo, sets)); m_GlobalConstraintsSet = sets[0]; m_LocalConstraintsSet = sets[1]; m_LenghtWindCollisionSet = sets[2]; @@ -835,10 +854,6 @@ VkResult TressFXMesh::AllocateDescriptorsSets( return VK_SUCCESS; } -#define AMD_SAFE_RELEASE(object, releaseFunction, device) \ - if (object != nullptr) \ - releaseFunction(device, object, nullptr); - //-------------------------------------------------------------------------------------- // // OnDestroy @@ -849,14 +864,12 @@ VkResult TressFXMesh::AllocateDescriptorsSets( void TressFXMesh::OnDestroy() { AMD_SAFE_RELEASE(m_pTriangleIndexBuffer, vkDestroyBuffer, m_pvkDevice); - AMD_SAFE_RELEASE(m_pTriangleIndexMemory, vkFreeMemory, m_pvkDevice); AMD_SAFE_RELEASE(m_pIndexBuffer, vkDestroyBuffer, m_pvkDevice); - AMD_SAFE_RELEASE(m_pIndexMemory, vkFreeMemory, m_pvkDevice); AMD_SAFE_RELEASE(m_pThicknessCoeffsView, vkDestroyBufferView, m_pvkDevice); AMD_SAFE_RELEASE(m_pThicknessCoeffsBuffer, vkDestroyBuffer, m_pvkDevice); - AMD_SAFE_RELEASE(m_pThicknessCoeffsMemory, vkFreeMemory, m_pvkDevice); + AMD_SAFE_RELEASE(m_pThicknessIndexTriangleIndexMemory, vkFreeMemory, m_pvkDevice); // compute shader variables AMD_SAFE_RELEASE(m_HairVertexPositionsView, vkDestroyBufferView, m_pvkDevice); diff --git a/amd_tressfx_vulkan/src/TressFXMeshVulkan.h b/amd_tressfx_vulkan/src/TressFXMeshVulkan.h index eed8992..480a29f 100644 --- a/amd_tressfx_vulkan/src/TressFXMeshVulkan.h +++ b/amd_tressfx_vulkan/src/TressFXMeshVulkan.h @@ -29,6 +29,7 @@ #pragma once #include "TressFXAsset.h" #include "Util.h" +#include "UtilVulkan.h" namespace AMD { @@ -38,11 +39,13 @@ class TressFXMesh private: VkDevice m_pvkDevice; // private member function - VkResult CreateBufferAndViews(VkDevice pvkDevice, TressFX_SceneMesh *sceneMesh, - uint32_t texture_buffer_memory_index, + VkResult CreateBufferAndViews(VkDevice pvkDevice, + TressFX_SceneMesh *sceneMesh, + VkPhysicalDeviceMemoryProperties memProperties, VkCommandBuffer upload_cmd_buffer, - VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, - size_t &offsetInUploadBuffer); + VkBuffer scratchBuffer, + VkDeviceMemory scratchMemory, + size_t &offsetInUploadBuffer, const DebugMarkerPointer& markerCallbacks); VkResult AllocateDescriptorsSets(VkDevice pvkDevice, VkDescriptorSetLayout GlobalConstraintsSetLayout, @@ -58,11 +61,10 @@ class TressFXMesh public: VkBuffer m_pIndexBuffer; - VkDeviceMemory m_pIndexMemory; VkBuffer m_pTriangleIndexBuffer; - VkDeviceMemory m_pTriangleIndexMemory; VkBuffer m_pThicknessCoeffsBuffer; - VkDeviceMemory m_pThicknessCoeffsMemory; + // Store thickness, index and triangle index buffer + VkDeviceMemory m_pThicknessIndexTriangleIndexMemory; VkBufferView m_pThicknessCoeffsView; int m_TotalIndexCount; int m_TotalTriangleIndexCount; @@ -149,18 +151,29 @@ class TressFXMesh TressFXMesh(void); ~TressFXMesh(void); - VkResult OnCreate(VkDevice pvkDevice, TressFX_HairBlob *pHairBlob, - TressFX_SceneMesh *sceneMesh, VkImageView pTexture, - uint32_t MemoryIndexGPU, VkCommandBuffer upload_cmd_buffer, - VkBuffer scratchBuffer, VkDeviceMemory scratchMemory, + VkResult OnCreate(VkDevice pvkDevice, + TressFX_HairBlob *pHairBlob, + TressFX_SceneMesh *sceneMesh, + VkImageView pTexture, + VkPhysicalDeviceMemoryProperties memProperties, + VkCommandBuffer upload_cmd_buffer, + VkBuffer scratchBuffer, + VkDeviceMemory scratchMemory, + VkDescriptorSetLayout GlobalConstraintsSetLayout, + VkDescriptorSetLayout LocalConstraintsSetLayout, + VkDescriptorSetLayout LenghtWindCollisiontSetLayout, + VkDescriptorSetLayout PrepareFollowHairSetLayout, + VkDescriptorSetLayout UpdateFollowHaitSetLayout, + VkDescriptorSetLayout ComputeTangetSetLayout, + VkDescriptorSetLayout Pass1SetLayout, - VkDescriptorSetLayout ShadowSetLayout); + VkDescriptorSetLayout ShadowSetLayout, const DebugMarkerPointer& markerCallbacks); void OnDestroy(); void DestroyAsset(); diff --git a/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp index 69891e7..441c1e0 100644 --- a/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp +++ b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.cpp @@ -24,26 +24,26 @@ namespace AMD { -void TressFX_OpaqueDesc::Initialize(TressFX_Desc &desc, VkImageView depthTexture, +void TressFX_OpaqueDesc::Initialize(TressFX_Desc &desc, + VkImageView depthTexture, VkImageView colorTexture, VkCommandBuffer commandBuffer, - VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, + VkDeviceMemory scratchMemory, + VkBuffer scratchBuffer, size_t &offsetInScratchBuffer, - uint32_t cpu_memory_index, uint32_t gpu_memory_index) + VkPhysicalDeviceMemoryProperties memProperties) { - if (initialized == false) - { - refCount = 0; - tressFXSimulation.OnCreateDevice(desc.pvkDevice, &desc.collisionCapsule, - desc.maxConstantBuffers, cpu_memory_index, - gpu_memory_index); - tressFXRenderer.OnCreateDevice( - desc.pvkDevice, desc.backBufferWidth, desc.backBufferHeight, desc.bShortCutOn, - desc.maxConstantBuffers, cpu_memory_index, desc.memoryIndexDeviceLocal, - depthTexture, colorTexture, commandBuffer, scratchMemory, scratchBuffer, - offsetInScratchBuffer); - initialized = true; - } + refCount = 0; + markerCallbacks.init(desc.pvkDevice); + tressFXSimulation.OnCreateDevice(desc.pvkDevice, + &desc.collisionCapsule, + desc.maxConstantBuffers, memProperties, + markerCallbacks); + tressFXRenderer.OnCreateDevice( + desc.pvkDevice, desc.backBufferWidth, desc.backBufferHeight, desc.bShortCutOn, + desc.maxConstantBuffers, memProperties, + depthTexture, colorTexture, commandBuffer, scratchMemory, scratchBuffer, + offsetInScratchBuffer, desc.depthStencilFormat, desc.colorFormat); refCount++; } @@ -52,7 +52,6 @@ void TressFX_OpaqueDesc::Release(VkDevice pvkDevice) refCount--; if (refCount <= 0) { - initialized = false; tressFXRenderer.OnDestroy(); tressFXSimulation.OnDestroy(pvkDevice); refCount = 0; @@ -68,7 +67,7 @@ bool TressFX_OpaqueDesc::LoadAppendAsset( bool TressFX_OpaqueDesc::CreateProcessedAsset( TressFX_Desc &desc, TressFX_HairBlob **ppHairBlob, TressFX_SceneMesh *sceneMesh, - VkImageView hairTexture, uint32_t texture_buffer_memory_index, + VkImageView hairTexture, VkPhysicalDeviceMemoryProperties memProperties, VkCommandBuffer uploadCmdBuffer, VkBuffer scratchBuffer, VkDeviceMemory scratchMemory) { tressFXAssetLoader.GenerateFollowHairs(); @@ -89,16 +88,20 @@ bool TressFX_OpaqueDesc::CreateProcessedAsset( delete pTressFXMesh; } pTressFXMesh = new TressFXMesh(); - pTressFXMesh->OnCreate(desc.pvkDevice, &desc.tressFXHair, sceneMesh, hairTexture, - texture_buffer_memory_index, uploadCmdBuffer, scratchBuffer, - scratchMemory, tressFXSimulation.m_GlobalConstraintsSetLayout, + pTressFXMesh->OnCreate(desc.pvkDevice, &desc.tressFXHair, sceneMesh, + hairTexture, + memProperties, uploadCmdBuffer, + scratchBuffer, + scratchMemory, + tressFXSimulation.m_GlobalConstraintsSetLayout, tressFXSimulation.m_LocalConstraintsSetLayout, tressFXSimulation.m_LenghtWindTangentSetLayout, tressFXSimulation.m_PrepareFollowHairSetLayout, tressFXSimulation.m_UpdateFollowHaitSetLayout, desc.pOpaque->tressFXSimulation.m_ComputeTangentSetLayout, tressFXRenderer.m_pass1_hair_set_layout, - tressFXRenderer.m_shadow_pass_hair_set_layout); + tressFXRenderer.m_shadow_pass_hair_set_layout, + desc.pOpaque->markerCallbacks); desc.numTotalHairStrands = pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; desc.numTotalHairVertices = pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; @@ -129,8 +132,9 @@ bool TressFX_OpaqueDesc::Simulate(TressFX_Desc &desc, VkCommandBuffer commandBuf windDir.z = desc.simulationParams.windDir.z; VkResult vr = tressFXSimulation.Simulate( desc.pvkDevice, commandBuffer, elapsedTime, desc.hairParams.density, windDir, - desc.simulationParams.windMag, &desc.modelTransformForHead, nullptr, - desc.targetFrameRate, desc.bSingleHeadTransform, false, uniformBufferIndex); + desc.simulationParams.windMag, &desc.modelTransformForHead, + desc.targetFrameRate, desc.bSingleHeadTransform, false, uniformBufferIndex, + markerCallbacks); return vr == VK_SUCCESS; } @@ -155,8 +159,10 @@ bool TressFX_OpaqueDesc::RenderShadowMap(TressFX_Desc &desc, VkCommandBuffer commandBuffer, uint32_t uniformBufferIndex) { - tressFXRenderer.GenerateShadowMap(desc.pvkDevice, commandBuffer, - desc.hairParams.density, uniformBufferIndex); + tressFXRenderer.GenerateShadowMap(desc.pvkDevice, + commandBuffer, + desc.hairParams.density, uniformBufferIndex, + markerCallbacks); desc.pHairShadowMapSRV = tressFXRenderer.GetShadowMapSRV(); return true; } @@ -166,14 +172,18 @@ bool TressFX_OpaqueDesc::RenderHair(TressFX_Desc &desc, VkCommandBuffer commandB { if (desc.bShortCutOn) { - tressFXRenderer.RenderHairShortcut(desc.pvkDevice, commandBuffer, - desc.backBufferWidth, desc.backBufferHeight, - uniformBufferIndex); + tressFXRenderer.RenderHairShortcut(desc.pvkDevice, + commandBuffer, + desc.backBufferWidth, + desc.backBufferHeight, + uniformBufferIndex, markerCallbacks); } else { - tressFXRenderer.RenderHair(desc.pvkDevice, commandBuffer, desc.backBufferWidth, - desc.backBufferHeight, uniformBufferIndex); + tressFXRenderer.RenderHair(desc.pvkDevice, commandBuffer, + desc.backBufferWidth, + desc.backBufferHeight, uniformBufferIndex, + markerCallbacks); } return true; } @@ -184,11 +194,11 @@ bool TressFX_OpaqueDesc::End(TressFX_Desc &desc) return true; } -bool TressFX_OpaqueDesc::Resize(TressFX_Desc &desc, uint32_t texture_memory_index) +bool TressFX_OpaqueDesc::Resize(TressFX_Desc &desc, VkPhysicalDeviceMemoryProperties memProperties) { VkResult vr = tressFXRenderer.OnResizedSwapChain( desc.pvkDevice, desc.backBufferWidth, desc.backBufferHeight, desc.bShortCutOn, - texture_memory_index); + memProperties); return (vr == VK_SUCCESS); } diff --git a/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h index ce10d73..aaa44cc 100644 --- a/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h +++ b/amd_tressfx_vulkan/src/TressFXOpaqueVulkan.h @@ -34,19 +34,21 @@ namespace AMD struct TressFX_OpaqueDesc { public: - TressFX_OpaqueDesc() : initialized(false), refCount(0) {} - void Initialize(TressFX_Desc &desc, VkImageView depthTexture, - VkImageView colorTexture, VkCommandBuffer commandBuffer, - VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, - size_t &offsetInScratchBuffer, uint32_t cpu_memory_index, - uint32_t gpu_memory_index); + TressFX_OpaqueDesc() : refCount(0) {} + void Initialize(TressFX_Desc &desc, + VkImageView depthTexture, + VkImageView colorTexture, + VkCommandBuffer commandBuffer, + VkDeviceMemory scratchMemory, + VkBuffer scratchBuffer, + size_t &offsetInScratchBuffer, VkPhysicalDeviceMemoryProperties memProperties); void Release(VkDevice pvkDevice); bool LoadAppendAsset(TressFX_HairBlob *pRawHairBlob, const TressFX_GuideFollowParams &guideFollowParams, int groupId); bool CreateProcessedAsset(TressFX_Desc &desc, TressFX_HairBlob **ppHairBlob, TressFX_SceneMesh *sceneMesh, VkImageView hairTexture, - uint32_t texture_buffer_memory_index, + VkPhysicalDeviceMemoryProperties memProperties, VkCommandBuffer uploadCmdBuffer, VkBuffer scratchBuffer, VkDeviceMemory scratchMemor); @@ -60,14 +62,16 @@ struct TressFX_OpaqueDesc uint32_t uniformBufferIndex); bool GenerateTransforms(TressFX_Desc &desc, TressFX_SceneMesh &sceneMesh); bool ApplyRigidTransforms(TressFX_Desc &desc); - bool Resize(TressFX_Desc &desc, uint32_t texture_memory_index); + bool Resize(TressFX_Desc &desc, VkPhysicalDeviceMemoryProperties memProperties); TressFXSimulation tressFXSimulation; // Hair simulation class TressFXRenderer tressFXRenderer; // Hair rendering class + DebugMarkerPointer markerCallbacks; private: - bool initialized; // only initialize this structure once TressFXAssetLoader tressFXAssetLoader; // Hair asset loading class int refCount; // reference count - delete allocations when 0 + TressFX_OpaqueDesc(const TressFX_OpaqueDesc&) {} + TressFX_OpaqueDesc& operator=(const TressFX_OpaqueDesc&) {} }; } // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h b/amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h index 8824d61..7f680f6 100644 --- a/amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h +++ b/amd_tressfx_vulkan/src/TressFXPrecompiledShadersVulkan.h @@ -2,7 +2,7 @@ const std::vector hair_shadow_vertex = {119734787, 65536, 524289, -40, +41, 0, 131089, 1, @@ -625,10 +625,10 @@ const std::vector hair_shadow_vertex = {119734787, 1, 262187, 6, -32, +33, 1065353216, 262176, -38, +39, 3, 7, 327734, @@ -655,54 +655,58 @@ const std::vector hair_shadow_vertex = {119734787, 11, 29, 28, +262244, +22, +30, +26, 327775, 7, +31, 30, -26, 29, 524367, 14, +32, +31, 31, -30, -30, 0, 1, 2, 327761, 6, -33, -31, +34, +32, 0, 327761, 6, -34, -31, +35, +32, 1, 327761, 6, -35, -31, +36, +32, 2, 458832, 7, -36, -33, +37, 34, 35, -32, +36, +33, 327825, 7, -37, +38, 21, -36, +37, 327745, -38, 39, +40, 10, 12, 196670, -39, -37, +40, +38, 65789, 65592, }; @@ -773,7 +777,7 @@ const std::vector hair_shadow_fragment = {119734787, const std::vector render_hair_vertex = {119734787, 65536, 524289, -228, +232, 0, 131089, 1, @@ -794,11 +798,11 @@ const std::vector render_hair_vertex = {119734787, 1852399981, 0, 65, -164, -199, -206, -213, -227, +167, +202, +209, +216, +231, 196611, 2, 450, @@ -886,11 +890,11 @@ const std::vector render_hair_vertex = {119734787, 1684949368, 30821, 262149, -72, +73, 1735287124, 7630437, 524293, -73, +74, 1632132967, 1700164201, 2019914866, @@ -898,35 +902,35 @@ const std::vector render_hair_vertex = {119734787, 1937010277, 0, 262149, -79, +81, 1769234802, 111, 327685, -82, +84, 1936617283, 1953390964, 115, 393222, -82, +84, 0, 1466785639, 1684828783, 0, 393222, -82, +84, 1, 1450008423, 1350002025, 6975346, 458758, -82, +84, 2, 1231904615, 1767274094, 1917876069, 27247, 524294, -82, +84, 3, 1450008423, 1350002025, @@ -934,17 +938,17 @@ const std::vector render_hair_vertex = {119734787, 1952999273, 0, 327686, -82, +84, 4, 1165385575, 25977, 327686, -82, +84, 5, 1986420583, 7761734, 524294, -82, +84, 6, 1833000807, 1852139874, @@ -952,7 +956,7 @@ const std::vector render_hair_vertex = {119734787, 1866691688, 7499628, 524294, -82, +84, 7, 1867538279, 1282698857, @@ -960,34 +964,34 @@ const std::vector render_hair_vertex = {119734787, 1869377347, 114, 458758, -82, +84, 8, 1867538279, 1282698857, 1952999273, 7565136, 458758, -82, +84, 9, 1632460647, 1935753844, 1819231077, 29295, 393222, -82, +84, 10, 1632460647, 1633045364, 6649196, 458758, -82, +84, 11, 1766219623, 1098016098, 1634234476, 0, 524294, -82, +84, 12, 1632132967, 1750299241, @@ -995,80 +999,80 @@ const std::vector render_hair_vertex = {119734787, 1752198209, 97, 458758, -82, +84, 13, 1164074855, 1851879544, 2020167780, 7564389, 458758, -82, +84, 14, 1766219623, 1383228770, 1969841249, 115, 393222, -82, +84, 15, 1767333735, 2053722990, 101, 458758, -82, +84, 16, 1766219623, 1400005986, 1768120688, 26478, 393222, -82, +84, 17, 1415733095, 1416522088, 28777, 458758, -82, +84, 18, 1315331943, 1282564453, 1952999273, 0, 393222, -82, +84, 19, 1181114215, 1766617697, 7628903, 393222, -82, +84, 20, 1416191847, 1399350117, 77, 458758, -82, +84, 21, 1432510311, 1866687859, 1634887030, 25959, 458758, -82, +84, 22, 1399414631, 1851880052, 1886339940, 7562601, 458758, -82, +84, 23, 1298751335, 1917220961, 1701668705, 7566446, 524294, -82, +84, 24, 1818320743, 1415669872, @@ -1076,19 +1080,19 @@ const std::vector render_hair_vertex = {119734787, 1684828008, 0, 393222, -82, +84, 25, 1214668647, 1265789281, 12915, 393222, -82, +84, 26, 1214668647, 1165125985, 12920, 589830, -82, +84, 27, 1231904615, 1767274094, @@ -1097,10 +1101,10 @@ const std::vector render_hair_vertex = {119734787, 1869641573, 29810, 196613, -84, +86, 0, 524293, -92, +94, 1632132967, 1750364777, 1852531561, @@ -1108,66 +1112,66 @@ const std::vector render_hair_vertex = {119734787, 1717986671, 115, 262149, -103, +106, 1751607666, 116, 262149, -113, +116, 1634886000, 109, 327685, -115, +118, 1785688688, 1734963807, 29800, 262149, -126, +129, 1634886000, 109, 393221, -129, +132, 1634760805, 1766876270, 1936483704, 0, 327685, -140, +143, 1919501414, 1701080649, 120, 262149, -150, +153, 1886217588, 0, 393221, -162, +165, 1348430951, 1700164197, 2019914866, 0, 393222, -162, +165, 0, 1348430951, 1953067887, 7237481, 196613, -164, +167, 0, 262149, -199, +202, 1953523044, 104, 262149, -206, +209, 1735287156, 7630437, 262149, -213, +216, 829436016, 0, 327685, -227, +231, 1634890867, 1866687598, 7499628, @@ -1184,239 +1188,239 @@ const std::vector render_hair_vertex = {119734787, 11, 42, 262215, -73, +74, 34, 1, 262215, -73, +74, 33, 8, 262216, -82, +84, 0, 5, 327752, -82, +84, 0, 35, 0, 327752, -82, +84, 0, 7, 16, 262216, -82, +84, 1, 5, 327752, -82, +84, 1, 35, 64, 327752, -82, +84, 1, 7, 16, 262216, -82, +84, 2, 5, 327752, -82, +84, 2, 35, 128, 327752, -82, +84, 2, 7, 16, 262216, -82, +84, 3, 5, 327752, -82, +84, 3, 35, 192, 327752, -82, +84, 3, 7, 16, 327752, -82, +84, 4, 35, 256, 327752, -82, +84, 5, 35, 268, 327752, -82, +84, 6, 35, 272, 327752, -82, +84, 7, 35, 288, 327752, -82, +84, 8, 35, 304, 327752, -82, +84, 9, 35, 320, 327752, -82, +84, 10, 35, 336, 327752, -82, +84, 11, 35, 352, 327752, -82, +84, 12, 35, 356, 327752, -82, +84, 13, 35, 360, 327752, -82, +84, 14, 35, 364, 327752, -82, +84, 15, 35, 368, 327752, -82, +84, 16, 35, 384, 327752, -82, +84, 17, 35, 388, 327752, -82, +84, 18, 35, 392, 327752, -82, +84, 19, 35, 396, 327752, -82, +84, 20, 35, 400, 327752, -82, +84, 21, 35, 404, 327752, -82, +84, 22, 35, 408, 327752, -82, +84, 23, 35, 412, 327752, -82, +84, 24, 35, 416, 327752, -82, +84, 25, 35, 420, 327752, -82, +84, 26, 35, 424, 262216, -82, +84, 27, 5, 327752, -82, +84, 27, 35, 432, 327752, -82, +84, 27, 7, 16, 196679, -82, +84, 2, 262215, -84, +86, 34, 0, 262215, -84, +86, 33, 16, 262215, -92, +94, 34, 1, 262215, -92, +94, 33, 6, 327752, -162, +165, 0, 11, 0, 196679, -162, +165, 2, 262215, -199, +202, 30, 0, 262215, -206, +209, 30, 2, 262215, -213, +216, 30, 1, 262215, -227, +231, 30, 3, 131091, @@ -1513,35 +1517,35 @@ const std::vector render_hair_vertex = {119734787, 67, 2, 262167, -69, +70, 6, 4, 262203, 60, -73, +74, 0, 262168, -81, -69, +83, +70, 4, 1966110, -82, -81, -81, -81, -81, +84, +83, +83, +83, +83, 13, 6, -69, -69, -69, -69, -69, +70, +70, +70, +70, +70, 6, 6, 6, 6, -69, +70, 6, 6, 6, @@ -1553,125 +1557,125 @@ const std::vector render_hair_vertex = {119734787, 6, 6, 6, -81, -262176, 83, +262176, +85, 2, -82, -262203, -83, 84, +262203, +85, +86, 2, 262187, 63, -85, +87, 17, 262176, -86, +88, 2, 6, 262203, 60, -92, +94, 0, 262165, -97, +100, 32, 0, 262187, -97, -98, +100, +101, 0, 262187, 6, -101, +104, 1065353216, 262187, 63, -106, +109, 4, 262176, -107, +110, 2, 13, 262187, 63, -116, +119, 1, 262176, -117, +120, 2, -81, +83, 262187, 63, -131, +134, 13, 262187, 6, -138, +141, 1060487823, 262187, 6, -147, +150, 3212836864, 262187, 63, -157, +160, 14, 196638, -162, -69, +165, +70, 262176, -163, +166, 3, -162, +165, 262203, -163, -164, +166, +167, 3, 262187, 63, -165, +168, 0, 262176, -174, +177, 3, -69, +70, 262187, 63, -182, +185, 15, 262187, -97, -183, +100, +186, 1, 262187, -97, -192, +100, +195, 3, 262176, -193, +196, 3, 6, 262203, -193, -199, +196, +202, 3, 262187, -97, -200, +100, +203, 2, 262203, -174, -206, +177, +209, 3, 262203, -174, -213, +177, +216, 3, 262203, -174, -227, +177, +231, 3, 327734, 2, @@ -1686,51 +1690,51 @@ const std::vector render_hair_vertex = {119734787, 7, 262203, 14, -72, +73, 7, 262203, 19, -79, +81, 7, 262203, 19, -80, +82, 7, 262203, 14, -103, +106, 7, 262203, 14, -113, +116, 7, 262203, 8, -115, +118, 7, 262203, 8, -126, +129, 7, 262203, 19, -129, +132, 7, 262203, 19, -130, +133, 7, 262203, 19, -140, +143, 7, 262203, 19, -141, +144, 7, 262203, 14, -150, +153, 7, 262205, 59, @@ -1745,634 +1749,650 @@ const std::vector render_hair_vertex = {119734787, 68, 66, 67, -327775, +262244, +58, 69, -70, 62, +327775, +70, +71, +69, 68, 524367, 13, +72, +71, 71, -70, -70, 0, 1, 2, 196670, 57, -71, +72, 262205, 59, +75, 74, -73, 262205, 63, -75, +76, 65, 327815, 63, +77, 76, -75, 67, +262244, +58, +78, +75, 327775, -69, +70, +79, +78, 77, -74, -76, 524367, 13, -78, -77, -77, +80, +79, +79, 0, 1, 2, 196670, -72, -78, +73, +80, 327745, +88, +89, 86, 87, -84, -85, 262205, 6, -88, -87, +90, +89, 327866, 26, -89, -88, +91, +90, 35, 196855, -91, +93, 0, 262394, -89, -90, -100, +91, +92, +103, 131320, -90, +92, 262205, 59, -93, -92, +95, +94, 262205, 63, -94, +96, 65, 327815, 63, -95, -94, -67, -327775, -69, +97, 96, -93, +67, +262244, +58, +98, 95, +327775, +70, +99, +98, +97, 327761, 6, +102, 99, -96, 0, 196670, -80, -99, +82, +102, 131321, -91, +93, 131320, -100, +103, 196670, -80, -101, +82, +104, 131321, -91, +93, 131320, -91, +93, 262205, 6, -102, -80, +105, +82, 196670, -79, -102, +81, +105, 262205, 13, -104, -72, +107, +73, 262205, 13, -105, +108, 57, 327745, -107, -108, -84, -106, +110, +111, +86, +109, 262205, 13, -109, -108, +112, +111, 327811, 13, -110, -105, -109, +113, +108, +112, 393228, 13, -111, +114, 1, 69, -110, +113, 458764, 13, -112, +115, 1, 68, -104, -111, +107, +114, 196670, -113, -112, +116, +115, 327737, 13, -114, +117, 17, -113, +116, 196670, -103, -114, -327745, +106, 117, -118, -84, -116, -262205, -81, +327745, +120, +121, +86, 119, -118, +262205, +83, +122, +121, 262205, 13, -120, -103, +123, +106, 327761, 6, -121, -120, +124, +123, 0, 327761, 6, -122, -120, +125, +123, 1, 327761, 6, +126, 123, -120, 2, 458832, -69, +70, +127, 124, -121, -122, -123, +125, +126, 35, 327825, -69, -125, -119, -124, +70, +128, +122, +127, 458831, 7, -127, -125, -125, +130, +128, +128, 0, 1, 196670, -126, -127, +129, +130, 327737, 7, -128, +131, 11, -126, +129, 196670, -115, -128, +118, +131, 327745, +88, +135, 86, -132, -84, -131, +134, 262205, 6, -133, -132, +136, +135, 327864, 26, -134, -133, +137, +136, 35, 196855, -136, +139, 0, 262394, -134, -135, 137, +138, +140, 131320, -135, +138, 196670, -130, +133, 35, 131321, -136, +139, 131320, -137, +140, 196670, -130, -138, +133, +141, 131321, -136, +139, 131320, -136, +139, 262205, 6, -139, -130, +142, +133, 196670, -129, -139, +132, +142, 262205, 63, -142, +145, 65, 327819, 63, -143, -142, +146, +145, 67, 327850, 26, -144, -143, -116, -196855, +147, 146, +119, +196855, +149, 0, 262394, -144, -145, +147, 148, +151, 131320, -145, +148, 196670, -141, -147, +144, +150, 131321, -146, +149, 131320, -148, +151, 196670, -141, -101, +144, +104, 131321, -146, +149, 131320, -146, +149, 262205, 6, -149, -141, +152, +144, 196670, -140, -149, +143, +152, 262205, 13, -151, +154, 57, 262205, 6, -152, -140, +155, +143, 262205, 13, -153, -103, +156, +106, 327822, 13, -154, -153, -152, +157, +156, +155, 262205, 6, -155, -79, +158, +81, 327822, 13, -156, -154, -155, +159, +157, +158, 327745, +88, +161, 86, -158, -84, -157, +160, 262205, 6, -159, -158, +162, +161, 327822, 13, -160, -156, +163, 159, +162, 327809, 13, -161, -151, -160, +164, +154, +163, 196670, -150, -161, +153, +164, 327745, -117, -166, -84, -116, +120, +169, +86, +119, 262205, -81, -167, -166, +83, +170, +169, 262205, 13, -168, -150, +171, +153, 327761, 6, -169, -168, +172, +171, 0, 327761, 6, -170, -168, +173, +171, 1, 327761, 6, +174, 171, -168, 2, 458832, -69, +70, +175, 172, -169, -170, -171, -101, -327825, -69, 173, -167, -172, -327745, 174, +104, +327825, +70, +176, +170, 175, -164, -165, -196670, -175, -173, 327745, -174, -176, -164, -165, -262205, -69, 177, +178, +167, +168, +196670, +178, 176, +327745, +177, +179, +167, +168, +262205, +70, +180, +179, 262205, 6, -178, -140, +181, +143, 262205, 7, -179, -115, +182, +118, 262205, 6, -180, -129, +183, +132, 327822, 7, -181, -179, -180, -393281, -86, 184, -84, 182, 183, +393281, +88, +187, +86, +185, +186, 262205, 6, -185, -184, +188, +187, 327760, 7, -186, -185, -185, +189, +188, +188, 327816, 7, -187, -181, -186, +190, +184, +189, 327761, 6, -188, -187, +191, +190, 0, 327761, 6, -189, -187, +192, +190, 1, 458832, -69, -190, -188, -189, +70, +193, +191, +192, 35, 35, 327822, -69, -191, -190, -178, -393281, -193, +70, 194, -164, -165, -192, +193, +181, +393281, +196, +197, +167, +168, +195, 262205, 6, -195, -194, +198, +197, 327822, -69, -196, -191, -195, +70, +199, +194, +198, 327809, -69, -197, -177, -196, +70, +200, +180, +199, 327745, -174, -198, -164, -165, +177, +201, +167, +168, 196670, -198, -197, -393281, -193, 201, -164, -165, 200, -262205, -6, -202, -201, 393281, -193, +196, +204, +167, +168, 203, -164, -165, -192, 262205, 6, +205, 204, -203, +393281, +196, +206, +167, +168, +195, +262205, +6, +207, +206, 327816, 6, +208, 205, -202, -204, +207, 196670, -199, -205, +202, +208, 262205, 13, -207, -72, +210, +73, 262205, 6, -208, -79, +211, +81, 327761, 6, -209, -207, +212, +210, 0, 327761, 6, +213, 210, -207, 1, 327761, 6, -211, -207, +214, +210, 2, 458832, -69, +70, +215, 212, -209, -210, +213, +214, 211, -208, 196670, -206, -212, +209, +215, 262205, 13, -214, +217, 57, 458831, 7, -215, -214, -214, +218, +217, +217, 0, 1, 262205, 59, -216, +219, 61, 262205, 63, -217, +220, 65, 327815, 63, -218, -217, +221, +220, 67, 327808, 63, +222, +221, +119, +262244, +58, +223, 219, -218, -116, 327775, -69, -220, -216, -219, +70, +224, +223, +222, 458831, 7, -221, -220, -220, +225, +224, +224, 0, 1, 327761, 6, -222, -215, +226, +218, 0, 327761, 6, -223, -215, +227, +218, 1, 327761, 6, -224, -221, +228, +225, 0, 327761, 6, +229, 225, -221, 1, 458832, -69, +70, +230, 226, -222, -223, -224, -225, +227, +228, +229, 196670, -213, -226, +216, +230, 65789, 65592, 327734, @@ -2556,7 +2576,7 @@ const std::vector render_hair_vertex = {119734787, const std::vector render_hair_aa_vertex = {119734787, 65536, 524289, -252, +255, 0, 131089, 1, @@ -2577,11 +2597,11 @@ const std::vector render_hair_aa_vertex = {119734787, 1852399981, 0, 65, -201, -230, -234, -241, -251, +204, +233, +237, +244, +254, 196611, 2, 450, @@ -2669,11 +2689,11 @@ const std::vector render_hair_aa_vertex = {119734787, 1684949368, 30821, 262149, -72, +73, 1735287124, 7630437, 524293, -73, +74, 1632132967, 1700164201, 2019914866, @@ -2681,35 +2701,35 @@ const std::vector render_hair_aa_vertex = {119734787, 1937010277, 0, 262149, -79, +81, 1769234802, 111, 327685, -82, +84, 1936617283, 1953390964, 115, 393222, -82, +84, 0, 1466785639, 1684828783, 0, 393222, -82, +84, 1, 1450008423, 1350002025, 6975346, 458758, -82, +84, 2, 1231904615, 1767274094, 1917876069, 27247, 524294, -82, +84, 3, 1450008423, 1350002025, @@ -2717,17 +2737,17 @@ const std::vector render_hair_aa_vertex = {119734787, 1952999273, 0, 327686, -82, +84, 4, 1165385575, 25977, 327686, -82, +84, 5, 1986420583, 7761734, 524294, -82, +84, 6, 1833000807, 1852139874, @@ -2735,7 +2755,7 @@ const std::vector render_hair_aa_vertex = {119734787, 1866691688, 7499628, 524294, -82, +84, 7, 1867538279, 1282698857, @@ -2743,34 +2763,34 @@ const std::vector render_hair_aa_vertex = {119734787, 1869377347, 114, 458758, -82, +84, 8, 1867538279, 1282698857, 1952999273, 7565136, 458758, -82, +84, 9, 1632460647, 1935753844, 1819231077, 29295, 393222, -82, +84, 10, 1632460647, 1633045364, 6649196, 458758, -82, +84, 11, 1766219623, 1098016098, 1634234476, 0, 524294, -82, +84, 12, 1632132967, 1750299241, @@ -2778,80 +2798,80 @@ const std::vector render_hair_aa_vertex = {119734787, 1752198209, 97, 458758, -82, +84, 13, 1164074855, 1851879544, 2020167780, 7564389, 458758, -82, +84, 14, 1766219623, 1383228770, 1969841249, 115, 393222, -82, +84, 15, 1767333735, 2053722990, 101, 458758, -82, +84, 16, 1766219623, 1400005986, 1768120688, 26478, 393222, -82, +84, 17, 1415733095, 1416522088, 28777, 458758, -82, +84, 18, 1315331943, 1282564453, 1952999273, 0, 393222, -82, +84, 19, 1181114215, 1766617697, 7628903, 393222, -82, +84, 20, 1416191847, 1399350117, 77, 458758, -82, +84, 21, 1432510311, 1866687859, 1634887030, 25959, 458758, -82, +84, 22, 1399414631, 1851880052, 1886339940, 7562601, 458758, -82, +84, 23, 1298751335, 1917220961, 1701668705, 7566446, 524294, -82, +84, 24, 1818320743, 1415669872, @@ -2859,19 +2879,19 @@ const std::vector render_hair_aa_vertex = {119734787, 1684828008, 0, 393222, -82, +84, 25, 1214668647, 1265789281, 12915, 393222, -82, +84, 26, 1214668647, 1165125985, 12920, 589830, -82, +84, 27, 1231904615, 1767274094, @@ -2880,10 +2900,10 @@ const std::vector render_hair_aa_vertex = {119734787, 1869641573, 29810, 196613, -84, +86, 0, 524293, -92, +94, 1632132967, 1750364777, 1852531561, @@ -2891,76 +2911,76 @@ const std::vector render_hair_aa_vertex = {119734787, 1717986671, 115, 262149, -103, +106, 1751607666, 116, 262149, -113, +116, 1634886000, 109, 327685, -115, +118, 1785688688, 1734963807, 29800, 262149, -126, +129, 1634886000, 109, 458757, -130, +133, 1919508840, 1701274693, 1769172816, 1852795252, 12403, 458757, -145, +148, 1919508840, 1701274693, 1769172816, 1852795252, 12659, 393221, -178, +181, 1634760805, 1766876270, 1936483704, 0, 327685, -189, +192, 1919501414, 1701080649, 120, 393221, -199, +202, 1348430951, 1700164197, 2019914866, 0, 393222, -199, +202, 0, 1348430951, 1953067887, 7237481, 196613, -201, +204, 0, 262149, -230, +233, 1953523044, 104, 262149, -234, +237, 1735287156, 7630437, 262149, -241, +244, 829436016, 0, 327685, -251, +254, 1634890867, 1866687598, 7499628, @@ -2977,239 +2997,239 @@ const std::vector render_hair_aa_vertex = {119734787, 11, 42, 262215, -73, +74, 34, 1, 262215, -73, +74, 33, 8, 262216, -82, +84, 0, 5, 327752, -82, +84, 0, 35, 0, 327752, -82, +84, 0, 7, 16, 262216, -82, +84, 1, 5, 327752, -82, +84, 1, 35, 64, 327752, -82, +84, 1, 7, 16, 262216, -82, +84, 2, 5, 327752, -82, +84, 2, 35, 128, 327752, -82, +84, 2, 7, 16, 262216, -82, +84, 3, 5, 327752, -82, +84, 3, 35, 192, 327752, -82, +84, 3, 7, 16, 327752, -82, +84, 4, 35, 256, 327752, -82, +84, 5, 35, 268, 327752, -82, +84, 6, 35, 272, 327752, -82, +84, 7, 35, 288, 327752, -82, +84, 8, 35, 304, 327752, -82, +84, 9, 35, 320, 327752, -82, +84, 10, 35, 336, 327752, -82, +84, 11, 35, 352, 327752, -82, +84, 12, 35, 356, 327752, -82, +84, 13, 35, 360, 327752, -82, +84, 14, 35, 364, 327752, -82, +84, 15, 35, 368, 327752, -82, +84, 16, 35, 384, 327752, -82, +84, 17, 35, 388, 327752, -82, +84, 18, 35, 392, 327752, -82, +84, 19, 35, 396, 327752, -82, +84, 20, 35, 400, 327752, -82, +84, 21, 35, 404, 327752, -82, +84, 22, 35, 408, 327752, -82, +84, 23, 35, 412, 327752, -82, +84, 24, 35, 416, 327752, -82, +84, 25, 35, 420, 327752, -82, +84, 26, 35, 424, 262216, -82, +84, 27, 5, 327752, -82, +84, 27, 35, 432, 327752, -82, +84, 27, 7, 16, 196679, -82, +84, 2, 262215, -84, +86, 34, 0, 262215, -84, +86, 33, 16, 262215, -92, +94, 34, 1, 262215, -92, +94, 33, 6, 327752, -199, +202, 0, 11, 0, 196679, -199, +202, 2, 262215, -230, +233, 30, 0, 262215, -234, +237, 30, 2, 262215, -241, +244, 30, 1, 262215, -251, +254, 30, 3, 131091, @@ -3306,35 +3326,35 @@ const std::vector render_hair_aa_vertex = {119734787, 67, 2, 262167, -69, +70, 6, 4, 262203, 60, -73, +74, 0, 262168, -81, -69, +83, +70, 4, 1966110, -82, -81, -81, -81, -81, +84, +83, +83, +83, +83, 13, 6, -69, -69, -69, -69, -69, +70, +70, +70, +70, +70, 6, 6, 6, 6, -69, +70, 6, 6, 6, @@ -3346,129 +3366,129 @@ const std::vector render_hair_aa_vertex = {119734787, 6, 6, 6, -81, -262176, 83, +262176, +85, 2, -82, -262203, -83, 84, +262203, +85, +86, 2, 262187, 63, -85, +87, 17, 262176, -86, +88, 2, 6, 262203, 60, -92, +94, 0, 262165, -97, +100, 32, 0, 262187, -97, -98, +100, +101, 0, 262187, 6, -101, +104, 1065353216, 262187, 63, -106, +109, 4, 262176, -107, +110, 2, 13, 262187, 63, -116, +119, 1, 262176, -117, +120, 2, -81, +83, 262176, -129, +132, 7, -69, +70, 262187, 63, -136, +139, 14, 262187, -97, -168, +100, +171, 3, 262187, 63, -180, +183, 13, 262187, 6, -187, +190, 1060487823, 262187, 6, -196, +199, 3212836864, 196638, -199, -69, +202, +70, 262176, -200, +203, 3, -199, +202, 262203, -200, -201, +203, +204, 3, 262187, 63, -202, +205, 0, 262187, 63, -216, +219, 15, 262187, -97, -217, +100, +220, 1, 262176, -227, +230, 3, -69, +70, 262176, -229, +232, 3, 6, 262203, -229, -230, +232, +233, 3, 262187, -97, -231, +100, +234, 2, 262203, -227, -234, +230, +237, 3, 262203, -227, -241, +230, +244, 3, 262203, -227, -251, +230, +254, 3, 327734, 2, @@ -3483,59 +3503,59 @@ const std::vector render_hair_aa_vertex = {119734787, 7, 262203, 14, -72, +73, 7, 262203, 19, -79, +81, 7, 262203, 19, -80, +82, 7, 262203, 14, -103, +106, 7, 262203, 14, -113, +116, 7, 262203, 8, -115, +118, 7, 262203, 8, -126, +129, 7, 262203, -129, -130, +132, +133, 7, 262203, -129, -145, +132, +148, 7, 262203, 19, -178, +181, 7, 262203, 19, -179, +182, 7, 262203, 19, -189, +192, 7, 262203, 19, -190, +193, 7, 262203, -129, -203, +132, +206, 7, 262205, 59, @@ -3550,754 +3570,766 @@ const std::vector render_hair_aa_vertex = {119734787, 68, 66, 67, -327775, +262244, +58, 69, -70, 62, +327775, +70, +71, +69, 68, 524367, 13, +72, +71, 71, -70, -70, 0, 1, 2, 196670, 57, -71, +72, 262205, 59, +75, 74, -73, 262205, 63, -75, +76, 65, 327815, 63, +77, 76, -75, 67, +262244, +58, +78, +75, 327775, -69, +70, +79, +78, 77, -74, -76, 524367, 13, -78, -77, -77, +80, +79, +79, 0, 1, 2, 196670, -72, -78, +73, +80, 327745, +88, +89, 86, 87, -84, -85, 262205, 6, -88, -87, +90, +89, 327866, 26, -89, -88, +91, +90, 35, 196855, -91, +93, 0, 262394, -89, -90, -100, +91, +92, +103, 131320, -90, +92, 262205, 59, -93, -92, +95, +94, 262205, 63, -94, +96, 65, 327815, 63, -95, -94, -67, -327775, -69, +97, 96, -93, +67, +262244, +58, +98, 95, +327775, +70, +99, +98, +97, 327761, 6, +102, 99, -96, 0, 196670, -80, -99, +82, +102, 131321, -91, +93, 131320, -100, +103, 196670, -80, -101, +82, +104, 131321, -91, +93, 131320, -91, +93, 262205, 6, -102, -80, +105, +82, 196670, -79, -102, +81, +105, 262205, 13, -104, -72, +107, +73, 262205, 13, -105, +108, 57, 327745, -107, -108, -84, -106, +110, +111, +86, +109, 262205, 13, -109, -108, +112, +111, 327811, 13, -110, -105, -109, +113, +108, +112, 393228, 13, -111, +114, 1, 69, -110, +113, 458764, 13, -112, +115, 1, 68, -104, -111, +107, +114, 196670, -113, -112, +116, +115, 327737, 13, -114, +117, 17, -113, +116, 196670, -103, -114, -327745, +106, 117, -118, -84, -116, -262205, -81, +327745, +120, +121, +86, 119, -118, +262205, +83, +122, +121, 262205, 13, -120, -103, +123, +106, 327761, 6, -121, -120, +124, +123, 0, 327761, 6, -122, -120, +125, +123, 1, 327761, 6, +126, 123, -120, 2, 458832, -69, +70, +127, 124, -121, -122, -123, +125, +126, 35, 327825, -69, -125, -119, -124, +70, +128, +122, +127, 458831, 7, -127, -125, -125, +130, +128, +128, 0, 1, 196670, -126, -127, +129, +130, 327737, 7, -128, +131, 11, -126, +129, 196670, -115, -128, +118, +131, 262205, 13, -131, +134, 57, 262205, 13, -132, -103, +135, +106, 327822, 13, -133, -132, -101, +136, +135, +104, 262205, 6, -134, -79, +137, +81, 327822, 13, -135, -133, -134, +138, +136, +137, 327745, +88, +140, 86, -137, -84, -136, +139, 262205, 6, -138, -137, +141, +140, 327822, 13, -139, -135, +142, 138, +141, 327811, 13, -140, -131, -139, +143, +134, +142, 327761, 6, -141, -140, +144, +143, 0, 327761, 6, -142, -140, +145, +143, 1, 327761, 6, +146, 143, -140, 2, 458832, -69, +70, +147, 144, -141, -142, -143, -101, +145, +146, +104, 196670, -130, -144, +133, +147, 262205, 13, -146, +149, 57, 262205, 13, -147, -103, +150, +106, 327822, 13, -148, -147, -101, +151, +150, +104, 262205, 6, -149, -79, +152, +81, 327822, 13, -150, -148, -149, +153, +151, +152, 327745, +88, +154, 86, -151, -84, -136, +139, 262205, 6, -152, -151, +155, +154, 327822, 13, +156, 153, -150, -152, +155, 327809, 13, -154, -146, -153, +157, +149, +156, 327761, 6, -155, -154, +158, +157, 0, 327761, 6, -156, -154, +159, +157, 1, 327761, 6, +160, 157, -154, 2, 458832, -69, -158, -155, -156, -157, -101, -196670, -145, +70, +161, 158, -327745, -117, -159, -84, -116, -262205, -81, -160, 159, -262205, -69, -161, -130, -327825, -69, -162, 160, -161, +104, 196670, -130, -162, +148, +161, 327745, -117, -163, -84, -116, +120, +162, +86, +119, 262205, -81, -164, +83, 163, +162, 262205, -69, -165, -145, -327825, -69, -166, +70, 164, +133, +327825, +70, 165, +163, +164, 196670, -145, +133, +165, +327745, +120, 166, +86, +119, 262205, -69, +83, 167, -130, -327745, -19, +166, +262205, +70, +168, +148, +327825, +70, 169, -130, +167, 168, -262205, -6, -170, +196670, +148, 169, -458832, -69, -171, -170, -170, -170, +262205, +70, 170, -327816, -69, +133, +327745, +19, 172, -167, +133, 171, -196670, -130, -172, 262205, -69, +6, 173, -145, +172, +458832, +70, +174, +173, +173, +173, +173, +327816, +70, +175, +170, +174, +196670, +133, +175, +262205, +70, +176, +148, 327745, 19, -174, -145, -168, +177, +148, +171, 262205, 6, -175, -174, +178, +177, 458832, -69, -176, -175, -175, -175, -175, +70, +179, +178, +178, +178, +178, 327816, -69, -177, -173, +70, +180, 176, +179, 196670, -145, -177, +148, +180, 327745, +88, +184, 86, -181, -84, -180, +183, 262205, 6, -182, -181, +185, +184, 327864, 26, -183, -182, +186, +185, 35, 196855, -185, +188, 0, 262394, -183, -184, 186, +187, +189, 131320, -184, +187, 196670, -179, +182, 35, 131321, -185, +188, 131320, -186, +189, 196670, -179, -187, +182, +190, 131321, -185, +188, 131320, -185, +188, 262205, 6, -188, -179, +191, +182, 196670, -178, -188, +181, +191, 262205, 63, -191, +194, 65, 327819, 63, -192, -191, +195, +194, 67, 327850, 26, -193, -192, -116, -196855, +196, 195, +119, +196855, +198, 0, 262394, -193, -194, +196, 197, +200, 131320, -194, +197, 196670, -190, -196, +193, +199, 131321, -195, +198, 131320, -197, +200, 196670, -190, -101, +193, +104, 131321, -195, +198, 131320, -195, +198, 262205, 6, -198, -190, +201, +193, 196670, -189, -198, +192, +201, 262205, 6, -204, -189, +207, +192, 327860, 26, -205, -204, -196, -196855, +208, 207, +199, +196855, +210, 0, 262394, -205, -206, +208, 209, +212, 131320, -206, +209, 262205, -69, -208, -130, +70, +211, +133, 196670, -203, -208, +206, +211, 131321, -207, +210, 131320, -209, +212, 262205, -69, -210, -145, +70, +213, +148, 196670, -203, -210, +206, +213, 131321, -207, +210, 131320, -207, +210, 262205, -69, -211, -203, +70, +214, +206, 262205, 6, -212, -189, +215, +192, 262205, 7, -213, -115, +216, +118, 262205, 6, -214, -178, +217, +181, 327822, 7, -215, -213, -214, -393281, -86, 218, -84, 216, 217, +393281, +88, +221, +86, +219, +220, 262205, 6, -219, -218, +222, +221, 327760, 7, -220, -219, -219, +223, +222, +222, 327816, 7, -221, -215, -220, +224, +218, +223, 327761, 6, -222, -221, +225, +224, 0, 327761, 6, -223, -221, +226, +224, 1, 458832, -69, -224, -222, -223, +70, +227, +225, +226, 35, 35, 327822, -69, -225, -224, -212, -327809, -69, -226, -211, -225, -327745, +70, +228, 227, +215, +327809, +70, +229, +214, 228, -201, -202, +327745, +230, +231, +204, +205, 196670, -228, -226, -393281, +231, 229, +393281, 232, -201, -202, -231, +235, +204, +205, +234, 262205, 6, -233, -232, +236, +235, 196670, -230, 233, +236, 262205, 13, -235, -72, +238, +73, 262205, 6, -236, -79, +239, +81, 327761, 6, -237, -235, +240, +238, 0, 327761, 6, +241, 238, -235, 1, 327761, 6, -239, -235, +242, +238, 2, 458832, -69, +70, +243, 240, -237, -238, +241, +242, 239, -236, 196670, -234, -240, +237, +243, 262205, -69, -242, -130, +70, +245, +133, 458831, 7, -243, -242, -242, +246, +245, +245, 0, 1, 262205, -69, -244, -145, +70, +247, +148, 458831, 7, -245, -244, -244, +248, +247, +247, 0, 1, 327761, 6, +249, 246, -243, 0, 327761, 6, -247, -243, +250, +246, 1, 327761, 6, +251, 248, -245, 0, 327761, 6, -249, -245, +252, +248, 1, 458832, -69, -250, -246, -247, -248, +70, +253, 249, -196670, -241, 250, +251, +252, +196670, +244, +253, 65789, 65592, 327734, @@ -4481,7 +4513,7 @@ const std::vector render_hair_aa_vertex = {119734787, const std::vector render_hair_strand_copies_vertex = {119734787, 65536, 524289, -285, +289, 0, 131089, 1, @@ -4503,11 +4535,11 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 0, 61, 66, -218, -253, -260, -267, -284, +221, +256, +263, +270, +288, 196611, 2, 450, @@ -4640,10 +4672,10 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1937010277, 0, 196613, -127, +128, 118, 524293, -129, +130, 1632132967, 1700164201, 2019914866, @@ -4651,35 +4683,35 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1852795252, 115, 262149, -136, +138, 1769234802, 111, 327685, -139, +141, 1936617283, 1953390964, 115, 393222, -139, +141, 0, 1466785639, 1684828783, 0, 393222, -139, +141, 1, 1450008423, 1350002025, 6975346, 458758, -139, +141, 2, 1231904615, 1767274094, 1917876069, 27247, 524294, -139, +141, 3, 1450008423, 1350002025, @@ -4687,17 +4719,17 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1952999273, 0, 327686, -139, +141, 4, 1165385575, 25977, 327686, -139, +141, 5, 1986420583, 7761734, 524294, -139, +141, 6, 1833000807, 1852139874, @@ -4705,7 +4737,7 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1866691688, 7499628, 524294, -139, +141, 7, 1867538279, 1282698857, @@ -4713,34 +4745,34 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1869377347, 114, 458758, -139, +141, 8, 1867538279, 1282698857, 1952999273, 7565136, 458758, -139, +141, 9, 1632460647, 1935753844, 1819231077, 29295, 393222, -139, +141, 10, 1632460647, 1633045364, 6649196, 458758, -139, +141, 11, 1766219623, 1098016098, 1634234476, 0, 524294, -139, +141, 12, 1632132967, 1750299241, @@ -4748,80 +4780,80 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1752198209, 97, 458758, -139, +141, 13, 1164074855, 1851879544, 2020167780, 7564389, 458758, -139, +141, 14, 1766219623, 1383228770, 1969841249, 115, 393222, -139, +141, 15, 1767333735, 2053722990, 101, 458758, -139, +141, 16, 1766219623, 1400005986, 1768120688, 26478, 393222, -139, +141, 17, 1415733095, 1416522088, 28777, 458758, -139, +141, 18, 1315331943, 1282564453, 1952999273, 0, 393222, -139, +141, 19, 1181114215, 1766617697, 7628903, 393222, -139, +141, 20, 1416191847, 1399350117, 77, 458758, -139, +141, 21, 1432510311, 1866687859, 1634887030, 25959, 458758, -139, +141, 22, 1399414631, 1851880052, 1886339940, 7562601, 458758, -139, +141, 23, 1298751335, 1917220961, 1701668705, 7566446, 524294, -139, +141, 24, 1818320743, 1415669872, @@ -4829,19 +4861,19 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1684828008, 0, 393222, -139, +141, 25, 1214668647, 1265789281, 12915, 393222, -139, +141, 26, 1214668647, 1165125985, 12920, 589830, -139, +141, 27, 1231904615, 1767274094, @@ -4850,10 +4882,10 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1869641573, 29810, 196613, -141, +143, 0, 524293, -149, +151, 1632132967, 1750364777, 1852531561, @@ -4861,66 +4893,66 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 1717986671, 115, 262149, -158, +161, 1751607666, 116, 262149, -168, +171, 1634886000, 109, 327685, -170, +173, 1785688688, 1734963807, 29800, 262149, -180, +183, 1634886000, 109, 393221, -183, +186, 1634760805, 1766876270, 1936483704, 0, 327685, -194, +197, 1919501414, 1701080649, 120, 262149, -204, +207, 1886217588, 0, 393221, -216, +219, 1348430951, 1700164197, 2019914866, 0, 393222, -216, +219, 0, 1348430951, 1953067887, 7237481, 196613, -218, +221, 0, 262149, -253, +256, 1953523044, 104, 262149, -260, +263, 1735287156, 7630437, 262149, -267, +270, 829436016, 0, 327685, -284, +288, 1634890867, 1866687598, 7499628, @@ -4957,239 +4989,239 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 33, 8, 262215, -129, +130, 34, 1, 262215, -129, +130, 33, 7, 262216, -139, +141, 0, 5, 327752, -139, +141, 0, 35, 0, 327752, -139, +141, 0, 7, 16, 262216, -139, +141, 1, 5, 327752, -139, +141, 1, 35, 64, 327752, -139, +141, 1, 7, 16, 262216, -139, +141, 2, 5, 327752, -139, +141, 2, 35, 128, 327752, -139, +141, 2, 7, 16, 262216, -139, +141, 3, 5, 327752, -139, +141, 3, 35, 192, 327752, -139, +141, 3, 7, 16, 327752, -139, +141, 4, 35, 256, 327752, -139, +141, 5, 35, 268, 327752, -139, +141, 6, 35, 272, 327752, -139, +141, 7, 35, 288, 327752, -139, +141, 8, 35, 304, 327752, -139, +141, 9, 35, 320, 327752, -139, +141, 10, 35, 336, 327752, -139, +141, 11, 35, 352, 327752, -139, +141, 12, 35, 356, 327752, -139, +141, 13, 35, 360, 327752, -139, +141, 14, 35, 364, 327752, -139, +141, 15, 35, 368, 327752, -139, +141, 16, 35, 384, 327752, -139, +141, 17, 35, 388, 327752, -139, +141, 18, 35, 392, 327752, -139, +141, 19, 35, 396, 327752, -139, +141, 20, 35, 400, 327752, -139, +141, 21, 35, 404, 327752, -139, +141, 22, 35, 408, 327752, -139, +141, 23, 35, 412, 327752, -139, +141, 24, 35, 416, 327752, -139, +141, 25, 35, 420, 327752, -139, +141, 26, 35, 424, 262216, -139, +141, 27, 5, 327752, -139, +141, 27, 35, 432, 327752, -139, +141, 27, 7, 16, 196679, -139, +141, 2, 262215, -141, +143, 34, 0, 262215, -141, +143, 33, 16, 262215, -149, +151, 34, 1, 262215, -149, +151, 33, 6, 327752, -216, +219, 0, 11, 0, 196679, -216, +219, 2, 262215, -253, +256, 30, 0, 262215, -260, +263, 30, 2, 262215, -267, +270, 30, 1, 262215, -284, +288, 30, 3, 131091, @@ -5365,18 +5397,18 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 0, 262203, 120, -129, +130, 0, 262168, -138, +140, 107, 4, 1966110, -139, -138, -138, -138, -138, +141, +140, +140, +140, +140, 13, 6, 107, @@ -5400,113 +5432,113 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 6, 6, 6, -138, -262176, 140, +262176, +142, 2, -139, -262203, -140, 141, +262203, +142, +143, 2, 262187, 57, -142, +144, 17, 262176, -143, +145, 2, 6, 262203, 120, -149, +151, 0, 262187, 68, -154, +157, 0, 262187, 57, -161, +164, 4, 262176, -162, +165, 2, 13, 262176, -171, +174, 2, -138, +140, 262187, 57, -185, +188, 13, 262187, 6, -192, +195, 1060487823, 262187, 6, -201, +204, 3212836864, 262187, 57, -211, +214, 14, 196638, -216, +219, 107, 262176, -217, +220, 3, -216, +219, 262203, -217, -218, +220, +221, 3, 262187, 57, -219, +222, 0, 262176, -228, +231, 3, 107, 262187, 57, -236, +239, 15, 262187, 68, -237, +240, 1, 262187, 68, -246, +249, 3, 262176, -247, +250, 3, 6, 262203, -247, -253, +250, +256, 3, 262187, 68, -254, +257, 2, 262203, -228, -260, +231, +263, 3, 262203, -228, -267, +231, +270, 3, 262203, -228, -284, +231, +288, 3, 327734, 2, @@ -5541,51 +5573,51 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 7, 262203, 14, -127, +128, 7, 262203, 19, -136, +138, 7, 262203, 19, -137, +139, 7, 262203, 14, -158, +161, 7, 262203, 14, -168, +171, 7, 262203, 8, -170, +173, 7, 262203, 8, -180, +183, 7, 262203, 19, -183, +186, 7, 262203, 19, -184, +187, 7, 262203, 19, -194, +197, 7, 262203, 19, -195, +198, 7, 262203, 14, -204, +207, 7, 262205, 57, @@ -5769,659 +5801,675 @@ const std::vector render_hair_strand_copies_vertex = {119734787, 124, 123, 63, +262244, +118, +125, +122, 327775, 107, +126, 125, -122, 124, 524367, 13, +127, +126, 126, -125, -125, 0, 1, 2, 196670, 117, -126, +127, 262205, 13, -128, +129, 93, 262205, 119, +131, 130, -129, 262205, 57, -131, +132, 61, 327815, 57, +133, 132, -131, 63, +262244, +118, +134, +131, 327775, 107, +135, +134, 133, -130, -132, 524367, 13, -134, -133, -133, +136, +135, +135, 0, 1, 2, 327809, 13, -135, -128, -134, +137, +129, +136, 196670, -127, -135, +128, +137, 327745, +145, +146, 143, 144, -141, -142, 262205, 6, -145, -144, +147, +146, 327866, 26, -146, -145, +148, +147, 35, 196855, -148, +150, 0, 262394, -146, -147, -156, +148, +149, +159, 131320, -147, +149, 262205, 119, -150, -149, +152, +151, 262205, 57, -151, +153, 61, 327815, 57, -152, -151, +154, +153, 63, +262244, +118, +155, +152, 327775, 107, -153, -150, -152, +156, +155, +154, 327761, 6, -155, -153, +158, +156, 0, 196670, -137, -155, +139, +158, 131321, -148, +150, 131320, -156, +159, 196670, -137, +139, 114, 131321, -148, +150, 131320, -148, +150, 262205, 6, -157, -137, +160, +139, 196670, -136, -157, +138, +160, 262205, 13, -159, +162, 117, 262205, 13, -160, -127, -327745, -162, 163, -141, -161, +128, +327745, +165, +166, +143, +164, 262205, 13, -164, -163, +167, +166, 327811, 13, -165, -160, -164, +168, +163, +167, 393228, 13, -166, +169, 1, 69, -165, +168, 458764, 13, -167, +170, 1, 68, -159, -166, +162, +169, 196670, -168, -167, +171, +170, 327737, 13, -169, +172, 17, -168, -196670, -158, -169, -327745, 171, +196670, +161, 172, -141, +327745, +174, +175, +143, 74, 262205, -138, -173, -172, +140, +176, +175, 262205, 13, -174, -158, +177, +161, 327761, 6, -175, -174, +178, +177, 0, 327761, 6, -176, -174, +179, +177, 1, 327761, 6, +180, 177, -174, 2, 458832, 107, +181, 178, -175, -176, -177, +179, +180, 35, 327825, 107, -179, -173, -178, +182, +176, +181, 458831, 7, -181, -179, -179, +184, +182, +182, 0, 1, 196670, -180, -181, +183, +184, 327737, 7, -182, +185, 11, -180, +183, 196670, -170, -182, +173, +185, 327745, +145, +189, 143, -186, -141, -185, +188, 262205, 6, -187, -186, +190, +189, 327864, 26, -188, -187, +191, +190, 35, 196855, -190, +193, 0, 262394, -188, -189, 191, +192, +194, 131320, -189, +192, 196670, -184, +187, 35, 131321, -190, +193, 131320, -191, +194, 196670, -184, -192, +187, +195, 131321, -190, +193, 131320, -190, +193, 262205, 6, -193, -184, +196, +187, 196670, -183, -193, +186, +196, 262205, 57, -196, +199, 61, 327819, 57, -197, -196, +200, +199, 63, 327850, 26, -198, -197, +201, +200, 74, 196855, -200, +203, 0, 262394, -198, -199, +201, 202, +205, 131320, -199, +202, 196670, -195, -201, +198, +204, 131321, -200, +203, 131320, -202, +205, 196670, -195, +198, 114, 131321, -200, +203, 131320, -200, +203, 262205, 6, -203, -195, +206, +198, 196670, -194, -203, +197, +206, 262205, 13, -205, -127, -262205, +208, +128, +262205, 6, -206, -194, +209, +197, 262205, 13, -207, -158, +210, +161, 327822, 13, -208, -207, -206, +211, +210, +209, 262205, 6, -209, -136, +212, +138, 327822, 13, -210, -208, -209, +213, +211, +212, 327745, +145, +215, 143, -212, -141, -211, +214, 262205, 6, -213, -212, +216, +215, 327822, 13, -214, -210, +217, 213, +216, 327809, 13, -215, -205, -214, +218, +208, +217, 196670, -204, -215, +207, +218, 327745, -171, -220, -141, +174, +223, +143, 74, 262205, -138, -221, -220, +140, +224, +223, 262205, 13, -222, -204, +225, +207, 327761, 6, -223, -222, +226, +225, 0, 327761, 6, -224, -222, +227, +225, 1, 327761, 6, +228, 225, -222, 2, 458832, 107, +229, 226, -223, -224, -225, +227, +228, 114, 327825, 107, -227, -221, -226, -327745, -228, -229, -218, -219, -196670, +230, +224, 229, -227, 327745, -228, +231, +232, +221, +222, +196670, +232, 230, -218, -219, +327745, +231, +233, +221, +222, 262205, 107, -231, -230, +234, +233, 262205, 6, -232, -194, +235, +197, 262205, 7, -233, -170, +236, +173, 262205, 6, -234, -183, +237, +186, 327822, 7, -235, -233, -234, -393281, -143, 238, -141, 236, 237, +393281, +145, +241, +143, +239, +240, 262205, 6, -239, -238, +242, +241, 327760, 7, -240, -239, -239, +243, +242, +242, 327816, 7, -241, -235, -240, +244, +238, +243, 327761, 6, -242, -241, +245, +244, 0, 327761, 6, -243, -241, +246, +244, 1, 458832, 107, -244, -242, -243, +247, +245, +246, 35, 35, 327822, 107, -245, -244, -232, -393281, -247, 248, -218, -219, -246, +247, +235, +393281, +250, +251, +221, +222, +249, 262205, 6, -249, -248, +252, +251, 327822, 107, -250, -245, -249, +253, +248, +252, 327809, 107, -251, -231, -250, +254, +234, +253, 327745, -228, -252, -218, -219, +231, +255, +221, +222, 196670, -252, -251, -393281, -247, 255, -218, -219, 254, -262205, -6, -256, -255, 393281, -247, +250, +258, +221, +222, 257, -218, -219, -246, 262205, 6, +259, 258, -257, +393281, +250, +260, +221, +222, +249, +262205, +6, +261, +260, 327816, 6, +262, 259, -256, -258, +261, 196670, -253, -259, +256, +262, 262205, 13, -261, +264, 117, 262205, 6, -262, -136, +265, +138, 327761, 6, -263, -261, +266, +264, 0, 327761, 6, +267, 264, -261, 1, 327761, 6, -265, -261, +268, +264, 2, 458832, 107, +269, 266, -263, -264, +267, +268, 265, -262, 196670, -260, -266, +263, +269, 262205, 13, -268, -127, +271, +128, 458831, 7, -269, -268, -268, +272, +271, +271, 0, 1, 262205, 13, -270, +273, 93, 458831, 7, -271, -270, -270, +274, +273, +273, 0, 1, 262205, 119, -272, -129, +275, +130, 262205, 57, -273, +276, 61, 327815, 57, -274, -273, +277, +276, 63, 327808, 57, -275, -274, +278, +277, 74, +262244, +118, +279, +275, 327775, 107, -276, -272, -275, +280, +279, +278, 458831, 7, -277, -276, -276, +281, +280, +280, 0, 1, 327809, 7, -278, -271, -277, +282, +274, +281, 327761, 6, -279, -269, +283, +272, 0, 327761, 6, -280, -269, +284, +272, 1, 327761, 6, -281, -278, +285, +282, 0, 327761, 6, +286, 282, -278, 1, 458832, 107, +287, 283, -279, -280, -281, -282, +284, +285, +286, 196670, -267, -283, +270, +287, 65789, 65592, 327734, @@ -6605,7 +6653,7 @@ const std::vector render_hair_strand_copies_vertex = {119734787, const std::vector render_hair_aa_strand_copies_vertex = {119734787, 65536, 524289, -321, +324, 0, 131089, 1, @@ -6627,11 +6675,11 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 0, 61, 66, -244, -286, -293, -300, -320, +247, +289, +296, +303, +323, 196611, 2, 450, @@ -6764,10 +6812,10 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1937010277, 0, 196613, -127, +128, 118, 524293, -129, +130, 1632132967, 1700164201, 2019914866, @@ -6775,35 +6823,35 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1852795252, 115, 262149, -136, +138, 1769234802, 111, 327685, -139, +141, 1936617283, 1953390964, 115, 393222, -139, +141, 0, 1466785639, 1684828783, 0, 393222, -139, +141, 1, 1450008423, 1350002025, 6975346, 458758, -139, +141, 2, 1231904615, 1767274094, 1917876069, 27247, 524294, -139, +141, 3, 1450008423, 1350002025, @@ -6811,17 +6859,17 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1952999273, 0, 327686, -139, +141, 4, 1165385575, 25977, 327686, -139, +141, 5, 1986420583, 7761734, 524294, -139, +141, 6, 1833000807, 1852139874, @@ -6829,7 +6877,7 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1866691688, 7499628, 524294, -139, +141, 7, 1867538279, 1282698857, @@ -6837,34 +6885,34 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1869377347, 114, 458758, -139, +141, 8, 1867538279, 1282698857, 1952999273, 7565136, 458758, -139, +141, 9, 1632460647, 1935753844, 1819231077, 29295, 393222, -139, +141, 10, 1632460647, 1633045364, 6649196, 458758, -139, +141, 11, 1766219623, 1098016098, 1634234476, 0, 524294, -139, +141, 12, 1632132967, 1750299241, @@ -6872,80 +6920,80 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1752198209, 97, 458758, -139, +141, 13, 1164074855, 1851879544, 2020167780, 7564389, 458758, -139, +141, 14, 1766219623, 1383228770, 1969841249, 115, 393222, -139, +141, 15, 1767333735, 2053722990, 101, 458758, -139, +141, 16, 1766219623, 1400005986, 1768120688, 26478, 393222, -139, +141, 17, 1415733095, 1416522088, 28777, 458758, -139, +141, 18, 1315331943, 1282564453, 1952999273, 0, 393222, -139, +141, 19, 1181114215, 1766617697, 7628903, 393222, -139, +141, 20, 1416191847, 1399350117, 77, 458758, -139, +141, 21, 1432510311, 1866687859, 1634887030, 25959, 458758, -139, +141, 22, 1399414631, 1851880052, 1886339940, 7562601, 458758, -139, +141, 23, 1298751335, 1917220961, 1701668705, 7566446, 524294, -139, +141, 24, 1818320743, 1415669872, @@ -6953,19 +7001,19 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1684828008, 0, 393222, -139, +141, 25, 1214668647, 1265789281, 12915, 393222, -139, +141, 26, 1214668647, 1165125985, 12920, 589830, -139, +141, 27, 1231904615, 1767274094, @@ -6974,10 +7022,10 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1869641573, 29810, 196613, -141, +143, 0, 524293, -149, +151, 1632132967, 1750364777, 1852531561, @@ -6985,76 +7033,76 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 1717986671, 115, 262149, -158, +161, 1751607666, 116, 262149, -168, +171, 1634886000, 109, 327685, -170, +173, 1785688688, 1734963807, 29800, 262149, -180, +183, 1634886000, 109, 393221, -183, +186, 1634760805, 1766876270, 1936483704, 0, 458757, -195, +198, 1919508840, 1701274693, 1769172816, 1852795252, 12403, 458757, -210, +213, 1919508840, 1701274693, 1769172816, 1852795252, 12659, 327685, -232, +235, 1919501414, 1701080649, 120, 393221, -242, +245, 1348430951, 1700164197, 2019914866, 0, 393222, -242, +245, 0, 1348430951, 1953067887, 7237481, 196613, -244, +247, 0, 262149, -286, +289, 1953523044, 104, 262149, -293, +296, 1735287156, 7630437, 262149, -300, +303, 829436016, 0, 327685, -320, +323, 1634890867, 1866687598, 7499628, @@ -7091,239 +7139,239 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 33, 8, 262215, -129, +130, 34, 1, 262215, -129, +130, 33, 7, 262216, -139, +141, 0, 5, 327752, -139, +141, 0, 35, 0, 327752, -139, +141, 0, 7, 16, 262216, -139, +141, 1, 5, 327752, -139, +141, 1, 35, 64, 327752, -139, +141, 1, 7, 16, 262216, -139, +141, 2, 5, 327752, -139, +141, 2, 35, 128, 327752, -139, +141, 2, 7, 16, 262216, -139, +141, 3, 5, 327752, -139, +141, 3, 35, 192, 327752, -139, +141, 3, 7, 16, 327752, -139, +141, 4, 35, 256, 327752, -139, +141, 5, 35, 268, 327752, -139, +141, 6, 35, 272, 327752, -139, +141, 7, 35, 288, 327752, -139, +141, 8, 35, 304, 327752, -139, +141, 9, 35, 320, 327752, -139, +141, 10, 35, 336, 327752, -139, +141, 11, 35, 352, 327752, -139, +141, 12, 35, 356, 327752, -139, +141, 13, 35, 360, 327752, -139, +141, 14, 35, 364, 327752, -139, +141, 15, 35, 368, 327752, -139, +141, 16, 35, 384, 327752, -139, +141, 17, 35, 388, 327752, -139, +141, 18, 35, 392, 327752, -139, +141, 19, 35, 396, 327752, -139, +141, 20, 35, 400, 327752, -139, +141, 21, 35, 404, 327752, -139, +141, 22, 35, 408, 327752, -139, +141, 23, 35, 412, 327752, -139, +141, 24, 35, 416, 327752, -139, +141, 25, 35, 420, 327752, -139, +141, 26, 35, 424, 262216, -139, +141, 27, 5, 327752, -139, +141, 27, 35, 432, 327752, -139, +141, 27, 7, 16, 196679, -139, +141, 2, 262215, -141, +143, 34, 0, 262215, -141, +143, 33, 16, 262215, -149, +151, 34, 1, 262215, -149, +151, 33, 6, 327752, -242, +245, 0, 11, 0, 196679, -242, +245, 2, 262215, -286, +289, 30, 0, 262215, -293, +296, 30, 2, 262215, -300, +303, 30, 1, 262215, -320, +323, 30, 3, 131091, @@ -7499,18 +7547,18 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 0, 262203, 120, -129, +130, 0, 262168, -138, +140, 107, 4, 1966110, -139, -138, -138, -138, -138, +141, +140, +140, +140, +140, 13, 6, 107, @@ -7534,117 +7582,117 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 6, 6, 6, -138, -262176, 140, +262176, +142, 2, -139, -262203, -140, 141, +262203, +142, +143, 2, 262187, 57, -142, +144, 17, 262176, -143, +145, 2, 6, 262203, 120, -149, +151, 0, 262187, 68, -154, +157, 0, 262187, 57, -161, +164, 4, 262176, -162, +165, 2, 13, 262176, -171, +174, 2, -138, +140, 262187, 57, -185, +188, 13, 262187, 6, -192, +195, 1060487823, 262176, -194, +197, 7, 107, 262187, 57, -201, +204, 14, 262187, 6, -239, +242, 3212836864, 196638, -242, +245, 107, 262176, -243, +246, 3, -242, +245, 262203, -243, -244, +246, +247, 3, 262187, 57, -245, +248, 0, 262187, 57, -259, +262, 15, 262187, 68, -260, +263, 1, 262187, 68, -274, +277, 3, 262176, -283, +286, 3, 107, 262176, -285, +288, 3, 6, 262203, -285, -286, +288, +289, 3, 262187, 68, -287, +290, 2, 262203, -283, -293, +286, +296, 3, 262203, -283, -300, +286, +303, 3, 262203, -283, -320, +286, +323, 3, 327734, 2, @@ -7679,63 +7727,63 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 7, 262203, 14, -127, +128, 7, 262203, 19, -136, +138, 7, 262203, 19, -137, +139, 7, 262203, 14, -158, +161, 7, 262203, 14, -168, +171, 7, 262203, 8, -170, +173, 7, 262203, 8, -180, +183, 7, 262203, 19, -183, +186, 7, 262203, 19, -184, +187, 7, 262203, -194, -195, +197, +198, 7, 262203, -194, -210, +197, +213, 7, 262203, 19, -232, +235, 7, 262203, 19, -233, +236, 7, 262203, -194, -246, +197, +249, 7, 262203, 19, -269, +272, 7, 262205, 57, @@ -7919,833 +7967,845 @@ const std::vector render_hair_aa_strand_copies_vertex = {119734787, 124, 123, 63, +262244, +118, +125, +122, 327775, 107, +126, 125, -122, 124, 524367, 13, +127, +126, 126, -125, -125, 0, 1, 2, 196670, 117, -126, +127, 262205, 13, -128, +129, 93, 262205, 119, +131, 130, -129, 262205, 57, -131, +132, 61, 327815, 57, +133, 132, -131, 63, +262244, +118, +134, +131, 327775, 107, +135, +134, 133, -130, -132, 524367, 13, -134, -133, -133, +136, +135, +135, 0, 1, 2, 327809, 13, -135, -128, -134, +137, +129, +136, 196670, -127, -135, +128, +137, 327745, +145, +146, 143, 144, -141, -142, 262205, 6, -145, -144, +147, +146, 327866, 26, -146, -145, +148, +147, 35, 196855, -148, +150, 0, 262394, -146, -147, -156, +148, +149, +159, 131320, -147, +149, 262205, 119, -150, -149, +152, +151, 262205, 57, -151, +153, 61, 327815, 57, -152, -151, +154, +153, 63, +262244, +118, +155, +152, 327775, 107, -153, -150, -152, +156, +155, +154, 327761, 6, -155, -153, +158, +156, 0, 196670, -137, -155, +139, +158, 131321, -148, +150, 131320, -156, +159, 196670, -137, +139, 114, 131321, -148, +150, 131320, -148, +150, 262205, 6, -157, -137, +160, +139, 196670, -136, -157, +138, +160, 262205, 13, -159, +162, 117, 262205, 13, -160, -127, -327745, -162, 163, -141, -161, +128, +327745, +165, +166, +143, +164, 262205, 13, -164, -163, +167, +166, 327811, 13, -165, -160, -164, +168, +163, +167, 393228, 13, -166, +169, 1, 69, -165, +168, 458764, 13, -167, +170, 1, 68, -159, -166, +162, +169, 196670, -168, -167, +171, +170, 327737, 13, -169, +172, 17, -168, -196670, -158, -169, -327745, 171, +196670, +161, 172, -141, +327745, +174, +175, +143, 74, 262205, -138, -173, -172, +140, +176, +175, 262205, 13, -174, -158, +177, +161, 327761, 6, -175, -174, +178, +177, 0, 327761, 6, -176, -174, +179, +177, 1, 327761, 6, +180, 177, -174, 2, 458832, 107, +181, 178, -175, -176, -177, +179, +180, 35, 327825, 107, -179, -173, -178, +182, +176, +181, 458831, 7, -181, -179, -179, +184, +182, +182, 0, 1, 196670, -180, -181, +183, +184, 327737, 7, -182, +185, 11, -180, +183, 196670, -170, -182, +173, +185, 327745, +145, +189, 143, -186, -141, -185, +188, 262205, 6, -187, -186, +190, +189, 327864, 26, -188, -187, +191, +190, 35, 196855, -190, +193, 0, 262394, -188, -189, 191, +192, +194, 131320, -189, +192, 196670, -184, +187, 35, 131321, -190, +193, 131320, -191, +194, 196670, -184, -192, +187, +195, 131321, -190, +193, 131320, -190, +193, 262205, 6, -193, -184, +196, +187, 196670, -183, -193, +186, +196, 262205, 13, -196, -127, +199, +128, 262205, 13, -197, -158, +200, +161, 327822, 13, -198, -197, +201, +200, 114, 262205, 6, -199, -136, +202, +138, 327822, 13, -200, -198, -199, +203, +201, +202, 327745, +145, +205, 143, -202, -141, -201, +204, 262205, 6, -203, -202, +206, +205, 327822, 13, -204, -200, +207, 203, +206, 327811, 13, -205, -196, -204, +208, +199, +207, 327761, 6, -206, -205, +209, +208, 0, 327761, 6, -207, -205, +210, +208, 1, 327761, 6, +211, 208, -205, 2, 458832, 107, +212, 209, -206, -207, -208, +210, +211, 114, 196670, -195, -209, +198, +212, 262205, 13, -211, -127, +214, +128, 262205, 13, -212, -158, +215, +161, 327822, 13, -213, -212, +216, +215, 114, 262205, 6, -214, -136, +217, +138, 327822, 13, -215, -213, -214, +218, +216, +217, 327745, +145, +219, 143, -216, -141, -201, +204, 262205, 6, -217, -216, +220, +219, 327822, 13, +221, 218, -215, -217, +220, 327809, 13, -219, -211, -218, +222, +214, +221, 327761, 6, -220, -219, +223, +222, 0, 327761, 6, -221, -219, +224, +222, 1, 327761, 6, +225, 222, -219, 2, 458832, 107, +226, 223, -220, -221, -222, +224, +225, 114, 196670, -210, -223, +213, +226, 327745, -171, -224, -141, +174, +227, +143, 74, 262205, -138, -225, -224, +140, +228, +227, 262205, 107, -226, -195, +229, +198, 327825, 107, -227, -225, -226, +230, +228, +229, 196670, -195, -227, +198, +230, 327745, -171, -228, -141, +174, +231, +143, 74, 262205, -138, -229, -228, +140, +232, +231, 262205, 107, -230, -210, +233, +213, 327825, 107, -231, -229, -230, +234, +232, +233, 196670, -210, -231, +213, +234, 262205, 57, -234, +237, 61, 327819, 57, -235, -234, +238, +237, 63, 327850, 26, -236, -235, +239, +238, 74, 196855, -238, +241, 0, 262394, -236, -237, +239, 240, +243, 131320, -237, +240, 196670, -233, -239, +236, +242, 131321, -238, +241, 131320, -240, +243, 196670, -233, +236, 114, 131321, -238, +241, 131320, -238, +241, 262205, 6, -241, -233, +244, +236, 196670, -232, -241, +235, +244, 262205, 6, -247, -232, +250, +235, 327860, 26, -248, -247, -239, -196855, +251, 250, +242, +196855, +253, 0, 262394, -248, -249, +251, 252, +255, 131320, -249, +252, 262205, 107, -251, -195, +254, +198, 196670, -246, -251, +249, +254, 131321, -250, +253, 131320, -252, +255, 262205, 107, -253, -210, +256, +213, 196670, -246, -253, +249, +256, 131321, -250, +253, 131320, -250, +253, 262205, 107, -254, -246, +257, +249, 262205, 6, -255, -232, +258, +235, 262205, 7, -256, -170, +259, +173, 262205, 6, -257, -183, +260, +186, 327822, 7, -258, -256, -257, -393281, -143, 261, -141, 259, 260, +393281, +145, +264, +143, +262, +263, 262205, 6, -262, -261, +265, +264, 327760, 7, -263, -262, -262, +266, +265, +265, 327816, 7, -264, -258, -263, +267, +261, +266, 327761, 6, -265, -264, +268, +267, 0, 327761, 6, -266, -264, +269, +267, 1, 458832, 107, -267, -265, -266, +270, +268, +269, 35, 35, 327822, 107, -268, -267, -255, +271, +270, +258, 262205, 6, -270, -232, +273, +235, 327860, 26, -271, -270, -239, -196855, +274, 273, +242, +196855, +276, 0, 262394, -271, -272, -277, +274, +275, +280, 131320, -272, +275, 327745, 19, -275, -195, -274, +278, +198, +277, 262205, 6, -276, -275, +279, +278, 196670, -269, -276, +272, +279, 131321, -273, +276, 131320, -277, +280, 327745, 19, -278, -210, -274, +281, +213, +277, 262205, 6, -279, -278, +282, +281, 196670, -269, -279, +272, +282, 131321, -273, +276, 131320, -273, +276, 262205, 6, -280, -269, +283, +272, 327822, 107, -281, -268, -280, +284, +271, +283, 327809, 107, -282, -254, -281, -327745, -283, +285, +257, 284, -244, -245, +327745, +286, +287, +247, +248, 196670, -284, -282, -393281, +287, 285, +393281, 288, -244, -245, -287, +291, +247, +248, +290, 262205, 6, -289, -288, +292, +291, 393281, -285, -290, -244, -245, -274, +288, +293, +247, +248, +277, 262205, 6, -291, -290, +294, +293, 327816, 6, +295, 292, -289, -291, +294, 196670, -286, -292, +289, +295, 262205, 13, -294, +297, 117, 262205, 6, -295, -136, +298, +138, 327761, 6, -296, -294, +299, +297, 0, 327761, 6, +300, 297, -294, 1, 327761, 6, -298, -294, +301, +297, 2, 458832, 107, +302, 299, -296, -297, +300, +301, 298, -295, 196670, -293, -299, +296, +302, 262205, 107, -301, -195, +304, +198, 458831, 7, -302, -301, -301, +305, +304, +304, 0, 1, 327745, 19, -303, -195, -274, +306, +198, +277, 262205, 6, -304, -303, +307, +306, 458764, 6, -305, +308, 1, 40, -304, +307, 25, 327760, 7, -306, -305, -305, +309, +308, +308, 327816, 7, -307, -302, -306, +310, +305, +309, 262205, 107, -308, -210, +311, +213, 458831, 7, -309, -308, -308, +312, +311, +311, 0, 1, 327745, 19, -310, -210, -274, +313, +213, +277, 262205, 6, -311, -310, +314, +313, 458764, 6, -312, +315, 1, 40, -311, +314, 25, 327760, 7, -313, -312, -312, +316, +315, +315, 327816, 7, -314, -309, -313, +317, +312, +316, 327761, 6, -315, -307, -0, +318, +310, +0, 327761, 6, -316, -307, +319, +310, 1, 327761, 6, +320, 317, -314, 0, 327761, 6, -318, -314, +321, +317, 1, 458832, 107, -319, -315, -316, -317, +322, 318, -196670, -300, 319, +320, +321, +196670, +303, +322, 65789, 65592, 327734, @@ -11440,7 +11500,7 @@ const std::vector pass1_fragment = {119734787, const std::vector pass2_vertex = {119734787, 65536, 524289, -31, +75, 0, 131089, 1, @@ -11453,15 +11513,14 @@ const std::vector pass2_vertex = {119734787, 196622, 0, 1, -589839, +524303, 0, 4, 1852399981, 0, -10, -14, -27, -28, +58, +62, +70, 196611, 2, 450, @@ -11488,121 +11547,211 @@ const std::vector pass2_vertex = {119734787, 1852399981, 0, 393221, -8, +12, +1349805415, +1953067887, +678326121, +3879285, +262149, +11, +1701080681, +120, +327685, +17, +1416914279, +829761603, +59, +262149, +16, +1701080681, +120, +393221, +56, 1348430951, 1700164197, 2019914866, 0, 393222, -8, +56, 0, 1348430951, 1953067887, 7237481, 196613, -10, -0, -327685, -14, -1769172816, -1852795252, +58, 0, +393221, +62, +1449094247, +1702130277, +1684949368, +30821, 262149, -27, +65, +1634886000, +109, +262149, +70, 2019906678, 0, -327685, -28, -1668834644, -1685221231, -0, +262149, +73, +1634886000, +109, 327752, -8, +56, 0, 11, 0, 196679, -8, +56, 2, 262215, -14, -30, -0, +62, +11, +42, 262215, -27, +70, 30, 0, -262215, -28, -30, -1, 131091, 2, 196641, 3, 2, -196630, +262165, 6, 32, -262167, +0, +262176, +7, 7, 6, +196630, +8, +32, +262167, +9, +8, 4, -196638, +262177, +10, +9, +7, +262167, +14, 8, +2, +262177, +15, +14, 7, -262176, +262187, +8, +25, +3212836864, +262187, +8, +26, +1065353216, +262187, +8, +27, +0, +458796, 9, -3, +28, +25, +26, +27, +26, +262187, 8, -262203, +30, +1077936128, +458796, 9, -10, +31, +30, +26, +27, +26, +262187, +8, +33, +3225419776, +458796, +9, +34, +25, +33, +27, +26, +458796, +9, +36, +27, +27, +27, +27, +327724, +14, +46, +27, +27, +262187, +8, +48, +1073741824, +327724, +14, +49, +27, +48, +327724, +14, +51, +48, +27, +196638, +56, +9, +262176, +57, +3, +56, +262203, +57, +58, 3, 262165, -11, +59, 32, 1, 262187, -11, -12, +59, +60, 0, 262176, -13, +61, 1, -7, +59, 262203, -13, -14, +61, +62, 1, -262167, -15, -6, -3, -262187, -6, -18, -1065353216, 262176, -23, +67, 3, -7, -262167, -25, -6, -2, +9, 262176, -26, +69, 3, -25, +14, 262203, -26, -27, +69, +70, 3, -262203, -13, -28, -1, 327734, 2, 4, @@ -11610,63 +11759,158 @@ const std::vector pass2_vertex = {119734787, 3, 131320, 5, -262205, +262203, 7, -16, +65, +7, +262203, +7, +73, +7, +262205, +59, +63, +62, +262268, +6, +64, +63, +196670, +65, +64, +327737, +9, +66, +12, +65, +327745, +67, +68, +58, +60, +196670, +68, +66, +262205, +59, +71, +62, +262268, +6, +72, +71, +196670, +73, +72, +327737, 14, -524367, -15, +74, 17, -16, -16, +73, +196670, +70, +74, +65789, +65592, +327734, +9, +12, 0, -1, -2, -327761, +10, +196663, +7, +11, +131320, +13, +262205, 6, 19, -17, +11, +196855, +24, +0, +590075, +19, +23, 0, -327761, -6, 20, -17, 1, -327761, -6, 21, -17, 2, -458832, -7, 22, -19, +131320, +23, +131326, +36, +131320, 20, +131326, +28, +131320, 21, -18, -327745, -23, -24, -10, -12, -196670, -24, +131326, +31, +131320, 22, -262205, +131326, +34, +131320, +24, +196609, +9, +39, +131326, +39, +65592, +327734, +14, +17, +0, +15, +196663, 7, -29, -28, -458831, -25, -30, -29, -29, +16, +131320, +18, +262205, +6, +40, +16, +196855, +45, +0, +590075, +40, +44, 0, +41, 1, -196670, -27, -30, -65789, +42, +2, +43, +131320, +44, +131326, +46, +131320, +41, +131326, +46, +131320, +42, +131326, +49, +131320, +43, +131326, +51, +131320, +45, +196609, +14, +55, +131326, +55, 65592, }; const std::vector pass2_fragment = {119734787, @@ -18231,7 +18475,7 @@ const std::vector pass2_fragment = {119734787, const std::vector global_constraints = {119734787, 65536, 524289, -511, +516, 0, 131089, 1, @@ -18251,8 +18495,8 @@ const std::vector global_constraints = {119734787, 4, 1852399981, 0, -266, -267, +270, +271, 393232, 4, 17, @@ -18926,12 +19170,12 @@ const std::vector global_constraints = {119734787, 1701869908, 0, 327685, -204, +208, 1886680431, 1867543669, 115, 524293, -247, +251, 1953067639, 1818386789, 1701990501, @@ -18939,7 +19183,7 @@ const std::vector global_constraints = {119734787, 1869182057, 29550, 655366, -247, +251, 0, 1632132967, 1700164201, @@ -18949,17 +19193,17 @@ const std::vector global_constraints = {119734787, 1701990515, 118, 196613, -249, +253, 0, 458757, -257, +261, 1953067639, 1818386789, 1936674917, 1869182057, 29550, 589830, -257, +261, 0, 1632132967, 1700164201, @@ -18968,10 +19212,10 @@ const std::vector global_constraints = {119734787, 1852795252, 115, 196613, -259, +263, 0, 524293, -266, +270, 1281322087, 1818321775, 1870032457, @@ -18979,41 +19223,41 @@ const std::vector global_constraints = {119734787, 1145663087, 0, 393221, -267, +271, 1465871463, 1198223983, 1886744434, 17481, 458757, -268, +272, 1651469415, 1951624289, 1684955506, 1701080649, 120, 458757, -269, +273, 1633906540, 1920226156, 1231318625, 2019910766, 0, 458757, -270, +274, 1651469415, 1700162657, 2019914866, 1701080649, 120, 458757, -271, +275, 1633906540, 1919243884, 1232627060, 2019910766, 0, 524293, -272, +276, 1450014062, 1769239141, 1232299363, @@ -19021,31 +19265,23 @@ const std::vector global_constraints = {119734787, 1634890835, 25710, 458757, -273, +277, 1701080681, 1919895160, 1918986323, 1699570789, 109, 327685, -274, +278, 1634890867, 2035573870, 25968, 262149, -275, -1634886000, -109, -262149, 279, 1634886000, 109, 262149, -282, -1634886000, -109, -262149, -284, +283, 1634886000, 109, 262149, @@ -19068,18 +19304,26 @@ const std::vector global_constraints = {119734787, 294, 1634886000, 109, +262149, +296, +1634886000, +109, +262149, +298, +1634886000, +109, 327685, -304, +308, 1920103779, 1349807717, 29551, 327685, -306, +310, 1953066601, 1349280105, 29551, 524293, -310, +314, 1850302311, 1634301033, 1767983212, @@ -19087,13 +19331,13 @@ const std::vector global_constraints = {119734787, 1869182057, 29550, 393221, -316, +321, 1684104520, 1851880020, 1919903347, 109, 589830, -316, +321, 0, 1867341671, 1416389988, @@ -19102,7 +19346,7 @@ const std::vector global_constraints = {119734787, 1215459142, 6578533, 589830, -316, +321, 1, 1867341671, 1382835556, @@ -19111,7 +19355,7 @@ const std::vector global_constraints = {119734787, 1684104520, 0, 589830, -316, +321, 2, 1852396386, 1214606439, @@ -19120,69 +19364,69 @@ const std::vector global_constraints = {119734787, 1836216166, 0, 327686, -316, +321, 3, 1684300144, 6778473, 196613, -318, +323, 0, 262149, -341, +346, 1349545332, 29551, 393221, -345, +350, 1886216548, 1130851945, 1717986671, 0, 262149, -384, +389, 1348758639, 29551, 262149, -390, +395, 1668444006, 101, 262149, -391, +396, 1634886000, 109, 262149, -398, +403, 1634886000, 109, 262149, -400, +405, 1634886000, 109, 262149, -402, +407, 1634886000, 109, 262149, -404, +409, 1634886000, 109, 262149, -406, +411, 1634886000, 109, 262149, -407, +412, 1634886000, 109, 262149, -409, +414, 1634886000, 109, 262149, -411, +416, 1634886000, 109, 655365, -416, +421, 1718187123, 1936027238, 1919895155, @@ -19192,7 +19436,7 @@ const std::vector global_constraints = {119734787, 1751348321, 6778473, 720901, -417, +422, 1651469415, 1750297697, 1298493537, @@ -19203,34 +19447,34 @@ const std::vector global_constraints = {119734787, 1735287122, 101, 262149, -468, +473, 1634886000, 109, 262149, -482, +487, 1952670054, 29295, 196613, -485, +490, 7103844, 262149, -500, +505, 1634886000, 109, 262149, -502, +507, 1634886000, 109, 262149, -504, +509, 1634886000, 109, 262149, -505, +510, 1634886000, 109, 262149, -507, +512, 1634886000, 109, 327752, @@ -19398,107 +19642,107 @@ const std::vector global_constraints = {119734787, 33, 22, 262215, -246, +250, 6, 16, 327752, -247, +251, 0, 35, 0, 196679, -247, +251, 3, 262215, -249, +253, 34, 1, 262215, -249, +253, 33, 20, 262215, -256, +260, 6, 16, 327752, -257, +261, 0, 35, 0, 196679, -257, +261, 3, 262215, -259, +263, 34, 1, 262215, -259, +263, 33, 7, 262215, -266, +270, 11, 27, 262215, -267, +271, 11, 26, 262215, -310, +314, 34, 1, 262215, -310, +314, 33, 21, 262215, -315, +320, 6, 16, 262216, -316, +321, 0, 5, 327752, -316, +321, 0, 35, 0, 327752, -316, +321, 0, 7, 16, 327752, -316, +321, 1, 35, 64, 327752, -316, +321, 2, 35, 80, 327752, -316, +321, 3, 35, 96, 196679, -316, +321, 3, 262215, -318, +323, 34, 0, 262215, -318, +323, 33, 27, 262215, -510, +515, 11, 25, 131091, @@ -19680,112 +19924,112 @@ const std::vector global_constraints = {119734787, 122, 0, 262167, -126, +127, 14, 4, 262187, 14, -128, +129, 0, 262187, 16, -182, +185, 64, 262187, 16, -206, +210, 6, 262176, -207, +211, 2, 6, 262167, -210, +214, 6, 3, 262187, 6, -211, +215, 3212836864, 393260, -210, -212, +214, +216, 82, -211, +215, 82, 262187, 6, -221, +225, 1065353216, 262187, 16, -233, +237, 7, 196637, -246, +250, 7, 196638, -247, -246, +251, +250, 262176, -248, +252, 2, -247, +251, 262203, -248, -249, +252, +253, 2, 262187, 16, -250, +254, 0, 262176, -254, +258, 2, 7, 196637, -256, +260, 7, 196638, -257, -256, +261, +260, 262176, -258, +262, 2, -257, +261, 262203, -258, -259, +262, +263, 2, 262167, -264, +268, 14, 3, 262176, -265, +269, 1, -264, +268, 262203, -265, -266, +269, +270, 1, 262203, -265, -267, +269, +271, 1, 262176, -276, +280, 1, 14, 458796, 7, -305, +309, 82, 82, 82, 82, 589849, -307, +311, 6, 5, 0, @@ -19794,113 +20038,113 @@ const std::vector global_constraints = {119734787, 1, 0, 196635, -308, -307, +312, +311, 262176, -309, +313, 0, -308, +312, 262203, -309, -310, +313, +314, 0, 262168, -314, +319, 7, 4, 262172, -315, +320, 6, 79, 393246, -316, -314, +321, +319, 7, 16, -315, +320, 262176, -317, +322, 2, -316, +321, 262203, -317, -318, +322, +323, 2, 262176, -319, +324, 2, -314, +319, 262187, 16, -332, +337, 27, 262176, -333, +338, 2, 16, 262187, 6, -346, +351, 1022739087, 262187, 16, -351, +356, 8, 262187, 16, -359, +364, 12, 262187, 14, -364, +369, 2, 262187, 16, -368, +373, 16, 262187, 16, -376, +381, 20, 262187, 16, -422, +427, 10, 262187, 16, -425, +430, 11, 262187, 16, -433, +438, 14, 262187, 16, -436, +441, 15, 262187, 16, -444, +449, 18, 262187, 16, -447, +452, 19, 262187, 16, -455, +460, 22, 262187, 16, -458, +463, 23, 262176, -484, +489, 7, -210, +214, 393260, -264, -510, +268, +515, 87, 109, 109, @@ -19913,1206 +20157,1210 @@ const std::vector global_constraints = {119734787, 5, 262203, 15, -268, +272, 7, 262203, 15, -269, +273, 7, 262203, 17, -270, +274, 7, 262203, 15, -271, +275, 7, 262203, 15, -272, +276, 7, 262203, 15, -273, +277, 7, 262203, 15, -274, +278, 7, 262203, 15, -275, +279, 7, 262203, 15, -279, +283, 7, 262203, 15, -282, +286, 7, 262203, 15, -284, +288, 7, 262203, 17, -286, +290, 7, 262203, 15, -288, +292, 7, 262203, 15, -290, +294, 7, 262203, 15, -292, +296, 7, 262203, 15, -294, +298, 7, 262203, 8, -304, +308, 7, 262203, 8, -306, +310, 7, 262203, 8, -341, +346, 7, 262203, 59, -345, +350, 7, 262203, 8, -384, +389, 7, 262203, 8, -390, +395, 7, 262203, 8, -391, +396, 7, 262203, 8, -398, +403, 7, 262203, 8, -400, +405, 7, 262203, 8, -402, +407, 7, 262203, 8, -404, +409, 7, 262203, 15, -406, +411, 7, 262203, 15, -407, +412, 7, 262203, 15, -409, +414, 7, 262203, 59, -411, +416, 7, 262203, 59, -416, +421, 7, 262203, 59, -417, +422, 7, 262203, 8, -468, +473, 7, 262203, 59, -482, +487, 7, 262203, -484, -485, +489, +490, 7, 262203, 8, -500, +505, 7, 262203, 8, -502, +507, 7, 262203, 15, -504, +509, 7, 262203, 15, -505, +510, 7, 262203, 15, -507, +512, 7, 327745, -276, -277, -266, -128, -262205, -14, -278, -277, -196670, -275, -278, -327745, -276, 280, -267, -128, +281, +270, +129, 262205, 14, +282, 281, -280, 196670, 279, -281, -262205, -14, -283, -268, -196670, 282, -283, +327745, +280, +284, +271, +129, 262205, 14, 285, -269, -196670, 284, +196670, +283, 285, 262205, -16, +14, 287, -270, +272, 196670, 286, 287, 262205, 14, 289, -271, +273, 196670, 288, 289, 262205, -14, +16, 291, -272, +274, 196670, 290, 291, 262205, 14, 293, -273, +275, 196670, 292, 293, 262205, 14, 295, -274, +276, 196670, 294, 295, -852025, -2, -296, -28, -275, -279, -282, -284, -286, -288, -290, -292, -294, 262205, 14, 297, -282, +277, 196670, -268, +296, 297, 262205, 14, -298, -284, -196670, -269, -298, -262205, -16, 299, -286, +278, 196670, -270, +298, 299, -262205, -14, +852025, +2, 300, +28, +279, +283, +286, 288, -196670, -271, -300, +290, +292, +294, +296, +298, 262205, 14, 301, -290, +286, 196670, 272, 301, 262205, 14, 302, -292, +288, 196670, 273, 302, 262205, -14, +16, 303, -294, +290, 196670, 274, 303, -196670, +262205, +14, 304, -305, +292, 196670, -306, +275, +304, +262205, +14, +305, +294, +196670, +276, 305, 262205, +14, +306, +296, +196670, +277, +306, +262205, +14, +307, +298, +196670, +278, +307, +196670, 308, -311, +309, +196670, 310, +309, 262205, -16, 312, -270, +315, +314, +262205, +16, +316, +274, +262244, +311, +317, +315, 327775, 7, -313, -311, -312, +318, +317, +316, 196670, -306, -313, -327745, -319, -320, +310, 318, -250, +327745, +324, +325, +323, +254, 262205, -314, -321, -320, +319, +326, +325, 262205, 7, -322, -306, +327, +310, 524367, -210, -323, -322, -322, +214, +328, +327, +327, 0, 1, 2, 327761, 6, -324, -323, +329, +328, 0, 327761, 6, -325, -323, +330, +328, 1, 327761, 6, -326, -323, +331, +328, 2, 458832, 7, -327, -324, -325, -326, -221, +332, +329, +330, +331, +225, 327825, 7, -328, -321, -327, +333, +326, +332, 524367, -210, -329, -328, -328, +214, +334, +333, +333, 0, 1, 2, 262205, 7, -330, -306, +335, +310, 589903, 7, -331, -330, -329, +336, +335, +334, 4, 5, 6, 3, 196670, -306, -331, +310, +336, 327745, -333, -334, +338, +339, 90, -332, +337, 262205, 16, -335, -334, +340, +339, 327851, 9, -336, -335, -250, +341, +340, +254, 196855, -338, +343, 0, 262394, -336, -337, -340, +341, +342, +345, 131320, -337, +342, 262205, 7, -339, -306, +344, +310, 196670, -304, -339, +308, +344, 131321, -338, +343, 131320, -340, +345, 262205, 16, -342, -270, +347, +274, 393281, +258, +348, +263, 254, -343, -259, -250, -342, +347, 262205, 7, -344, -343, +349, +348, 196670, -341, -344, +346, +349, 196670, -304, -344, +308, +349, 131321, -338, +343, 131320, -338, +343, 196670, -345, -346, +350, +351, 262205, 14, -347, -274, +352, +278, 327850, 9, -348, -347, -128, +353, +352, +129, 196855, -350, +355, 0, 262394, -348, -349, +353, 354, +359, 131320, -349, +354, 327745, -207, -352, +211, +357, 90, -351, +356, 262205, 6, -353, -352, +358, +357, 196670, -345, -353, -131321, 350, +358, +131321, +355, 131320, -354, +359, 262205, 14, -355, -274, +360, +278, 327850, 9, -356, -355, +361, +360, 109, 196855, -358, +363, 0, 262394, -356, -357, +361, 362, +367, 131320, -357, +362, 327745, -207, -360, +211, +365, 90, -359, +364, 262205, 6, -361, -360, +366, +365, 196670, -345, -361, +350, +366, 131321, -358, +363, 131320, -362, +367, 262205, 14, -363, -274, +368, +278, 327850, 9, -365, -363, -364, +370, +368, +369, 196855, -367, +372, 0, 262394, -365, -366, +370, 371, +376, 131320, -366, +371, 327745, -207, -369, +211, +374, 90, -368, +373, 262205, 6, -370, -369, +375, +374, 196670, -345, -370, +350, +375, 131321, -367, +372, 131320, -371, +376, 262205, 14, -372, -274, +377, +278, 327850, 9, -373, -372, +378, +377, 79, 196855, -375, +380, 0, 262394, -373, -374, -375, +378, +379, +380, 131320, -374, +379, 327745, -207, -377, +211, +382, 90, -376, +381, 262205, 6, -378, -377, +383, +382, 196670, -345, -378, +350, +383, 131321, -375, +380, 131320, -375, +380, 131321, -367, +372, 131320, -367, +372, 131321, -358, +363, 131320, -358, +363, 131321, -350, +355, 131320, -350, +355, 327745, -333, -379, +338, +384, 90, -332, +337, 262205, 16, -380, -379, +385, +384, 327851, 9, -381, -380, -250, +386, +385, +254, 196855, -383, +388, 0, 262394, -381, -382, 386, +387, +391, 131320, -382, +387, 262205, 7, -385, -304, +390, +308, 196670, -384, -385, +389, +390, 131321, -383, +388, 131320, -386, +391, 262205, 16, -387, -270, +392, +274, 393281, +258, +393, +253, 254, -388, -249, -250, -387, +392, 262205, 7, -389, -388, +394, +393, 196670, -384, 389, +394, 131321, -383, +388, 131320, -383, +388, 196670, -390, -305, +395, +309, 262205, 7, -392, -304, +397, +308, 196670, -391, -392, +396, +397, 327737, 9, -393, +398, 12, -391, +396, 196855, -395, +400, 0, 262394, -393, -394, -414, +398, +399, +419, 131320, -394, +399, 262205, 16, -396, -270, +401, +274, 262268, 14, -397, -396, -262205, -7, -399, -304, -196670, -398, -399, -262205, -7, -401, -384, -196670, -400, +402, 401, 262205, 7, -403, -306, +404, +308, 196670, -402, 403, +404, 262205, 7, -405, -390, +406, +389, 196670, -404, 405, -196670, 406, -397, 262205, -14, +7, 408, -271, +310, 196670, 407, 408, 262205, -14, +7, 410, -272, +395, 196670, 409, 410, -262205, -6, -412, -345, 196670, 411, -412, -786489, -7, -413, -69, -398, -400, 402, -404, -406, -407, -409, -411, +262205, +14, +413, +275, 196670, -341, +412, 413, -131321, -395, -131320, -414, 262205, -7, +14, 415, -306, +276, 196670, -341, +414, 415, -131321, -395, -131320, -395, +262205, +6, +417, +350, 196670, 416, +417, +786489, +7, +418, +69, +403, +405, +407, +409, +411, +412, +414, +416, +196670, +346, +418, +131321, +400, +131320, +419, +262205, +7, +420, +310, +196670, +346, +420, +131321, +400, +131320, +400, +196670, +421, 82, 196670, -417, +422, 82, 262205, 14, -418, -274, +423, +278, 327850, 9, -419, -418, -128, +424, +423, +129, 196855, -421, +426, 0, 262394, -419, -420, -428, +424, +425, +433, 131320, -420, +425, 327745, -207, -423, +211, +428, 90, -422, +427, 262205, 6, -424, -423, +429, +428, 196670, -416, -424, +421, +429, 327745, -207, -426, +211, +431, 90, -425, +430, 262205, 6, -427, -426, +432, +431, 196670, -417, -427, +422, +432, 131321, -421, +426, 131320, -428, +433, 262205, 14, -429, -274, +434, +278, 327850, 9, -430, -429, +435, +434, 109, 196855, -432, +437, 0, 262394, -430, -431, -439, +435, +436, +444, 131320, -431, +436, 327745, -207, -434, +211, +439, 90, -433, +438, 262205, 6, -435, -434, +440, +439, 196670, -416, -435, +421, +440, 327745, -207, -437, +211, +442, 90, -436, +441, 262205, 6, -438, -437, +443, +442, 196670, -417, -438, +422, +443, 131321, -432, +437, 131320, -439, +444, 262205, 14, -440, -274, +445, +278, 327850, 9, -441, -440, -364, +446, +445, +369, 196855, -443, +448, 0, 262394, -441, -442, -450, +446, +447, +455, 131320, -442, +447, 327745, -207, -445, +211, +450, 90, -444, +449, 262205, 6, -446, -445, +451, +450, 196670, -416, -446, +421, +451, 327745, -207, -448, +211, +453, 90, -447, +452, 262205, 6, -449, -448, +454, +453, 196670, -417, -449, +422, +454, 131321, -443, +448, 131320, -450, +455, 262205, 14, -451, -274, +456, +278, 327850, 9, -452, -451, +457, +456, 79, 196855, -454, +459, 0, 262394, -452, -453, -454, +457, +458, +459, 131320, -453, +458, 327745, -207, -456, +211, +461, 90, -455, +460, 262205, 6, -457, -456, +462, +461, 196670, -416, -457, +421, +462, 327745, -207, -459, +211, +464, 90, -458, +463, 262205, 6, -460, -459, +465, +464, 196670, -417, -460, +422, +465, 131321, -454, +459, 131320, -454, +459, 131321, -443, +448, 131320, -443, +448, 131321, -432, +437, 131320, -432, +437, 131321, -421, +426, 131320, -421, +426, 262205, 6, -461, -416, +466, +421, 327866, 9, -462, -461, +467, +466, 82, 262205, 6, -463, -417, +468, +422, 327862, 9, -464, -463, +469, +468, 82, 327847, 9, -465, -462, -464, -196855, +470, 467, +469, +196855, +472, 0, 262394, -465, -466, -467, +470, +471, +472, 131320, -466, +471, 262205, 7, -469, -341, +474, +346, 196670, -468, -469, +473, +474, 327737, 9, -470, +475, 12, -468, +473, 196855, -472, +477, 0, 262394, -470, -471, -472, +475, +476, +477, 131320, -471, +476, 262205, 14, -473, -271, +478, +275, 262256, 6, -474, -473, +479, +478, 262205, 6, -475, -417, +480, +422, 262205, 14, -476, -272, +481, +276, 262256, 6, -477, -476, +482, +481, 327813, 6, -478, -475, -477, +483, +480, +482, 327864, 9, +484, 479, -474, -478, +483, 196855, -481, +486, 0, 262394, -479, -480, -481, +484, +485, +486, 131320, -480, +485, 262205, 6, -483, -416, +488, +421, 196670, -482, -483, +487, +488, 262205, 6, -486, -482, +491, +487, 262205, 7, -487, -306, +492, +310, 262205, 7, -488, -341, +493, +346, 327811, 7, -489, -487, -488, +494, +492, +493, 524367, -210, -490, -489, -489, +214, +495, +494, +494, 0, 1, 2, 327822, -210, +214, +496, +495, 491, -490, -486, 196670, -485, -491, +490, +496, 262205, -210, -492, -485, +214, +497, +490, 262205, 7, -493, -341, +498, +346, 524367, -210, -494, -493, -493, +214, +499, +498, +498, 0, 1, 2, 327809, -210, -495, -494, -492, +214, +500, +499, +497, 262205, 7, -496, -341, +501, +346, 589903, 7, -497, -496, -495, +502, +501, +500, 4, 5, 6, 3, 196670, -341, -497, +346, +502, 131321, -481, +486, 131320, -481, +486, 131321, -472, +477, 131320, -472, +477, 131321, -467, +472, 131320, -467, +472, 262205, 16, -498, -270, +503, +274, 262268, 14, -499, -498, +504, +503, 262205, 7, -501, -304, +506, +308, 196670, -500, -501, +505, +506, 262205, 7, -503, -341, +508, +346, 196670, -502, -503, +507, +508, 196670, +509, 504, -499, 262205, 14, -506, -271, +511, +275, 196670, -505, -506, +510, +511, 262205, 14, -508, -272, +513, +276, 196670, -507, -508, +512, +513, 589881, 2, -509, +514, 77, -500, -502, -504, 505, 507, +509, +510, +512, 65789, 65592, 327734, @@ -21319,48 +21567,52 @@ const std::vector global_constraints = {119734787, 16, 125, 124, -327775, +262244, +119, 126, -127, 123, +327775, +127, +128, +126, 125, 327761, 14, -129, -127, +130, +128, 0, 196670, 27, -129, +130, 262205, 14, -130, +131, 21, 262205, 14, -131, +132, 25, 327812, 14, -132, -130, +133, 131, +132, 262205, 14, -133, +134, 24, 327808, 14, -134, -132, +135, 133, +134, 262268, 16, +136, 135, -134, 196670, 23, -135, +136, 65789, 65592, 327734, @@ -21399,163 +21651,167 @@ const std::vector global_constraints = {119734787, 40, 262205, 14, -136, +137, 30, 196670, 37, -136, +137, 327745, 92, -137, +138, 90, 91, 262205, 14, +139, 138, -137, 327814, 14, -139, +140, 87, -138, +139, 196670, 36, -139, +140, 262205, 14, -140, +141, 30, 327745, 92, -141, +142, 90, 91, 262205, 14, +143, 142, -141, 327817, 14, +144, +141, 143, -140, -142, 196670, 33, -143, +144, 262205, 14, -144, +145, 31, 327745, 92, -145, +146, 90, 91, 262205, 14, +147, 146, -145, 327812, 14, +148, +145, 147, -144, -146, 262205, 14, -148, +149, 33, 327808, 14, -149, -147, +150, 148, +149, 196670, 32, -149, +150, 262205, 14, -150, +151, 30, 262205, 14, -151, +152, 33, 327810, 14, -152, -150, +153, 151, +152, 327745, 92, -153, +154, 90, 91, 262205, 14, +155, 154, -153, 327814, 14, +156, +153, 155, -152, -154, 196670, 35, -155, +156, 262205, 120, -156, +157, 122, 262205, 14, -157, +158, 32, 262268, 16, +159, 158, +262244, +119, +160, 157, 327775, -126, +127, +161, +160, 159, -156, -158, 327761, 14, -160, -159, +162, +161, 0, 196670, 38, -160, +162, 262205, 14, -161, +163, 32, 262205, 14, -162, +164, 36, 327812, 14, +165, 163, -161, -162, +164, 262205, 14, -164, +166, 35, 327808, 14, +167, 165, -163, -164, +166, 262268, 16, -166, -165, +168, +167, 196670, 34, -166, +168, 65789, 65592, 327734, @@ -21585,83 +21841,87 @@ const std::vector global_constraints = {119734787, 49, 262205, 14, -167, +169, 43, 327812, 14, -168, +170, 87, -167, +169, 262205, 14, -169, +171, 42, 327808, 14, +172, 170, -168, -169, +171, 196670, 44, -170, +172, 327745, 92, -171, +173, 90, 91, 262205, 14, -172, -171, +174, +173, 327814, 14, -173, +175, 87, -172, +174, 196670, 45, -173, +175, 262205, 120, -174, +176, 122, 262205, 14, -175, +177, 44, 262268, 16, -176, -175, -327775, -126, +178, 177, -174, +262244, +119, +179, 176, +327775, +127, +180, +179, +178, 327761, 14, -178, -177, +181, +180, 0, 196670, 47, -178, +181, 262205, 14, -179, +182, 44, 262205, 14, -180, +183, 45, 327812, 14, -181, -179, -180, +184, +182, +183, 196670, 46, -181, +184, 65789, 65592, 327734, @@ -21691,113 +21951,117 @@ const std::vector global_constraints = {119734787, 58, 262205, 16, -183, +186, 52, 327812, 16, -184, -182, -183, +187, +185, +186, 262205, 16, -185, +188, 51, 327808, 16, -186, -184, -185, +189, +187, +188, 196670, 53, -186, +189, 327745, 92, -187, +190, 90, 106, 262205, 14, -188, -187, +191, +190, 327808, 14, -189, -188, +192, +191, 109, 262268, 16, -190, -189, +193, +192, 262205, 16, -191, +194, 53, 327812, 16, -192, -191, -190, +195, +194, +193, 196670, 53, -192, +195, 327745, 92, -193, +196, 90, 91, 262205, 14, -194, -193, +197, +196, 327814, 14, -195, +198, 87, -194, +197, 196670, 54, -195, +198, 262205, 120, -196, +199, 122, 262205, 16, -197, +200, 53, +262244, +119, +201, +199, 327775, -126, -198, -196, -197, +127, +202, +201, +200, 327761, 14, -199, -198, +203, +202, 0, 196670, 56, -199, +203, 262205, 16, -200, +204, 53, 262205, 14, -201, +205, 54, 262268, 16, -202, -201, +206, +205, 327812, 16, -203, -200, -202, +207, +204, +206, 196670, 55, -203, +207, 65789, 65592, 327734, @@ -21833,189 +22097,189 @@ const std::vector global_constraints = {119734787, 70, 262203, 8, -204, +208, 7, 262205, 7, -205, +209, 61, 196670, -204, -205, -327745, -207, 208, +209, +327745, +211, +212, 90, -206, +210, 262205, 6, -209, -208, -327822, -210, 213, 212, -209, +327822, +214, +217, +216, +213, 262205, 7, -214, +218, 64, 524367, -210, -215, -214, 214, +219, +218, +218, 0, 1, 2, 327809, -210, -216, -215, -213, +214, +220, +219, +217, 262205, 7, -217, +221, 64, 589903, 7, -218, -217, -216, +222, +221, +220, 4, 5, 6, 3, 196670, 64, -218, +222, 262205, 7, -219, +223, 61, 524367, -210, -220, -219, -219, +214, +224, +223, +223, 0, 1, 2, 262205, 6, -222, +226, 68, 327811, 6, -223, -221, -222, +227, +225, +226, 262205, 7, -224, +228, 61, 524367, -210, -225, -224, -224, +214, +229, +228, +228, 0, 1, 2, 262205, 7, -226, +230, 62, 524367, -210, -227, -226, -226, +214, +231, +230, +230, 0, 1, 2, 327811, -210, -228, -225, -227, -327822, -210, +214, +232, 229, -228, -223, +231, +327822, +214, +233, +232, +227, 327809, -210, -230, -220, -229, +214, +234, +224, +233, 262205, 7, -231, +235, 64, 524367, -210, -232, -231, -231, +214, +236, +235, +235, 0, 1, 2, 327745, -207, -234, +211, +238, 90, -233, +237, 262205, 6, -235, -234, +239, +238, 327822, -210, +214, +240, 236, -232, -235, +239, 327745, -207, -237, +211, +241, 90, -233, +237, 262205, 6, -238, -237, +242, +241, 327822, -210, -239, -236, -238, -327809, -210, +214, +243, 240, -230, -239, +242, +327809, +214, +244, +234, +243, 262205, 7, -241, -204, +245, +208, 589903, 7, -242, -241, -240, +246, +245, +244, 4, 5, 6, 3, 196670, -204, -242, +208, +246, 262205, 7, -243, -204, +247, +208, 131326, -243, +247, 65592, 327734, 2, @@ -22041,53 +22305,53 @@ const std::vector global_constraints = {119734787, 78, 262205, 14, -251, +255, 74, 262268, 16, -252, -251, +256, +255, 262205, 7, -253, +257, 72, 393281, +258, +259, +253, 254, -255, -249, -250, -252, +256, 196670, -255, -253, +259, +257, 262205, 14, -260, +264, 74, 262268, 16, -261, -260, +265, +264, 262205, 7, -262, +266, 73, 393281, -254, +258, +267, 263, -259, -250, -261, +254, +265, 196670, -263, -262, +267, +266, 65789, 65592, }; const std::vector local_constraints = {119734787, 65536, 524289, -701, +707, 0, 131089, 1, @@ -22107,8 +22371,8 @@ const std::vector local_constraints = {119734787, 4, 1852399981, 0, -417, -422, +421, +426, 393232, 4, 17, @@ -22741,39 +23005,39 @@ const std::vector local_constraints = {119734787, 1701869908, 0, 196613, -206, +210, 113, 262149, -307, +311, 1667593841, 0, 196613, -315, +319, 30325, 196613, -319, +323, 7763317, 327685, -338, +342, 1718378856, 1818717761, 101, 262149, -342, +346, 1215195507, 6712417, 327685, -345, +349, 1952544113, 1768845925, 28271, 327685, -357, +361, 1735288172, 1901291636, 114, 524293, -417, +421, 1281322087, 1818321775, 1870032457, @@ -22781,20 +23045,20 @@ const std::vector local_constraints = {119734787, 1145663087, 0, 393221, -422, +426, 1465871463, 1198223983, 1886744434, 17481, 458757, -426, +430, 1651469415, 1951624289, 1684955506, 1701080649, 120, 524293, -427, +431, 1450014062, 1769239141, 1232299363, @@ -22802,7 +23066,7 @@ const std::vector local_constraints = {119734787, 1634890835, 25710, 524293, -428, +432, 1651469415, 1867672673, 1700164719, @@ -22810,36 +23074,36 @@ const std::vector local_constraints = {119734787, 1701080649, 120, 327685, -429, +433, 1634890867, 2035573870, 25968, 262149, -430, +434, 1634886000, 109, 262149, -431, +435, 1634886000, 109, 262149, -432, +436, 1634886000, 109, 262149, -434, +438, 1634886000, 109, 262149, -436, +440, 1634886000, 109, 262149, -438, +442, 1634886000, 109, 655365, -445, +449, 1718187123, 1936027238, 1919895155, @@ -22849,34 +23113,34 @@ const std::vector local_constraints = {119734787, 1768448884, 26478, 458757, -483, +487, 1651469415, 1700162657, 2019914866, 1701080649, 120, 458757, -485, +489, 1633906540, 1919243884, 1232627060, 2019910766, 0, 393221, -501, +505, 1918986355, 1951622245, 1684955506, 7565136, 458757, -504, +508, 1953067639, 1818386789, 1936674917, 1869182057, 29550, 589830, -504, +508, 0, 1632132967, 1700164201, @@ -22885,55 +23149,55 @@ const std::vector local_constraints = {119734787, 1852795252, 115, 196613, -506, +510, 0, 327685, -515, +519, 1919251561, 1869182049, 29550, 196613, -527, +531, 7565168, 327685, -530, +534, 1198813042, 1633841004, 108, 458757, -534, +538, 1816616807, 1818321519, 1635020626, 1852795252, 115, 458757, -538, +543, 1633906540, 1919243884, 1232627060, 2019910766, 0, 393221, -552, +557, 1601400688, 1937075312, 1701736287, 0, 393221, -557, +562, 1198813042, 1633841004, 1919899500, 25708, 393221, -560, +565, 1684104520, 1851880020, 1919903347, 109, 589830, -560, +565, 0, 1867341671, 1416389988, @@ -22942,7 +23206,7 @@ const std::vector local_constraints = {119734787, 1215459142, 6578533, 589830, -560, +565, 1, 1867341671, 1382835556, @@ -22951,7 +23215,7 @@ const std::vector local_constraints = {119734787, 1684104520, 0, 589830, -560, +565, 2, 1852396386, 1214606439, @@ -22960,23 +23224,23 @@ const std::vector local_constraints = {119734787, 1836216166, 0, 327686, -560, +565, 3, 1684300144, 6778473, 196613, -562, +567, 0, 262149, -563, +568, 1634886000, 109, 262149, -566, +571, 1634886000, 109, 655365, -569, +574, 1348956783, 1767863151, 1970040927, @@ -22986,7 +23250,7 @@ const std::vector local_constraints = {119734787, 1701667186, 26975, 589829, -570, +575, 1632132967, 1699902057, 1667585638, @@ -22995,7 +23259,7 @@ const std::vector local_constraints = {119734787, 1835102790, 101, 655365, -576, +582, 1348956783, 1767863151, 1970040927, @@ -23005,89 +23269,89 @@ const std::vector local_constraints = {119734787, 1835102790, 101, 262149, -577, +583, 1634886000, 109, 262149, -579, +585, 1634886000, 109, 196613, -585, +591, 7103844, 262149, -592, +598, 1634886000, 109, 262149, -603, +609, 1634886000, 109, 458757, -614, +620, 1383493225, 1816622191, 1818321519, 1819438935, 100, 262149, -615, +621, 1634886000, 109, 196613, -618, +624, 6514038, 458757, -625, +631, 1600741240, 1937075312, 1717514591, 1701667186, 26975, 262149, -626, +632, 1634886000, 109, 262149, -628, +634, 1634886000, 109, 196613, -632, +638, 101, 262149, -634, +640, 1098149746, 7563640, 393221, -643, +649, 1818717793, 1634885477, 1851877732, 0, 327685, -650, +656, 1633906540, 1953452652, 0, 262149, -651, +657, 1634886000, 109, 262149, -653, +659, 1634886000, 109, 262149, -656, +662, 1634886000, 109, 262149, -658, +664, 1634886000, 109, 458757, -679, +685, 1633906540, 1919243884, 1232627060, @@ -23258,95 +23522,95 @@ const std::vector local_constraints = {119734787, 33, 22, 262215, -417, +421, 11, 27, 262215, -422, +426, 11, 26, 262215, -503, +507, 6, 16, 327752, -504, +508, 0, 35, 0, 196679, -504, +508, 3, 262215, -506, +510, 34, 1, 262215, -506, +510, 33, 7, 262215, -534, +538, 34, 1, 262215, -534, +538, 33, 23, 262215, -559, +564, 6, 16, 262216, -560, +565, 0, 5, 327752, -560, +565, 0, 35, 0, 327752, -560, +565, 0, 7, 16, 327752, -560, +565, 1, 35, 64, 327752, -560, +565, 2, 35, 80, 327752, -560, +565, 3, 35, 96, 196679, -560, +565, 3, 262215, -562, +567, 34, 0, 262215, -562, +567, 33, 27, 262215, -570, +575, 34, 1, 262215, -570, +575, 33, 24, 262215, -700, +706, 11, 25, 131091, @@ -23536,140 +23800,140 @@ const std::vector local_constraints = {119734787, 124, 0, 262167, -128, +129, 14, 4, 262187, 14, -130, +131, 0, 262187, 16, -184, +187, 64, 262187, 14, -224, +228, 2, 262187, 6, -323, +327, 1073741824, 262187, 6, -339, +343, 1056964608, 262187, 6, -382, +386, 981668463, 262187, 6, -386, +390, 1065353216, 458796, 7, -387, +391, 84, 84, 84, -386, +390, 262167, -415, +419, 14, 3, 262176, -416, +420, 1, -415, +419, 262203, -416, -417, +420, +421, 1, 262176, -418, +422, 1, 14, 262203, -416, -422, +420, +426, 1, 262187, 6, -446, +450, 1053609165, 262187, 16, -451, +455, 17, 262176, -452, +456, 2, 6, 262187, 16, -460, +464, 21, 262187, 16, -468, +472, 13, 262187, 16, -476, +480, 9, 262187, 6, -480, +484, 1064514355, 262187, 16, -484, +488, 0, 262187, 14, -498, +502, 16, 262172, -499, +503, 7, -498, +502, 262176, -500, +504, 7, -499, -196637, 503, +196637, +507, 7, 196638, -504, -503, +508, +507, 262176, -505, +509, 2, -504, +508, 262203, -505, -506, +509, +510, 2, 262176, -508, +512, 2, 7, 262187, 16, -513, +517, 1, 262187, 16, -522, +526, 28, 262176, -523, +527, 2, 16, 589849, -531, +535, 6, 5, 0, @@ -23678,51 +23942,51 @@ const std::vector local_constraints = {119734787, 1, 0, 196635, -532, -531, +536, +535, 262176, -533, +537, 0, -532, +536, 262203, -533, -534, +537, +538, 0, 262168, -558, +563, 7, 4, 262172, -559, +564, 6, 81, 393246, -560, -558, +565, +563, 7, 16, -559, +564, 262176, -561, +566, 2, -560, +565, 262203, -561, -562, +566, +567, 2, 262203, -533, -570, +537, +575, 0, 393260, 64, -633, -386, +639, +390, 84, 84, 393260, -415, -700, +419, +706, 89, 111, 111, @@ -23735,198 +23999,185 @@ const std::vector local_constraints = {119734787, 5, 262203, 17, -426, +430, 7, 262203, 15, -427, +431, 7, 262203, 17, -428, +432, 7, 262203, 15, -429, +433, 7, 262203, 17, -430, +434, 7, 262203, 17, -431, +435, 7, 262203, 17, -432, +436, 7, 262203, 15, -434, +438, 7, 262203, 17, -436, +440, 7, 262203, 15, -438, +442, 7, 262203, 71, -445, +449, 7, 262203, 17, -483, +487, 7, 262203, 17, -485, +489, 7, 262203, -500, -501, +504, +505, 7, 262203, 17, -515, +519, 7, 262203, 8, -527, +531, 7, 262203, 8, -530, +534, 7, 262203, 17, -538, +543, 7, 262203, 8, -552, +557, 7, 262203, 8, -557, +562, 7, 262203, 8, -563, +568, 7, 262203, 8, -566, +571, 7, 262203, 65, -569, +574, 7, 262203, 65, -576, +582, 7, 262203, 8, -577, +583, 7, 262203, 65, -579, +585, 7, 262203, 65, -585, +591, 7, 262203, 8, -592, +598, 7, 262203, 8, -603, +609, 7, 262203, 8, -614, +620, 7, 262203, 8, -615, +621, 7, 262203, 65, -618, +624, 7, 262203, 65, -625, +631, 7, 262203, 8, -626, +632, 7, 262203, 65, -628, +634, 7, 262203, 65, -632, +638, 7, 262203, 65, -634, +640, 7, 262203, 71, -643, +649, 7, 262203, 8, -650, +656, 7, 262203, 71, -651, +657, 7, 262203, 65, -653, +659, 7, 262203, 8, -656, +662, 7, 262203, 8, -658, +664, 7, 262203, 17, -679, +685, 7, 327745, -418, -419, -417, -130, -262205, -14, -420, -419, -262268, -16, -421, -420, -327745, -418, -423, 422, -130, +423, +421, +131, 262205, 14, 424, @@ -23935,1190 +24186,1211 @@ const std::vector local_constraints = {119734787, 16, 425, 424, -196670, -430, -421, -196670, -431, -425, -262205, -16, -433, +327745, +422, +427, 426, -196670, -432, -433, +131, 262205, 14, -435, +428, 427, +262268, +16, +429, +428, 196670, 434, +425, +196670, 435, +429, 262205, 16, 437, -428, +430, 196670, 436, 437, 262205, 14, 439, -429, +431, 196670, 438, 439, -655417, -2, -440, -57, -430, -431, -432, -434, -436, -438, 262205, 16, 441, 432, 196670, -426, +440, 441, 262205, 14, +443, +433, +196670, 442, +443, +655417, +2, +444, +57, 434, -196670, -427, +435, +436, +438, +440, 442, 262205, 16, -443, +445, 436, 196670, -428, -443, +430, +445, 262205, 14, -444, +446, 438, 196670, -429, -444, -196670, -445, +431, 446, 262205, -14, +16, 447, -429, +440, +196670, +432, +447, +262205, +14, +448, +442, +196670, +433, +448, +196670, +449, +450, +262205, +14, +451, +433, 327850, 9, -448, -447, -224, +452, +451, +228, 196855, -450, +454, 0, 262394, -448, -449, -455, -131320, -449, -327745, 452, 453, +459, +131320, +453, +327745, +456, +457, 92, -451, +455, 262205, 6, -454, -453, +458, +457, 196670, -445, -454, +449, +458, 131321, -450, +454, 131320, -455, +459, 262205, 14, -456, -429, +460, +433, 327850, 9, -457, -456, +461, +460, 81, 196855, -459, +463, 0, 262394, -457, -458, -463, +461, +462, +467, 131320, -458, +462, 327745, -452, -461, +456, +465, 92, -460, +464, 262205, 6, -462, -461, +466, +465, 196670, -445, -462, +449, +466, 131321, -459, -131320, 463, +131320, +467, 262205, 14, -464, -429, +468, +433, 327850, 9, -465, -464, +469, +468, 111, 196855, -467, +471, 0, 262394, -465, -466, -471, +469, +470, +475, 131320, -466, +470, 327745, -452, -469, +456, +473, 92, -468, +472, 262205, 6, -470, -469, +474, +473, 196670, -445, -470, +449, +474, 131321, -467, -131320, 471, +131320, +475, 262205, 14, -472, -429, +476, +433, 327850, 9, -473, -472, -130, +477, +476, +131, 196855, -475, +479, 0, 262394, -473, -474, -475, +477, +478, +479, 131320, -474, +478, 327745, -452, -477, +456, +481, 92, -476, +480, 262205, 6, -478, -477, +482, +481, 196670, -445, -478, +449, +482, 131321, -475, +479, 131320, -475, +479, 131321, -467, +471, 131320, -467, +471, 131321, -459, +463, 131320, -459, +463, 131321, -450, +454, 131320, -450, +454, 262205, 6, -479, -445, +483, +449, 458764, 6, -481, +485, 1, 37, -479, -480, +483, +484, 327813, 6, -482, -339, -481, +486, +343, +485, 196670, -445, -482, +449, +486, 196670, -483, -484, +487, +488, 196670, -485, -484, +489, +488, 131321, -486, +490, 131320, -486, +490, 262390, -488, -489, +492, +493, 0, 131321, -490, +494, 131320, -490, +494, 262205, 16, -491, -485, +495, +489, 262268, 14, -492, -491, +496, +495, 262205, 14, -493, -427, +497, +431, 327856, 9, -494, -492, -493, +498, +496, +497, 262394, -494, -487, -488, +498, +491, +492, 131320, -487, +491, 262205, 16, -495, -428, +499, +432, 262205, 16, -496, -485, +500, +489, 327808, 16, -497, -495, -496, +501, +499, +500, 196670, -483, -497, +487, +501, 262205, 16, -502, -485, +506, +489, 262205, 16, -507, -483, +511, +487, 393281, -508, -509, -506, -484, -507, +512, +513, +510, +488, +511, 262205, 7, -510, -509, +514, +513, 327745, 8, -511, -501, -502, +515, +505, +506, 196670, -511, -510, +515, +514, 131321, -489, +493, 131320, -489, +493, 262205, 16, -512, -485, +516, +489, 327808, 16, -514, -512, -513, +518, +516, +517, 196670, -485, -514, +489, +518, 131321, -486, +490, 131320, -488, +492, 196670, -515, -484, +519, +488, 131321, -516, +520, 131320, -516, +520, 262390, -518, -519, +522, +523, 0, 131321, -520, +524, 131320, -520, +524, 262205, 16, -521, -515, +525, +519, 327745, -523, -524, +527, +528, 92, -522, +526, 262205, 16, -525, -524, +529, +528, 327857, 9, -526, -521, +530, 525, +529, 262394, -526, -517, -518, +530, +521, +522, 131320, -517, +521, 327745, 8, -528, -501, -513, +532, +505, +517, 262205, 7, -529, -528, +533, +532, 196670, -527, -529, +531, +533, 262205, -532, -535, -534, +536, +539, +538, 262205, 16, -536, -428, +540, +432, +262244, +535, +541, +539, 327775, 7, -537, -535, -536, +542, +541, +540, 196670, -530, -537, +534, +542, 196670, -538, -513, +543, +517, 131321, -539, +544, 131320, -539, +544, 262390, -541, -542, +546, +547, 0, 131321, -543, +548, 131320, -543, +548, 262205, 16, -544, -538, +549, +543, 262268, 14, -545, -544, +550, +549, 262205, 14, -546, -427, +551, +431, 327810, 14, -547, -546, +552, +551, 111, 327856, 9, -548, -545, -547, +553, +550, +552, 262394, -548, -540, -541, +553, +545, +546, 131320, -540, +545, 262205, 16, -549, -428, +554, +432, 262205, 16, -550, -538, +555, +543, 327808, 16, -551, -549, -550, +556, +554, +555, 196670, -483, -551, +487, +556, 262205, 16, -553, -538, +558, +543, 327808, 16, -554, -553, -513, +559, +558, +517, 327745, 8, -555, -501, -554, +560, +505, +559, 262205, 7, -556, -555, +561, +560, 196670, -552, -556, +557, +561, 327745, -508, -564, -562, -513, +512, +569, +567, +517, 262205, 7, -565, -564, +570, +569, 196670, -563, -565, +568, +570, 262205, 7, -567, -530, +572, +534, 196670, -566, -567, +571, +572, 393273, 7, -568, +573, 62, -563, -566, -196670, -557, 568, -262205, -532, 571, -570, +196670, +562, +573, +262205, +536, +576, +575, 262205, 16, -572, -483, +577, +487, 327808, 16, -573, -572, -513, +578, +577, +517, +262244, +535, +579, +576, 327775, 7, -574, -571, -573, +580, +579, +578, 524367, 64, -575, -574, -574, -0, +581, +580, +580, +0, 1, 2, 196670, -569, -575, +574, +581, 262205, 7, -578, -557, +584, +562, 196670, -577, -578, +583, +584, 262205, 64, -580, -569, +586, +574, 196670, -579, -580, +585, +586, 393273, 64, -581, +587, 69, -577, -579, +583, +585, 262205, 7, -582, -527, +588, +531, 524367, 64, -583, -582, -582, +589, +588, +588, 0, 1, 2, 327809, 64, -584, -581, -583, +590, +587, +589, 196670, -576, -584, +582, +590, 262205, 6, -586, -445, +592, +449, 262205, 64, -587, -576, +593, +582, 262205, 7, -588, -552, +594, +557, 524367, 64, -589, -588, -588, +595, +594, +594, 0, 1, 2, 327811, 64, -590, -587, -589, +596, +593, +595, 327822, 64, -591, -590, -586, +597, +596, +592, 196670, -585, 591, +597, 262205, 7, -593, -527, +599, +531, 196670, -592, -593, +598, +599, 327737, 9, -594, +600, 12, -592, +598, 196855, -596, +602, 0, 262394, -594, -595, -596, +600, +601, +602, 131320, -595, +601, 262205, 64, -597, -585, +603, +591, 262205, 7, -598, -527, +604, +531, 524367, 64, -599, -598, -598, +605, +604, +604, 0, 1, 2, 327811, 64, -600, -599, -597, +606, +605, +603, 262205, 7, -601, -527, +607, +531, 589903, 7, -602, -601, -600, +608, +607, +606, 4, 5, 6, 3, 196670, -527, -602, +531, +608, 131321, -596, +602, 131320, -596, +602, 262205, 7, -604, -552, +610, +557, 196670, -603, -604, +609, +610, 327737, 9, -605, +611, 12, -603, +609, 196855, -607, +613, 0, 262394, -605, -606, -607, +611, +612, +613, 131320, -606, +612, 262205, 64, -608, -585, +614, +591, 262205, 7, -609, -552, +615, +557, 524367, 64, -610, -609, -609, +616, +615, +615, 0, 1, 2, 327809, 64, -611, -610, -608, +617, +616, +614, 262205, 7, -612, -552, +618, +557, 589903, 7, -613, -612, -611, +619, +618, +617, 4, 5, 6, 3, 196670, -552, -613, +557, +619, 131321, -607, +613, 131320, -607, +613, 262205, 7, -616, -557, +622, +562, 196670, -615, -616, +621, +622, 327737, 7, -617, +623, 79, -615, +621, 196670, -614, -617, +620, +623, 262205, 7, -619, -552, +625, +557, 524367, 64, -620, -619, -619, +626, +625, +625, 0, 1, 2, 262205, 7, -621, -527, +627, +531, 524367, 64, -622, -621, -621, +628, +627, +627, 0, 1, 2, 327811, 64, -623, -620, -622, +629, +626, +628, 393228, 64, -624, +630, 1, 69, -623, +629, 196670, -618, 624, +630, 262205, 7, -627, -614, +633, +620, 196670, -626, -627, +632, +633, 262205, 64, -629, -618, +635, +624, 196670, -628, -629, +634, +635, 393273, 64, -630, +636, 69, -626, -628, +632, +634, 393228, 64, -631, +637, 1, 69, -630, +636, 196670, -625, 631, +637, 196670, -632, -633, +638, +639, 262205, 64, -635, -632, +641, +638, 262205, 64, -636, -625, +642, +631, 458764, 64, -637, +643, 1, 68, -635, -636, +641, +642, 196670, -634, -637, +640, +643, 262205, 64, -638, -634, +644, +640, 393228, 6, -639, +645, 1, 66, -638, +644, 327866, 9, -640, -639, -382, +646, +645, +386, 196855, -642, +648, 0, 262394, -640, -641, -642, +646, +647, +648, 131320, -641, +647, 262205, 64, -644, -632, +650, +638, 262205, 64, -645, -625, +651, +631, 327828, 6, -646, -644, -645, +652, +650, +651, 393228, 6, -647, +653, 1, 17, -646, +652, 196670, -643, -647, +649, +653, 262205, 64, -648, -634, +654, +640, 393228, 64, -649, +655, 1, 69, -648, +654, 196670, -634, -649, +640, +655, 262205, 6, -652, -643, +658, +649, 196670, -651, -652, +657, +658, 262205, 64, -654, -634, +660, +640, 196670, -653, -654, +659, +660, 393273, 7, -655, +661, 75, -651, -653, +657, +659, 196670, -650, -655, +656, +661, 262205, 7, -657, -530, +663, +534, 196670, -656, -657, +662, +663, 262205, 7, -659, -650, +665, +656, 196670, -658, -659, +664, +665, 393273, 7, -660, +666, 62, -656, -658, +662, +664, 196670, -530, -660, +534, +666, 131321, -642, +648, 131320, -642, +648, 262205, 16, -661, -538, +667, +543, 262205, 7, -662, -527, +668, +531, 524367, 64, -663, -662, -662, +669, +668, +668, 0, 1, 2, 327745, 8, -664, -501, -661, +670, +505, +667, 262205, 7, -665, -664, +671, +670, 589903, 7, -666, -665, -663, +672, +671, +669, 4, 5, 6, 3, 196670, -664, -666, +670, +672, 262205, 16, -667, -538, +673, +543, 327808, 16, -668, -667, -513, +674, +673, +517, 262205, 7, -669, -552, +675, +557, 524367, 64, -670, -669, -669, +676, +675, +675, 0, 1, 2, 327745, 8, -671, -501, -668, +677, +505, +674, 262205, 7, -672, -671, +678, +677, 589903, 7, -673, -672, -670, +679, +678, +676, 4, 5, 6, 3, 196670, -671, -673, +677, +679, 262205, 7, -674, -552, +680, +557, 196670, -527, -674, +531, +680, 131321, -542, +547, 131320, -542, +547, 262205, 16, -675, -538, +681, +543, 327808, 16, -676, -675, -513, +682, +681, +517, 196670, -538, -676, +543, +682, 131321, -539, +544, 131320, -541, +546, 131321, -519, +523, 131320, -519, +523, 262205, 16, -677, -515, +683, +519, 327808, 16, -678, -677, -513, +684, +683, +517, 196670, -515, -678, +519, +684, 131321, -516, +520, 131320, -518, +522, 196670, -679, -484, +685, +488, 131321, -680, +686, 131320, -680, +686, 262390, -682, -683, +688, +689, 0, 131321, -684, +690, 131320, -684, +690, 262205, 16, +691, 685, -679, 262268, 14, -686, -685, +692, +691, 262205, 14, -687, -427, +693, +431, 327856, 9, -688, -686, -687, +694, +692, +693, 262394, +694, +687, 688, -681, -682, 131320, -681, +687, 262205, 16, -689, -428, +695, +432, 262205, 16, -690, -679, +696, +685, 327808, 16, -691, -689, -690, +697, +695, +696, 196670, -483, -691, +487, +697, 262205, 16, -692, -483, +698, +487, 262205, 16, -693, -679, +699, +685, 327745, 8, -694, -501, -693, +700, +505, +699, 262205, 7, -695, -694, +701, +700, 393281, -508, -696, -506, -484, -692, +512, +702, +510, +488, +698, 196670, -696, -695, +702, +701, 131321, -683, +689, 131320, -683, +689, 262205, 16, -697, -679, +703, +685, 327808, 16, -698, -697, -513, +704, +703, +517, 196670, -679, -698, +685, +704, 131321, -680, +686, 131320, -682, +688, 65789, 65592, 327734, @@ -25325,48 +25597,52 @@ const std::vector local_constraints = {119734787, 16, 127, 126, -327775, +262244, +121, 128, -129, 125, +327775, +129, +130, +128, 127, 327761, 14, -131, -129, +132, +130, 0, 196670, 27, -131, +132, 262205, 14, -132, +133, 21, 262205, 14, -133, +134, 25, 327812, 14, -134, -132, +135, 133, +134, 262205, 14, -135, +136, 24, 327808, 14, -136, -134, +137, 135, +136, 262268, 16, +138, 137, -136, 196670, 23, -137, +138, 65789, 65592, 327734, @@ -25405,163 +25681,167 @@ const std::vector local_constraints = {119734787, 40, 262205, 14, -138, +139, 30, 196670, 37, -138, +139, 327745, 94, -139, +140, 92, 93, 262205, 14, +141, 140, -139, 327814, 14, -141, +142, 89, -140, +141, 196670, 36, -141, +142, 262205, 14, -142, +143, 30, 327745, 94, -143, +144, 92, 93, 262205, 14, +145, 144, -143, 327817, 14, +146, +143, 145, -142, -144, 196670, 33, -145, +146, 262205, 14, -146, +147, 31, 327745, 94, -147, +148, 92, 93, 262205, 14, +149, 148, -147, 327812, 14, +150, +147, 149, -146, -148, 262205, 14, -150, +151, 33, 327808, 14, -151, -149, +152, 150, +151, 196670, 32, -151, +152, 262205, 14, -152, +153, 30, 262205, 14, -153, +154, 33, 327810, 14, -154, -152, +155, 153, +154, 327745, 94, -155, +156, 92, 93, 262205, 14, +157, 156, -155, 327814, 14, +158, +155, 157, -154, -156, 196670, 35, -157, +158, 262205, 122, -158, +159, 124, 262205, 14, -159, +160, 32, 262268, 16, +161, 160, +262244, +121, +162, 159, 327775, -128, +129, +163, +162, 161, -158, -160, 327761, 14, -162, -161, +164, +163, 0, 196670, 38, -162, +164, 262205, 14, -163, +165, 32, 262205, 14, -164, +166, 36, 327812, 14, +167, 165, -163, -164, +166, 262205, 14, -166, +168, 35, 327808, 14, +169, 167, -165, -166, +168, 262268, 16, -168, -167, +170, +169, 196670, 34, -168, +170, 65789, 65592, 327734, @@ -25591,83 +25871,87 @@ const std::vector local_constraints = {119734787, 49, 262205, 14, -169, +171, 43, 327812, 14, -170, +172, 89, -169, +171, 262205, 14, -171, +173, 42, 327808, 14, +174, 172, -170, -171, +173, 196670, 44, -172, +174, 327745, 94, -173, +175, 92, 93, 262205, 14, -174, -173, +176, +175, 327814, 14, -175, +177, 89, -174, +176, 196670, 45, -175, +177, 262205, 122, -176, +178, 124, 262205, 14, -177, +179, 44, 262268, 16, -178, -177, -327775, -128, +180, 179, -176, +262244, +121, +181, 178, +327775, +129, +182, +181, +180, 327761, 14, -180, -179, +183, +182, 0, 196670, 47, -180, +183, 262205, 14, -181, +184, 44, 262205, 14, -182, +185, 45, 327812, 14, -183, -181, -182, +186, +184, +185, 196670, 46, -183, +186, 65789, 65592, 327734, @@ -25697,113 +25981,117 @@ const std::vector local_constraints = {119734787, 58, 262205, 16, -185, +188, 52, 327812, 16, -186, -184, -185, +189, +187, +188, 262205, 16, -187, +190, 51, 327808, 16, -188, -186, -187, +191, +189, +190, 196670, 53, -188, +191, 327745, 94, -189, +192, 92, 108, 262205, 14, -190, -189, +193, +192, 327808, 14, -191, -190, +194, +193, 111, 262268, 16, -192, -191, +195, +194, 262205, 16, -193, +196, 53, 327812, 16, -194, -193, -192, +197, +196, +195, 196670, 53, -194, +197, 327745, 94, -195, +198, 92, 93, 262205, 14, -196, -195, +199, +198, 327814, 14, -197, +200, 89, -196, +199, 196670, 54, -197, +200, 262205, 122, -198, +201, 124, 262205, 16, -199, +202, 53, +262244, +121, +203, +201, 327775, -128, -200, -198, -199, +129, +204, +203, +202, 327761, 14, -201, -200, +205, +204, 0, 196670, 56, -201, +205, 262205, 16, -202, +206, 53, 262205, 14, -203, +207, 54, 262268, 16, -204, -203, +208, +207, 327812, 16, -205, -202, -204, +209, +206, +208, 196670, 55, -205, +209, 65789, 65592, 327734, @@ -25821,474 +26109,474 @@ const std::vector local_constraints = {119734787, 63, 262203, 8, -206, +210, 7, 327745, 71, -207, +211, 60, 81, 262205, 6, -208, -207, +212, +211, 327745, 71, -209, +213, 61, 81, 262205, 6, -210, -209, +214, +213, 327813, 6, -211, -208, -210, +215, +212, +214, 327745, 71, -212, +216, 60, -130, +131, 262205, 6, -213, -212, +217, +216, 327745, 71, -214, +218, 61, -130, +131, 262205, 6, -215, -214, +219, +218, 327813, 6, -216, -213, -215, +220, +217, +219, 327811, 6, -217, -211, -216, +221, +215, +220, 327745, 71, -218, +222, 60, 111, 262205, 6, -219, -218, +223, +222, 327745, 71, -220, +224, 61, 111, 262205, 6, -221, -220, +225, +224, 327813, 6, -222, -219, -221, +226, +223, +225, 327811, 6, -223, -217, -222, +227, +221, +226, 327745, 71, -225, +229, 60, -224, +228, 262205, 6, -226, -225, +230, +229, 327745, 71, -227, +231, 61, -224, +228, 262205, 6, -228, -227, +232, +231, 327813, 6, -229, -226, -228, +233, +230, +232, 327811, 6, -230, -223, -229, +234, +227, +233, 327745, 71, -231, -206, +235, +210, 81, 196670, -231, -230, +235, +234, 327745, 71, -232, +236, 60, 81, 262205, 6, -233, -232, +237, +236, 327745, 71, -234, +238, 61, -130, +131, 262205, 6, -235, -234, +239, +238, 327813, 6, -236, -233, -235, +240, +237, +239, 327745, 71, -237, +241, 60, -130, +131, 262205, 6, -238, -237, +242, +241, 327745, 71, -239, +243, 61, 81, 262205, 6, -240, -239, +244, +243, 327813, 6, -241, -238, -240, +245, +242, +244, 327809, 6, -242, -236, -241, +246, +240, +245, 327745, 71, -243, +247, 60, 111, 262205, 6, -244, -243, +248, +247, 327745, 71, -245, +249, 61, -224, +228, 262205, 6, -246, -245, +250, +249, 327813, 6, -247, -244, -246, +251, +248, +250, 327809, 6, -248, -242, -247, +252, +246, +251, 327745, 71, -249, +253, 60, -224, +228, 262205, 6, -250, -249, +254, +253, 327745, 71, -251, +255, 61, 111, 262205, 6, -252, -251, +256, +255, 327813, 6, -253, -250, -252, +257, +254, +256, 327811, 6, -254, -248, -253, +258, +252, +257, 327745, 71, -255, -206, -130, +259, +210, +131, 196670, -255, -254, +259, +258, 327745, 71, -256, +260, 60, 81, 262205, 6, -257, -256, +261, +260, 327745, 71, -258, +262, 61, 111, 262205, 6, -259, -258, +263, +262, 327813, 6, -260, -257, -259, +264, +261, +263, 327745, 71, -261, +265, 60, 111, 262205, 6, -262, -261, +266, +265, 327745, 71, -263, +267, 61, 81, 262205, 6, -264, -263, +268, +267, 327813, 6, -265, -262, -264, +269, +266, +268, 327809, 6, -266, -260, -265, +270, +264, +269, 327745, 71, -267, +271, 60, -224, +228, 262205, 6, -268, -267, +272, +271, 327745, 71, -269, +273, 61, -130, +131, 262205, 6, -270, -269, +274, +273, 327813, 6, -271, -268, -270, +275, +272, +274, 327809, 6, -272, -266, -271, +276, +270, +275, 327745, 71, -273, +277, 60, -130, +131, 262205, 6, -274, -273, +278, +277, 327745, 71, -275, +279, 61, -224, +228, 262205, 6, -276, -275, +280, +279, 327813, 6, -277, -274, -276, +281, +278, +280, 327811, 6, -278, -272, -277, +282, +276, +281, 327745, 71, -279, -206, +283, +210, 111, 196670, -279, -278, +283, +282, 327745, 71, -280, +284, 60, 81, 262205, 6, -281, -280, +285, +284, 327745, 71, -282, +286, 61, -224, +228, 262205, 6, -283, -282, +287, +286, 327813, 6, -284, -281, -283, +288, +285, +287, 327745, 71, -285, +289, 60, -224, +228, 262205, 6, -286, -285, +290, +289, 327745, 71, -287, +291, 61, 81, 262205, 6, -288, -287, +292, +291, 327813, 6, -289, -286, -288, -327809, -6, +293, 290, -284, -289, +292, +327809, +6, +294, +288, +293, 327745, 71, -291, +295, 60, -130, +131, 262205, 6, -292, -291, +296, +295, 327745, 71, -293, +297, 61, 111, 262205, 6, -294, -293, +298, +297, 327813, 6, -295, -292, -294, +299, +296, +298, 327809, 6, -296, -290, -295, +300, +294, +299, 327745, 71, -297, +301, 60, 111, 262205, 6, -298, -297, +302, +301, 327745, 71, -299, +303, 61, -130, +131, 262205, 6, -300, -299, +304, +303, 327813, 6, -301, -298, -300, +305, +302, +304, 327811, 6, -302, -296, -301, +306, +300, +305, 327745, 71, -303, -206, -224, +307, +210, +228, 196670, -303, -302, +307, +306, 262205, 7, -304, -206, +308, +210, 131326, -304, +308, 65592, 327734, 64, @@ -26305,150 +26593,150 @@ const std::vector local_constraints = {119734787, 70, 262203, 65, -307, +311, 7, 262203, 65, -315, +319, 7, 262203, 65, -319, +323, 7, 327745, 71, -308, +312, 67, -130, +131, 262205, 6, -309, -308, +313, +312, 327745, 71, -310, +314, 67, 111, 262205, 6, -311, -310, +315, +314, 327745, 71, -312, +316, 67, -224, +228, 262205, 6, -313, -312, +317, +316, 393296, 64, -314, -309, -311, +318, 313, +315, +317, 196670, -307, -314, +311, +318, 262205, 64, -316, -307, +320, +311, 262205, 64, -317, +321, 68, 458764, 64, -318, +322, 1, 68, -316, -317, +320, +321, 196670, -315, -318, +319, +322, 262205, 64, -320, -307, +324, +311, 262205, 64, -321, -315, +325, +319, 458764, 64, -322, +326, 1, 68, -320, -321, +324, +325, 196670, -319, -322, +323, +326, 327745, 71, -324, +328, 67, 81, 262205, 6, -325, -324, +329, +328, 327813, 6, -326, -323, -325, +330, +327, +329, 262205, 64, -327, -315, +331, +319, 327822, 64, -328, -327, -326, +332, +331, +330, 196670, -315, -328, +319, +332, 262205, 64, -329, -319, +333, +323, 327822, 64, -330, -329, -323, +334, +333, +327, 196670, -319, -330, +323, +334, 262205, 64, -331, +335, 68, 262205, 64, -332, -315, +336, +319, 327809, 64, -333, -331, -332, +337, +335, +336, 262205, 64, -334, -319, +338, +323, 327809, 64, -335, -333, -334, +339, +337, +338, 131326, -335, +339, 65592, 327734, 7, @@ -26465,94 +26753,94 @@ const std::vector local_constraints = {119734787, 76, 262203, 71, -338, +342, 7, 262203, 71, -342, +346, 7, 262203, 8, -345, +349, 7, 262205, 6, -340, +344, 73, 327813, 6, -341, -339, -340, +345, +343, +344, 196670, -338, -341, +342, +345, 262205, 6, -343, -338, +347, +342, 393228, 6, -344, +348, 1, 13, -343, +347, 196670, -342, -344, +346, +348, 262205, 6, -346, -338, +350, +342, 393228, 6, -347, +351, 1, 14, -346, +350, 327745, 71, -348, -345, +352, +349, 81, 196670, -348, -347, +352, +351, 262205, 6, -349, -342, +353, +346, 262205, 64, -350, +354, 74, 327822, 64, -351, -350, -349, +355, +354, +353, 262205, 7, -352, -345, +356, +349, 589903, 7, -353, -352, -351, +357, +356, +355, 4, 5, 6, 3, 196670, -345, -353, +349, +357, 262205, 7, -354, -345, +358, +349, 131326, -354, +358, 65592, 327734, 7, @@ -26566,268 +26854,268 @@ const std::vector local_constraints = {119734787, 80, 262203, 71, -357, +361, 7, 327745, 71, -358, +362, 78, -130, +131, 262205, 6, -359, -358, +363, +362, 327745, 71, -360, +364, 78, -130, +131, 262205, 6, -361, -360, +365, +364, 327813, 6, -362, -359, -361, +366, +363, +365, 327745, 71, -363, +367, 78, 111, 262205, 6, -364, -363, +368, +367, 327745, 71, -365, +369, 78, 111, 262205, 6, -366, -365, +370, +369, 327813, 6, -367, -364, -366, +371, +368, +370, 327809, 6, -368, -362, -367, +372, +366, +371, 327745, 71, -369, +373, 78, -224, +228, 262205, 6, -370, -369, +374, +373, 327745, 71, -371, +375, 78, -224, +228, 262205, 6, -372, -371, +376, +375, 327813, 6, -373, -370, -372, +377, +374, +376, 327809, 6, -374, -368, -373, +378, +372, +377, 327745, 71, -375, +379, 78, 81, 262205, 6, -376, -375, +380, +379, 327745, 71, -377, +381, 78, 81, 262205, 6, -378, -377, +382, +381, 327813, 6, -379, -376, -378, +383, +380, +382, 327809, 6, -380, -374, -379, +384, +378, +383, 196670, -357, -380, +361, +384, 262205, 6, -381, -357, +385, +361, 327864, 9, -383, -381, -382, -196855, +387, 385, +386, +196855, +389, 0, 262394, -383, -384, -385, +387, +388, +389, 131320, -384, +388, 131326, -387, +391, 131320, -385, +389, 327745, 71, -389, +393, 78, -130, +131, 262205, 6, -390, -389, +394, +393, 262271, 6, -391, -390, +395, +394, 262205, 6, -392, -357, +396, +361, 327816, 6, -393, -391, -392, +397, +395, +396, 327745, 71, -394, +398, 78, -130, +131, 196670, -394, -393, +398, +397, 327745, 71, -395, +399, 78, 111, 262205, 6, -396, -395, +400, +399, 262271, 6, -397, -396, +401, +400, 262205, 6, -398, -357, +402, +361, 327816, 6, -399, -397, -398, +403, +401, +402, 327745, 71, -400, +404, 78, 111, 196670, -400, -399, +404, +403, 327745, 71, -401, +405, 78, -224, +228, 262205, 6, -402, -401, +406, +405, 262271, 6, -403, -402, +407, +406, 262205, 6, -404, -357, +408, +361, 327816, 6, -405, -403, -404, +409, +407, +408, 327745, 71, -406, +410, 78, -224, +228, 196670, -406, -405, +410, +409, 327745, 71, -407, +411, 78, 81, 262205, 6, -408, -407, +412, +411, 262205, 6, -409, -357, +413, +361, 327816, 6, -410, -408, -409, +414, +412, +413, 327745, 71, -411, +415, 78, 81, 196670, -411, -410, +415, +414, 262205, 7, -412, +416, 78, 131326, -412, +416, 65592, }; -const std::vector length_wind_collision = {119734787, +const std::vector compute_tangents = {119734787, 65536, 524289, -582, +302, 0, 131089, 1, @@ -26847,8 +27135,8 @@ const std::vector length_wind_collision = {119734787, 4, 1852399981, 0, -279, -280, +191, +192, 393232, 4, 17, @@ -27129,84 +27417,33 @@ const std::vector length_wind_collision = {119734787, 1634890867, 2035573870, 25968, -655365, -63, -1936617283, -1767993972, -1968010350, -1885959276, -1919248748, -879130152, -879130171, -59, 327685, -61, -1953653104, -1701602153, -48, -327685, -62, -1953653104, -1701602153, -49, -786437, -71, -1819308097, -1936278649, -1668178292, -1852785509, -1634890867, -678719081, -993289846, -993289846, -1715155302, -15153, -262149, -67, -812871536, -0, -262149, -68, -829648752, -0, -393221, 69, -1735549300, -1766093925, -1851880563, -25955, -327685, -70, -1718187123, -1936027238, -115, -327685, -82, 1936617283, 1953390964, 115, 327686, -82, +69, 0, 1767333735, 25710, 327686, -82, +69, 1, 1767333735, 3236974, 327686, -82, +69, 2, 1767333735, 3302510, 327686, -82, +69, 3, 1767333735, 3368046, 720902, -82, +69, 4, 1968070503, 1852132461, @@ -27217,14 +27454,14 @@ const std::vector length_wind_collision = {119734787, 1769234802, 7564911, 458758, -82, +69, 5, 1130520423, 1768713327, 1852795251, 0, 524294, -82, +69, 6, 1917280103, 1953068641, @@ -27232,19 +27469,19 @@ const std::vector length_wind_collision = {119734787, 1970563438, 25956, 393222, -82, +69, 7, 1767137127, 1951622509, 28773, 393222, -82, +69, 8, 1631870823, 1852403821, 12391, 786438, -82, +69, 9, 1951620967, 1852204649, @@ -27256,7 +27493,7 @@ const std::vector length_wind_collision = {119734787, 1735289192, 48, 786438, -82, +69, 10, 1951620967, 1852204649, @@ -27268,7 +27505,7 @@ const std::vector length_wind_collision = {119734787, 1852401763, 12391, 851974, -82, +69, 11, 1816616807, 1818321519, @@ -27281,13 +27518,13 @@ const std::vector length_wind_collision = {119734787, 811951982, 0, 393222, -82, +69, 12, 1631870823, 1852403821, 12647, 786438, -82, +69, 13, 1951620967, 1852204649, @@ -27299,7 +27536,7 @@ const std::vector length_wind_collision = {119734787, 1735289192, 49, 786438, -82, +69, 14, 1951620967, 1852204649, @@ -27311,7 +27548,7 @@ const std::vector length_wind_collision = {119734787, 1852401763, 12647, 851974, -82, +69, 15, 1816616807, 1818321519, @@ -27324,13 +27561,13 @@ const std::vector length_wind_collision = {119734787, 828729198, 0, 393222, -82, +69, 16, 1631870823, 1852403821, 12903, 786438, -82, +69, 17, 1951620967, 1852204649, @@ -27342,7 +27579,7 @@ const std::vector length_wind_collision = {119734787, 1735289192, 50, 786438, -82, +69, 18, 1951620967, 1852204649, @@ -27354,7 +27591,7 @@ const std::vector length_wind_collision = {119734787, 1852401763, 12903, 851974, -82, +69, 19, 1816616807, 1818321519, @@ -27367,13 +27604,13 @@ const std::vector length_wind_collision = {119734787, 845506414, 0, 393222, -82, +69, 20, 1631870823, 1852403821, 13159, 786438, -82, +69, 21, 1951620967, 1852204649, @@ -27385,7 +27622,7 @@ const std::vector length_wind_collision = {119734787, 1735289192, 51, 786438, -82, +69, 22, 1951620967, 1852204649, @@ -27397,7 +27634,7 @@ const std::vector length_wind_collision = {119734787, 1852401763, 13159, 851974, -82, +69, 23, 1816616807, 1818321519, @@ -27410,7 +27647,7 @@ const std::vector length_wind_collision = {119734787, 862283630, 0, 720902, -82, +69, 24, 1968070503, 1399213933, @@ -27421,7 +27658,7 @@ const std::vector length_wind_collision = {119734787, 1886744434, 0, 720902, -82, +69, 25, 1968070503, 1819231853, @@ -27432,7 +27669,7 @@ const std::vector length_wind_collision = {119734787, 1919508808, 0, 589830, -82, +69, 26, 1767137127, 1885688688, @@ -27441,12 +27678,12 @@ const std::vector length_wind_collision = {119734787, 1869898593, 114, 327686, -82, +69, 27, 1466064743, 7369313, 786438, -82, +69, 28, 1968070503, 1668238445, @@ -27458,56 +27695,17 @@ const std::vector length_wind_collision = {119734787, 1852795252, 115, 196613, -84, +71, 0, 458757, -116, +103, 1632132967, 1951625833, 1684955506, 1701869908, 0, -262149, -198, -1634886000, -109, -262149, -203, -1634886000, -109, -262149, -216, -1634886000, -109, -262149, -229, -1953260900, -97, -327685, -235, -1953720676, -1701015137, -0, -327685, -240, -1701999731, -1768448884, -26478, -327685, -249, -1953265005, -1768714345, -29285, -262149, -250, -1634886000, -109, -262149, -252, -1634886000, -109, 524293, -279, +191, 1281322087, 1818321775, 1870032457, @@ -27515,41 +27713,41 @@ const std::vector length_wind_collision = {119734787, 1145663087, 0, 393221, -280, +192, 1465871463, 1198223983, 1886744434, 17481, 458757, -281, +193, 1651469415, 1951624289, 1684955506, 1701080649, 120, 458757, -282, +194, 1633906540, 1920226156, 1231318625, 2019910766, 0, 458757, -283, +195, 1651469415, 1700162657, 2019914866, 1701080649, 120, 458757, -284, +196, 1633906540, 1919243884, 1232627060, 2019910766, 0, 524293, -285, +197, 1450014062, 1769239141, 1232299363, @@ -27557,55 +27755,68 @@ const std::vector length_wind_collision = {119734787, 1634890835, 25710, 458757, -286, +198, 1701080681, 1919895160, 1918986323, 1699570789, 109, 327685, -287, +199, 1634890867, 2035573870, 25968, 262149, -288, +200, 1634886000, 109, 262149, -292, +204, 1634886000, 109, 262149, -295, +207, 1634886000, 109, 262149, -297, +209, 1634886000, 109, 262149, -299, +211, 1634886000, 109, 262149, -301, +213, 1634886000, 109, 262149, -303, +215, 1634886000, 109, 262149, -305, +217, 1634886000, 109, 262149, -307, +219, 1634886000, 109, +327685, +231, +1918986355, +1867539557, +115, +524293, +233, +1632132967, +1700164201, +2019914866, +1769172816, +1852795252, +115, 589829, -317, +242, 1332573550, 1920226150, 1935961697, @@ -27613,131 +27824,47 @@ const std::vector length_wind_collision = {119734787, 1634038376, 1869760356, 28789, -327685, -322, -1918986355, -1867539557, -115, +262149, +251, +1735287156, +7630437, 458757, -325, +264, 1953067639, 1818386789, 1936674917, 1869182057, 29550, 589830, -325, +264, 0, 1632132967, 1700164201, 2019914866, -1769172816, -1852795252, -115, +1735287124, +1937010277, +0, 196613, -327, +266, 0, 393221, -337, -1918986355, -1699505253, -1752459118, -0, -458757, -342, -1632132967, -1699902057, -1699509363, -1752459118, -5657171, -262149, -371, -1668444006, -101, -262149, -373, -1835102822, -101, -196613, -387, -97, -196613, -394, -119, -327685, -423, -1918986355, -1850303589, -7890276, -196613, -432, -118, -262149, -445, -1668444006, -101, -196613, -468, -97, -196613, -475, -98, -327685, -482, -1919251561, -1869182049, -17774, -327685, -494, -1918986355, -1850303589, -7890276, -262149, -516, -1634886000, -109, -262149, -519, -1634886000, -109, -262149, -522, -1634886000, -109, -262149, -525, -1634886000, -109, -262149, -550, -1634886000, -109, -262149, -553, -1634886000, -109, -262149, -556, -1634886000, -109, +276, +1953654134, +1834969439, +1937075817, +12639, 262149, -559, -1634886000, -109, -393221, -568, -1819231074, -1702126916, -1684370531, -0, +283, +1953654134, +26975, 393221, -578, +298, 1684104520, 1851880020, 1919903347, 109, 589830, -578, +298, 0, 1867341671, 1416389988, @@ -27746,7 +27873,7 @@ const std::vector length_wind_collision = {119734787, 1215459142, 6578533, 589830, -578, +298, 1, 1867341671, 1382835556, @@ -27755,7 +27882,7 @@ const std::vector length_wind_collision = {119734787, 1684104520, 0, 589830, -578, +298, 2, 1852396386, 1214606439, @@ -27764,259 +27891,259 @@ const std::vector length_wind_collision = {119734787, 1836216166, 0, 327686, -578, +298, 3, 1684300144, 6778473, 196613, -580, +300, 0, 327752, -82, +69, 0, 35, 0, 327752, -82, +69, 1, 35, 16, 327752, -82, +69, 2, 35, 32, 327752, -82, +69, 3, 35, 48, 327752, -82, +69, 4, 35, 64, 327752, -82, +69, 5, 35, 68, 327752, -82, +69, 6, 35, 72, 327752, -82, +69, 7, 35, 76, 327752, -82, +69, 8, 35, 80, 327752, -82, +69, 9, 35, 84, 327752, -82, +69, 10, 35, 88, 327752, -82, +69, 11, 35, 92, 327752, -82, +69, 12, 35, 96, 327752, -82, +69, 13, 35, 100, 327752, -82, +69, 14, 35, 104, 327752, -82, +69, 15, 35, 108, 327752, -82, +69, 16, 35, 112, 327752, -82, +69, 17, 35, 116, 327752, -82, +69, 18, 35, 120, 327752, -82, +69, 19, 35, 124, 327752, -82, +69, 20, 35, 128, 327752, -82, +69, 21, 35, 132, 327752, -82, +69, 22, 35, 136, 327752, -82, +69, 23, 35, 140, 327752, -82, +69, 24, 35, 144, 327752, -82, +69, 25, 35, 148, 327752, -82, +69, 26, 35, 152, 327752, -82, +69, 27, 35, 156, 327752, -82, +69, 28, 35, 160, 196679, -82, +69, 3, 262215, -84, +71, 34, 0, 262215, -84, +71, 33, 16, 262215, -116, +103, 34, 1, 262215, -116, +103, 33, 22, 262215, -279, +191, 11, 27, 262215, -280, +192, 11, 26, 262215, -324, +233, +34, +1, +262215, +233, +33, +7, +262215, +263, 6, 16, 327752, -325, +264, 0, 35, 0, 196679, -325, +264, 3, 262215, -327, -34, -1, -262215, -327, -33, -7, -262215, -342, +266, 34, 1, 262215, -342, +266, 33, -26, +8, 262215, -577, +297, 6, 16, 262216, -578, +298, 0, 5, 327752, -578, +298, 0, 35, 0, 327752, -578, +298, 0, 7, 16, 327752, -578, +298, 1, 35, 64, 327752, -578, +298, 2, 35, 80, 327752, -578, +298, 3, 35, 96, 196679, -578, +298, 3, 262215, -580, +300, 34, 0, 262215, -580, +300, 33, 27, 262215, -581, +301, 11, 25, 131091, @@ -28087,40 +28214,24 @@ const std::vector length_wind_collision = {119734787, 15, 17, 15, -262167, -59, -6, -2, -327713, -60, +262187, +14, 59, -8, -8, +3, 262176, -65, +60, 7, 6, -458785, -66, -2, -8, -8, -65, -65, -262187, -14, -73, -3, 262187, 6, -76, +63, 0, 262187, 14, -81, +68, 64, 2031646, -82, +69, 7, 7, 7, @@ -28151,31 +28262,31 @@ const std::vector length_wind_collision = {119734787, 16, 16, 262176, -83, +70, 2, -82, +69, 262203, -83, -84, +70, +71, 2, 262187, 16, -85, +72, 24, 262176, -86, +73, 2, 14, 262187, 16, -100, +87, 25, 262187, 14, -103, +90, 1, 589849, -113, +100, 14, 5, 0, @@ -28184,256 +28295,130 @@ const std::vector length_wind_collision = {119734787, 1, 0, 196635, -114, -113, +101, +100, 262176, -115, +102, 0, -114, +101, 262203, -115, -116, +102, +103, 0, 262167, -120, +108, 14, 4, 262187, 14, -122, +110, 0, 262187, 16, -176, +166, 64, -262187, -6, -208, -1056964608, -327724, -59, -209, -208, -208, -262187, -6, -212, -1065353216, -327724, -59, -213, -212, -76, -327724, -59, -221, -76, -212, -327724, -59, -224, -76, -76, -262167, -227, -6, -3, -262176, -228, -7, -227, -262187, -6, -238, -869711765, -262176, -248, -7, -59, 262167, -277, +189, 14, 3, 262176, -278, +190, 1, -277, +189, 262203, -278, -279, +190, +191, 1, 262203, -278, -280, +190, +192, 1, 262176, -289, +201, 1, 14, 262172, -320, +229, 7, -81, +68, 262176, -321, +230, 4, -320, +229, 262203, -321, -322, +230, +231, 4, -196637, -324, -7, -196638, -325, -324, -262176, -326, -2, -325, 262203, -326, -327, -2, -262187, -16, -328, +102, +233, 0, 262176, -330, -2, -7, -262176, -333, +239, 4, 7, -262172, -335, -6, -81, -262176, -336, -4, -335, -262203, -336, -337, -4, -589849, -339, -6, -5, -0, -0, -0, -1, -0, -196635, -340, -339, -262176, -341, -0, -340, -262203, -341, -342, -0, -262176, -347, -4, -6, -262187, -14, -349, -4062, -262176, -350, -2, -6, 262187, 14, -364, +241, 2, -458796, -7, -372, -76, -76, -76, -76, -262187, -14, -389, -20, -262187, +262167, +249, 6, -392, -1101004800, -262187, -16, -402, -1, -262187, -16, -409, -2, -262187, -16, -417, 3, -262187, -16, -454, +262176, +250, 7, -262187, -6, -471, -1073741824, -262187, -16, -489, -4, +249, +196637, +263, +7, +196638, +264, +263, 262176, -490, +265, 2, +264, +262203, +265, +266, +2, +262187, 16, +267, +0, 262176, -567, +271, +2, 7, -9, -196650, -9, -569, 262168, -576, +296, 7, 4, 262172, -577, +297, 6, -73, +59, 393246, -578, -576, +298, +296, 7, 16, -577, +297, 262176, -579, +299, 2, -578, +298, 262203, -579, -580, +299, +300, 2, 393260, -277, -581, -81, -103, -103, +189, +301, +68, +90, +90, 327734, 2, 4, @@ -28443,1843 +28428,942 @@ const std::vector length_wind_collision = {119734787, 5, 262203, 15, -281, +193, 7, 262203, 15, -282, +194, 7, 262203, 17, -283, +195, 7, 262203, 15, -284, +196, 7, 262203, 15, -285, +197, 7, 262203, 15, -286, +198, 7, 262203, 15, -287, +199, 7, 262203, 15, -288, +200, 7, 262203, 15, -292, +204, 7, 262203, 15, -295, +207, 7, 262203, 15, -297, +209, 7, 262203, 17, -299, +211, 7, 262203, 15, -301, +213, 7, 262203, 15, -303, +215, 7, 262203, 15, -305, +217, 7, 262203, 15, -307, +219, 7, 262203, 15, -317, -7, -262203, -8, -371, -7, -262203, -65, -373, -7, -262203, -65, -387, -7, -262203, -228, -394, -7, -262203, -17, -423, -7, -262203, -228, -432, -7, -262203, -228, -445, -7, -262203, -17, -468, -7, -262203, -17, -475, -7, -262203, -17, -482, -7, -262203, -17, -494, -7, -262203, -8, -516, -7, -262203, -8, -519, -7, -262203, -65, -522, -7, -262203, -65, -525, -7, -262203, -8, -550, -7, -262203, -8, -553, +242, 7, 262203, -65, -556, +250, +251, 7, 262203, -65, -559, +250, +276, 7, 262203, -567, -568, +250, +283, 7, 327745, -289, -290, -279, -122, +201, +202, +191, +110, 262205, 14, -291, -290, +203, +202, 196670, -288, -291, +200, +203, 327745, -289, -293, -280, -122, +201, +205, +192, +110, 262205, 14, -294, -293, +206, +205, 196670, -292, -294, +204, +206, 262205, 14, -296, -281, +208, +193, 196670, -295, -296, +207, +208, 262205, 14, -298, -282, +210, +194, 196670, -297, -298, +209, +210, 262205, 16, -300, -283, +212, +195, 196670, -299, -300, +211, +212, 262205, 14, -302, -284, +214, +196, 196670, -301, -302, +213, +214, 262205, 14, -304, -285, +216, +197, 196670, -303, -304, +215, +216, 262205, 14, -306, -286, +218, +198, 196670, -305, -306, +217, +218, 262205, 14, -308, -287, +220, +199, 196670, -307, -308, +219, +220, 852025, 2, -309, -28, -288, -292, -295, -297, -299, -301, -303, -305, -307, +221, +39, +200, +204, +207, +209, +211, +213, +215, +217, +219, 262205, 14, -310, -295, +222, +207, 196670, -281, -310, +193, +222, 262205, 14, -311, -297, +223, +209, 196670, -282, -311, +194, +223, 262205, 16, -312, -299, -196670, -283, -312, -262205, -14, -313, -301, -196670, -284, -313, -262205, -14, -314, -303, +224, +211, 196670, -285, -314, +195, +224, 262205, 14, -315, -305, +225, +213, 196670, -286, -315, +196, +225, 262205, 14, -316, -307, +226, +215, 196670, -287, -316, -327745, -86, -318, -84, -85, +197, +226, 262205, 14, -319, -318, +227, +217, 196670, -317, -319, +198, +227, 262205, 14, -323, -286, -262205, -16, -329, -283, -393281, -330, -331, -327, -328, -329, -262205, -7, -332, -331, -327745, -333, -334, -322, -323, +228, +219, 196670, -334, -332, +199, +228, 262205, 14, -338, -286, +232, +198, 262205, -340, -343, -342, +101, +234, +233, 262205, 16, -344, -283, +235, +195, +262244, +100, +236, +234, 327775, +108, +237, +236, +235, +262256, 7, -345, -343, -344, -327761, -6, -346, -345, -0, +238, +237, 327745, -347, -348, -337, -338, +239, +240, +231, +232, 196670, -348, -346, -196833, -103, -349, +240, +238, 262368, -103, -103, -122, -393281, -350, -351, -84, -328, -122, -262205, -6, -352, -351, -327862, -9, -353, -352, -76, -262312, -9, -354, -353, -196855, -356, -0, -262394, -354, -355, -356, -131320, -355, -393281, -350, -357, -84, -328, -103, -262205, -6, -358, -357, -327862, -9, -359, -358, -76, -131321, -356, -131320, -356, -458997, -9, -360, -353, -5, -359, -355, -262312, -9, -361, -360, -196855, -363, -0, -262394, -361, -362, -363, -131320, -362, -393281, -350, -365, -84, -328, -364, -262205, -6, -366, -365, -327862, -9, -367, -366, -76, -131321, -363, -131320, -363, -458997, -9, -368, -360, -356, -367, -362, -196855, -370, -0, -262394, -368, -369, -370, -131320, -369, -196670, -371, -372, -393281, -350, -374, -84, -328, +241, +90, +110, +327745, 73, +243, +71, +72, 262205, -6, -375, -374, +14, +244, +243, 196670, -373, -375, +242, +244, 262205, 14, -376, -284, -327854, +245, +196, +327850, 9, -377, -376, -364, +246, +245, +110, 196855, -379, +248, 0, 262394, -377, -378, -379, +246, +247, +275, 131320, -378, -262205, -14, -380, -284, +247, 262205, 14, -381, -285, -327810, -14, -382, -381, -103, -327856, -9, -383, -380, -382, -131321, -379, -131320, -379, -458997, -9, -384, -377, -369, -383, -378, -196855, -386, -0, -262394, -384, -385, -386, -131320, -385, +252, +198, 262205, 14, -388, -281, -327817, +253, +242, +327808, 14, -390, -388, -389, -262256, -6, -391, -390, -327816, -6, -393, -391, -392, -196670, -387, -393, -262205, -6, -395, -387, +254, +252, +253, 327745, -330, -396, -84, -328, +239, +255, +231, +254, 262205, 7, -397, -396, +256, +255, 524367, -227, -398, -397, -397, +249, +257, +256, +256, 0, 1, 2, -327822, -227, -399, -398, -395, 262205, -6, -400, -387, -327811, -6, -401, -212, -400, +14, +258, +198, 327745, -330, -403, -84, -402, +239, +259, +231, +258, 262205, 7, -404, -403, +260, +259, 524367, -227, -405, -404, -404, +249, +261, +260, +260, 0, 1, 2, -327822, -227, -406, -405, -401, -327809, -227, -407, -399, -406, +327811, +249, +262, +257, +261, +196670, +251, +262, +262205, +16, +268, +195, +262205, +249, +269, +251, +393228, +249, +270, +1, +69, +269, +393281, +271, +272, +266, +267, +268, 262205, +7, +273, +272, +589903, +7, +274, +273, +270, +4, +5, 6, -408, -387, +3, +196670, +272, +274, +131321, +248, +131320, +275, +262205, +14, +277, +198, +262205, +14, +278, +242, +327810, +14, +279, +277, +278, 327745, -330, -410, -84, -409, +239, +280, +231, +279, 262205, 7, -411, -410, +281, +280, 524367, -227, -412, -411, -411, -0, -1, -2, -327822, -227, -413, -412, -408, -327809, -227, -414, -407, -413, -262205, -6, -415, -387, -327811, -6, -416, -212, -415, -327745, -330, -418, -84, -417, -262205, -7, -419, -418, -524367, -227, -420, -419, -419, +249, +282, +281, +281, 0, 1, 2, -327822, -227, -421, -420, -416, -327809, -227, -422, -414, -421, 196670, -394, -422, -262205, -14, -424, -284, -262268, -16, -425, -424, -262205, -14, -426, -317, -262268, -16, -427, -426, -327812, -16, -428, -425, -427, -262205, -14, -429, +276, 282, -262268, -16, -430, -429, -327808, -16, -431, -428, -430, -196670, -423, -431, -262205, -16, -433, -423, -327745, -333, -434, -322, -433, -262205, -7, -435, -434, -524367, -227, -436, -435, -435, -0, -1, -2, -262205, -16, -437, -423, -262268, -14, -438, -437, 262205, 14, -439, -317, -327808, -14, -440, -438, -439, +284, +198, 327745, -333, -441, -322, -440, +239, +285, +231, +284, 262205, 7, -442, -441, +286, +285, 524367, -227, -443, -442, -442, +249, +287, +286, +286, 0, 1, 2, -327811, -227, -444, -436, -443, -196670, -432, -444, -262205, -227, -446, -432, -262205, -227, -447, -394, -458764, -227, -448, -1, -68, -446, -447, -262205, -227, -449, -432, -458764, -227, -450, -1, -68, -448, -449, -262271, -227, -451, -450, 196670, -445, -451, +283, +287, 262205, 16, -452, -423, -262205, -227, -453, -445, -327745, -350, -455, -84, -454, -262205, -6, -456, -455, -327822, -227, -457, -453, -456, -327745, -350, -458, -84, -454, +288, +195, 262205, -6, -459, -458, -327822, -227, -460, -457, -459, -327745, -333, -461, -322, -452, +249, +289, +283, 262205, -7, -462, -461, -524367, -227, -463, -462, -462, -0, +249, +290, +276, +327811, +249, +291, +289, +290, +393228, +249, +292, 1, -2, -327809, -227, -464, -463, -460, -327745, -333, -465, -322, -452, +69, +291, +393281, +271, +293, +266, +267, +288, 262205, 7, -466, -465, +294, +293, 589903, 7, -467, -466, -464, +295, +294, +292, 4, 5, 6, 3, 196670, -465, -467, -131321, -386, -131320, -386, -131321, -370, -131320, -370, -196833, -103, -349, -262368, -103, -103, -122, -262205, -14, -469, -285, -262256, -6, -470, -469, -327816, -6, -472, -470, -471, -393228, -6, -473, -1, -8, -472, -262254, -16, -474, -473, -196670, -468, -474, -262205, -14, -476, -285, -262256, -6, -477, -476, -327811, -6, -478, -477, -212, -327816, -6, -479, -478, -471, -393228, -6, -480, -1, -8, -479, -262254, -16, -481, -480, -196670, -475, -481, -196670, -482, -328, +293, +295, 131321, -483, +248, 131320, -483, -262390, -485, -486, +248, +65789, +65592, +327734, +9, +12, 0, -131321, -487, +10, +196663, +8, +11, 131320, -487, -262205, -16, -488, -482, +13, 327745, -490, -491, -84, -489, +60, +61, +11, +59, 262205, -16, -492, -491, -327857, +6, +62, +61, +327866, 9, -493, -488, -492, -262394, -493, -484, -485, +64, +62, +63, +131326, +64, +65592, +327734, +2, +28, +0, +18, +196663, +15, +19, +196663, +15, +20, +196663, +15, +21, +196663, +15, +22, +196663, +17, +23, +196663, +15, +24, +196663, +15, +25, +196663, +15, +26, +196663, +15, +27, 131320, -484, +29, 262205, 14, -495, -284, -262268, -16, -496, -495, -327812, -16, -497, -409, -496, +67, +19, +196670, +26, +67, +327745, +73, +74, +71, +72, 262205, 14, -498, -317, -262268, -16, -499, -498, -327812, -16, -500, -497, -499, -262205, +75, +74, +327814, 14, -501, -282, -262268, -16, -502, -501, -327808, -16, -503, -500, -502, +76, +68, +75, 196670, -494, -503, +25, +76, 262205, 14, -504, -284, -262205, -16, -505, -468, -262268, -14, -506, -505, -327856, -9, -507, -504, -506, -196855, -509, -0, -262394, -507, -508, -509, -131320, -508, -262205, -16, -510, -494, -262205, -16, -511, -494, -262268, -14, -512, -511, +77, +19, +327745, +73, +78, +71, +72, 262205, 14, -513, -317, -327808, +79, +78, +327817, 14, -514, -512, -513, -262205, -16, -515, -494, -327745, -333, -517, -322, -510, -262205, -7, -518, -517, +80, +77, +79, 196670, -516, -518, -327745, -333, -520, -322, -514, +22, +80, 262205, -7, -521, -520, -196670, -519, -521, +14, +81, +20, 327745, -347, -523, -337, -515, -262205, -6, -524, -523, -196670, -522, -524, -196670, -525, -212, -524345, -2, -526, +73, +82, 71, -516, -519, -522, -525, -262205, -7, -527, -516, -327745, -333, -528, -322, -510, -196670, -528, -527, -262205, -7, -529, -519, -327745, -333, -530, -322, -514, -196670, -530, -529, -131321, -509, -131320, -509, -196833, -103, -349, -262368, -103, -103, -122, -262205, -14, -531, -284, +72, 262205, -16, -532, -475, -262268, 14, -533, -532, -327856, -9, -534, -531, -533, -196855, -536, -0, -262394, -534, -535, -536, -131320, -535, -262205, -16, -537, -494, -262268, +83, +82, +327812, 14, -538, -537, +84, +81, +83, 262205, 14, -539, -317, +85, +22, 327808, 14, -540, -538, -539, +86, +84, +85, +196670, +21, +86, +327745, +73, +88, +71, +87, 262205, -16, -541, -494, -262268, 14, -542, -541, +89, +88, +327808, +14, +91, +89, +90, 262205, 14, -543, -317, +92, +21, 327812, 14, -544, -543, -364, -327808, -14, -545, -542, -544, +93, +92, +91, +196670, +21, +93, 262205, -16, -546, -494, -262268, 14, -547, -546, +94, +19, 262205, 14, -548, -317, -327808, +95, +22, +327810, 14, -549, -547, -548, -327745, -333, -551, -322, -540, -262205, -7, -552, -551, -196670, -550, -552, -327745, -333, -554, -322, -545, -262205, -7, -555, -554, -196670, -553, -555, +96, +94, +95, 327745, -347, -557, -337, -549, -262205, -6, -558, -557, -196670, -556, -558, -196670, -559, -212, -524345, -2, -560, +73, +97, 71, -550, -553, -556, -559, +72, 262205, -7, -561, -550, -327745, -333, -562, -322, -540, +14, +98, +97, +327814, +14, +99, +96, +98, 196670, -562, -561, +24, +99, 262205, -7, -563, -553, -327745, -333, -564, -322, -545, -196670, -564, -563, -131321, -536, -131320, -536, -196833, -103, -349, -262368, -103, +101, +104, 103, -122, -131321, -486, -131320, -486, 262205, +14, +105, +21, +262268, 16, -565, -482, -327808, -16, -566, -565, -402, -196670, -482, -566, -131321, -483, -131320, -485, +106, +105, +262244, +100, +107, +104, +327775, +108, +109, +107, +106, +327761, +14, +111, +109, +0, 196670, -568, -569, +27, +111, 262205, -16, -570, -283, +14, +112, +21, 262205, 14, -571, -286, -327745, -333, -572, -322, -571, +113, +25, +327812, +14, +114, +112, +113, 262205, -7, -573, -572, -393281, -330, -574, -327, -328, -570, +14, +115, +24, +327808, +14, +116, +114, +115, +262268, +16, +117, +116, 196670, -574, -573, +23, +117, 65789, 65592, 327734, -9, -12, -0, -10, -196663, -8, -11, -131320, -13, -327745, -65, -74, -11, -73, -262205, -6, -75, -74, -327866, -9, -77, -75, -76, -131326, -77, -65592, -327734, 2, -28, +39, 0, 18, 196663, 15, -19, +30, 196663, 15, -20, +31, 196663, 15, -21, +32, 196663, 15, -22, +33, 196663, 17, -23, +34, 196663, 15, -24, +35, 196663, 15, -25, +36, 196663, 15, -26, +37, 196663, 15, -27, +38, 131320, -29, +40, 262205, 14, -80, -19, +118, +30, 196670, -26, -80, +37, +118, 327745, -86, -87, -84, -85, +73, +119, +71, +72, 262205, 14, -88, -87, +120, +119, 327814, 14, -89, -81, -88, +121, +68, +120, 196670, -25, -89, +36, +121, 262205, 14, -90, -19, +122, +30, 327745, -86, -91, -84, -85, +73, +123, +71, +72, 262205, 14, -92, -91, +124, +123, 327817, 14, -93, -90, -92, -196670, -22, -93, -262205, -14, -94, -20, -327745, -86, -95, -84, -85, -262205, -14, -96, -95, -327812, -14, -97, -94, -96, -262205, -14, -98, -22, -327808, -14, -99, -97, -98, -196670, -21, -99, -327745, -86, -101, -84, -100, -262205, -14, -102, -101, -327808, -14, -104, -102, -103, -262205, -14, -105, -21, -327812, -14, -106, -105, -104, +125, +122, +124, 196670, -21, -106, -262205, -14, -107, -19, +33, +125, 262205, 14, -108, -22, -327810, -14, -109, -107, -108, +126, +31, 327745, -86, -110, -84, -85, -262205, -14, -111, -110, -327814, -14, -112, -109, -111, -196670, -24, -112, -262205, -114, -117, -116, -262205, -14, -118, -21, -262268, -16, -119, -118, -327775, -120, -121, -117, -119, -327761, -14, -123, -121, -0, -196670, -27, -123, -262205, -14, -124, -21, +73, +127, +71, +72, 262205, 14, -125, -25, +128, +127, 327812, 14, +129, 126, -124, -125, +128, 262205, 14, -127, -24, +130, +33, 327808, 14, -128, -126, -127, -262268, -16, -129, -128, -196670, -23, +131, 129, -65789, -65592, -327734, -2, -39, -0, -18, -196663, -15, -30, -196663, -15, -31, -196663, -15, -32, -196663, -15, -33, -196663, -17, -34, -196663, -15, -35, -196663, -15, -36, -196663, -15, -37, -196663, -15, -38, -131320, -40, -262205, -14, 130, -30, 196670, -37, -130, -327745, -86, +32, 131, -84, -85, 262205, 14, 132, -131, -327814, +30, +262205, 14, 133, -81, -132, -196670, -36, -133, -262205, +33, +327810, 14, 134, -30, +132, +133, 327745, -86, +73, 135, -84, -85, +71, +72, 262205, 14, 136, 135, -327817, +327814, 14, 137, 134, 136, 196670, -33, +35, 137, 262205, -14, +101, 138, -31, -327745, -86, -139, -84, -85, +103, 262205, 14, +139, +32, +262268, +16, 140, 139, -327812, -14, +262244, +100, 141, 138, -140, -262205, -14, +327775, +108, 142, -33, -327808, +141, +140, +327761, 14, 143, -141, 142, +0, 196670, -32, +38, 143, 262205, 14, 144, -30, +32, 262205, 14, 145, -33, -327810, +36, +327812, 14, 146, 144, 145, -327745, -86, -147, -84, -85, 262205, 14, -148, 147, -327814, -14, -149, -146, -148, -196670, -35, -149, -262205, -114, -150, -116, -262205, -14, -151, -32, -262268, -16, -152, -151, -327775, -120, -153, -150, -152, -327761, -14, -154, -153, -0, -196670, -38, -154, -262205, -14, -155, -32, -262205, -14, -156, -36, -327812, -14, -157, -155, -156, -262205, -14, -158, 35, 327808, 14, -159, -157, -158, +148, +146, +147, 262268, 16, -160, -159, +149, +148, 196670, 34, -160, +149, 65789, 65592, 327734, @@ -30309,83 +29393,87 @@ const std::vector length_wind_collision = {119734787, 49, 262205, 14, -161, +150, 43, 327812, 14, -162, -81, -161, +151, +68, +150, 262205, 14, -163, +152, 42, 327808, 14, -164, -162, -163, +153, +151, +152, 196670, 44, -164, +153, 327745, -86, -165, -84, -85, +73, +154, +71, +72, 262205, 14, -166, -165, +155, +154, 327814, 14, -167, -81, -166, +156, +68, +155, 196670, 45, -167, +156, 262205, -114, -168, -116, +101, +157, +103, 262205, 14, -169, +158, 44, 262268, 16, -170, -169, +159, +158, +262244, +100, +160, +157, 327775, -120, -171, -168, -170, +108, +161, +160, +159, 327761, 14, -172, -171, +162, +161, 0, 196670, 47, -172, +162, 262205, 14, -173, +163, 44, 262205, 14, -174, +164, 45, 327812, 14, -175, -173, -174, +165, +163, +164, 196670, 46, -175, +165, 65789, 65592, 327734, @@ -30415,515 +29503,124 @@ const std::vector length_wind_collision = {119734787, 58, 262205, 16, -177, +167, 52, 327812, 16, -178, -176, -177, +168, +166, +167, 262205, 16, -179, +169, 51, 327808, 16, -180, -178, -179, +170, +168, +169, 196670, 53, -180, +170, 327745, -86, -181, -84, -100, +73, +171, +71, +87, 262205, 14, -182, -181, +172, +171, 327808, 14, -183, -182, -103, +173, +172, +90, 262268, 16, -184, -183, +174, +173, 262205, 16, -185, +175, 53, 327812, 16, -186, -185, -184, +176, +175, +174, 196670, 53, -186, +176, 327745, -86, -187, -84, -85, +73, +177, +71, +72, 262205, 14, -188, -187, +178, +177, 327814, 14, -189, -81, -188, +179, +68, +178, 196670, 54, -189, +179, 262205, -114, -190, -116, +101, +180, +103, 262205, 16, -191, +181, 53, +262244, +100, +182, +180, 327775, -120, -192, -190, -191, +108, +183, +182, +181, 327761, 14, -193, -192, +184, +183, 0, 196670, 56, -193, +184, 262205, 16, -194, +185, 53, 262205, 14, -195, +186, 54, 262268, 16, -196, -195, +187, +186, 327812, 16, -197, -194, -196, +188, +185, +187, 196670, 55, -197, -65789, -65592, -327734, -59, -63, -0, -60, -196663, -8, -61, -196663, -8, -62, -131320, -64, -262203, -8, -198, -7, -262203, -8, -203, -7, -262203, -8, -216, -7, -262205, -7, -199, -61, -196670, -198, -199, -327737, -9, -200, -12, -198, -196855, -202, -0, -262394, -200, -201, -215, -131320, -201, -262205, -7, -204, -62, -196670, -203, -204, -327737, -9, -205, -12, -203, -196855, -207, -0, -262394, -205, -206, -211, -131320, -206, -131326, -209, -131320, -211, -131326, -213, -131320, -207, -131321, -202, -131320, -215, -262205, -7, -217, -62, -196670, -216, -217, -327737, -9, -218, -12, -216, -196855, -220, -0, -262394, -218, -219, -223, -131320, -219, -131326, -221, -131320, -223, -131326, -224, -131320, -220, -131321, -202, -131320, -202, -196609, -59, -226, -131326, -226, -65592, -327734, -2, -71, -0, -66, -196663, -8, -67, -196663, -8, -68, -196663, -65, -69, -196663, -65, -70, -131320, -72, -262203, -228, -229, -7, -262203, -65, -235, -7, -262203, -65, -240, -7, -262203, -248, -249, -7, -262203, -8, -250, -7, -262203, -8, -252, -7, -262205, -7, -230, -68, -524367, -227, -231, -230, -230, -0, -1, -2, -262205, -7, -232, -67, -524367, -227, -233, -232, -232, -0, -1, -2, -327811, -227, -234, -231, -233, -196670, -229, -234, -262205, -227, -236, -229, -393228, -6, -237, -1, -66, -236, -458764, -6, -239, -1, -40, -237, -238, -196670, -235, -239, -262205, -6, -241, -69, -262205, -6, -242, -235, -327816, -6, -243, -241, -242, -327811, -6, -244, -212, -243, -196670, -240, -244, -262205, -6, -245, -240, -262205, -227, -246, -229, -327822, -227, -247, -246, -245, -196670, -229, -247, -262205, -7, -251, -67, -196670, -250, -251, -262205, -7, -253, -68, -196670, -252, -253, -393273, -59, -254, -63, -250, -252, -196670, -249, -254, -327745, -65, -255, -249, -122, -262205, -6, -256, -255, -262205, -227, -257, -229, -327822, -227, -258, -257, -256, -262205, -6, -259, -70, -327822, -227, -260, -258, -259, -262205, -7, -261, -67, -524367, -227, -262, -261, -261, -0, -1, -2, -327809, -227, -263, -262, -260, -262205, -7, -264, -67, -589903, -7, -265, -264, -263, -4, -5, -6, -3, -196670, -67, -265, -327745, -65, -266, -249, -103, -262205, -6, -267, -266, -262205, -227, -268, -229, -327822, -227, -269, -268, -267, -262205, -6, -270, -70, -327822, -227, -271, -269, -270, -262205, -7, -272, -68, -524367, -227, -273, -272, -272, -0, -1, -2, -327811, -227, -274, -273, -271, -262205, -7, -275, -68, -589903, -7, -276, -275, -274, -4, -5, -6, -3, -196670, -68, -276, +188, 65789, 65592, }; -const std::vector compute_tangents = {119734787, +const std::vector length_wind_collision = {119734787, 65536, 524289, -297, +586, 0, 131089, 1, @@ -30943,8 +29640,8 @@ const std::vector compute_tangents = {119734787, 4, 1852399981, 0, -187, -188, +283, +284, 393232, 4, 17, @@ -31225,33 +29922,84 @@ const std::vector compute_tangents = {119734787, 1634890867, 2035573870, 25968, +655365, +63, +1936617283, +1767993972, +1968010350, +1885959276, +1919248748, +879130152, +879130171, +59, +327685, +61, +1953653104, +1701602153, +48, 327685, +62, +1953653104, +1701602153, +49, +786437, +71, +1819308097, +1936278649, +1668178292, +1852785509, +1634890867, +678719081, +993289846, +993289846, +1715155302, +15153, +262149, +67, +812871536, +0, +262149, +68, +829648752, +0, +393221, 69, +1735549300, +1766093925, +1851880563, +25955, +327685, +70, +1718187123, +1936027238, +115, +327685, +82, 1936617283, 1953390964, 115, 327686, -69, +82, 0, 1767333735, 25710, 327686, -69, +82, 1, 1767333735, 3236974, 327686, -69, +82, 2, 1767333735, 3302510, 327686, -69, +82, 3, 1767333735, 3368046, 720902, -69, +82, 4, 1968070503, 1852132461, @@ -31262,14 +30010,14 @@ const std::vector compute_tangents = {119734787, 1769234802, 7564911, 458758, -69, +82, 5, 1130520423, 1768713327, 1852795251, 0, 524294, -69, +82, 6, 1917280103, 1953068641, @@ -31277,19 +30025,19 @@ const std::vector compute_tangents = {119734787, 1970563438, 25956, 393222, -69, +82, 7, 1767137127, 1951622509, 28773, 393222, -69, +82, 8, 1631870823, 1852403821, 12391, 786438, -69, +82, 9, 1951620967, 1852204649, @@ -31301,7 +30049,7 @@ const std::vector compute_tangents = {119734787, 1735289192, 48, 786438, -69, +82, 10, 1951620967, 1852204649, @@ -31313,7 +30061,7 @@ const std::vector compute_tangents = {119734787, 1852401763, 12391, 851974, -69, +82, 11, 1816616807, 1818321519, @@ -31326,13 +30074,13 @@ const std::vector compute_tangents = {119734787, 811951982, 0, 393222, -69, +82, 12, 1631870823, 1852403821, 12647, 786438, -69, +82, 13, 1951620967, 1852204649, @@ -31344,7 +30092,7 @@ const std::vector compute_tangents = {119734787, 1735289192, 49, 786438, -69, +82, 14, 1951620967, 1852204649, @@ -31356,7 +30104,7 @@ const std::vector compute_tangents = {119734787, 1852401763, 12647, 851974, -69, +82, 15, 1816616807, 1818321519, @@ -31369,13 +30117,13 @@ const std::vector compute_tangents = {119734787, 828729198, 0, 393222, -69, +82, 16, 1631870823, 1852403821, 12903, 786438, -69, +82, 17, 1951620967, 1852204649, @@ -31387,7 +30135,7 @@ const std::vector compute_tangents = {119734787, 1735289192, 50, 786438, -69, +82, 18, 1951620967, 1852204649, @@ -31399,7 +30147,7 @@ const std::vector compute_tangents = {119734787, 1852401763, 12903, 851974, -69, +82, 19, 1816616807, 1818321519, @@ -31412,13 +30160,13 @@ const std::vector compute_tangents = {119734787, 845506414, 0, 393222, -69, +82, 20, 1631870823, 1852403821, 13159, 786438, -69, +82, 21, 1951620967, 1852204649, @@ -31430,7 +30178,7 @@ const std::vector compute_tangents = {119734787, 1735289192, 51, 786438, -69, +82, 22, 1951620967, 1852204649, @@ -31442,7 +30190,7 @@ const std::vector compute_tangents = {119734787, 1852401763, 13159, 851974, -69, +82, 23, 1816616807, 1818321519, @@ -31455,7 +30203,7 @@ const std::vector compute_tangents = {119734787, 862283630, 0, 720902, -69, +82, 24, 1968070503, 1399213933, @@ -31466,7 +30214,7 @@ const std::vector compute_tangents = {119734787, 1886744434, 0, 720902, -69, +82, 25, 1968070503, 1819231853, @@ -31477,7 +30225,7 @@ const std::vector compute_tangents = {119734787, 1919508808, 0, 589830, -69, +82, 26, 1767137127, 1885688688, @@ -31486,12 +30234,12 @@ const std::vector compute_tangents = {119734787, 1869898593, 114, 327686, -69, +82, 27, 1466064743, 7369313, 786438, -69, +82, 28, 1968070503, 1668238445, @@ -31503,17 +30251,56 @@ const std::vector compute_tangents = {119734787, 1852795252, 115, 196613, -71, +84, 0, 458757, -103, +116, 1632132967, 1951625833, 1684955506, 1701869908, 0, +262149, +202, +1634886000, +109, +262149, +207, +1634886000, +109, +262149, +220, +1634886000, +109, +262149, +233, +1953260900, +97, +327685, +239, +1953720676, +1701015137, +0, +327685, +244, +1701999731, +1768448884, +26478, +327685, +253, +1953265005, +1768714345, +29285, +262149, +254, +1634886000, +109, +262149, +256, +1634886000, +109, 524293, -187, +283, 1281322087, 1818321775, 1870032457, @@ -31521,41 +30308,41 @@ const std::vector compute_tangents = {119734787, 1145663087, 0, 393221, -188, +284, 1465871463, 1198223983, 1886744434, 17481, 458757, -189, +285, 1651469415, 1951624289, 1684955506, 1701080649, 120, 458757, -190, +286, 1633906540, 1920226156, 1231318625, 2019910766, 0, 458757, -191, +287, 1651469415, 1700162657, 2019914866, 1701080649, 120, 458757, -192, +288, 1633906540, 1919243884, 1232627060, 2019910766, 0, 524293, -193, +289, 1450014062, 1769239141, 1232299363, @@ -31563,68 +30350,55 @@ const std::vector compute_tangents = {119734787, 1634890835, 25710, 458757, -194, +290, 1701080681, 1919895160, 1918986323, 1699570789, 109, 327685, -195, +291, 1634890867, 2035573870, 25968, 262149, -196, +292, 1634886000, 109, 262149, -200, +296, 1634886000, 109, 262149, -203, +299, 1634886000, 109, 262149, -205, +301, 1634886000, 109, 262149, -207, +303, 1634886000, 109, 262149, -209, +305, 1634886000, 109, 262149, -211, +307, 1634886000, 109, 262149, -213, +309, 1634886000, 109, 262149, -215, +311, 1634886000, 109, -327685, -227, -1918986355, -1867539557, -115, -524293, -229, -1632132967, -1700164201, -2019914866, -1769172816, -1852795252, -115, 589829, -237, +321, 1332573550, 1920226150, 1935961697, @@ -31632,47 +30406,131 @@ const std::vector compute_tangents = {119734787, 1634038376, 1869760356, 28789, -262149, -246, -1735287156, -7630437, +327685, +326, +1918986355, +1867539557, +115, 458757, -259, +329, 1953067639, 1818386789, 1936674917, 1869182057, 29550, 589830, -259, +329, 0, 1632132967, 1700164201, 2019914866, -1735287124, -1937010277, -0, +1769172816, +1852795252, +115, 196613, -261, +331, 0, 393221, -271, -1953654134, -1834969439, -1937075817, -12639, +341, +1918986355, +1699505253, +1752459118, +0, +458757, +346, +1632132967, +1699902057, +1699509363, +1752459118, +5657171, 262149, -278, -1953654134, -26975, +375, +1668444006, +101, +262149, +377, +1835102822, +101, +196613, +391, +97, +196613, +398, +119, +327685, +427, +1918986355, +1850303589, +7890276, +196613, +436, +118, +262149, +449, +1668444006, +101, +196613, +472, +97, +196613, +479, +98, +327685, +486, +1919251561, +1869182049, +17774, +327685, +498, +1918986355, +1850303589, +7890276, +262149, +520, +1634886000, +109, +262149, +523, +1634886000, +109, +262149, +526, +1634886000, +109, +262149, +529, +1634886000, +109, +262149, +554, +1634886000, +109, +262149, +557, +1634886000, +109, +262149, +560, +1634886000, +109, +262149, +563, +1634886000, +109, 393221, -293, +572, +1819231074, +1702126916, +1684370531, +0, +393221, +582, 1684104520, 1851880020, 1919903347, 109, 589830, -293, +582, 0, 1867341671, 1416389988, @@ -31681,7 +30539,7 @@ const std::vector compute_tangents = {119734787, 1215459142, 6578533, 589830, -293, +582, 1, 1867341671, 1382835556, @@ -31690,7 +30548,7 @@ const std::vector compute_tangents = {119734787, 1684104520, 0, 589830, -293, +582, 2, 1852396386, 1214606439, @@ -31699,259 +30557,259 @@ const std::vector compute_tangents = {119734787, 1836216166, 0, 327686, -293, +582, 3, 1684300144, 6778473, 196613, -295, +584, 0, 327752, -69, +82, 0, 35, 0, 327752, -69, +82, 1, 35, 16, 327752, -69, +82, 2, 35, 32, 327752, -69, +82, 3, 35, 48, 327752, -69, +82, 4, 35, 64, 327752, -69, +82, 5, 35, 68, 327752, -69, +82, 6, 35, 72, 327752, -69, +82, 7, 35, 76, 327752, -69, +82, 8, 35, 80, 327752, -69, +82, 9, 35, 84, 327752, -69, +82, 10, 35, 88, 327752, -69, +82, 11, 35, 92, 327752, -69, +82, 12, 35, 96, 327752, -69, +82, 13, 35, 100, 327752, -69, +82, 14, 35, 104, 327752, -69, +82, 15, 35, 108, 327752, -69, +82, 16, 35, 112, 327752, -69, +82, 17, 35, 116, 327752, -69, +82, 18, 35, 120, 327752, -69, +82, 19, 35, 124, 327752, -69, +82, 20, 35, 128, 327752, -69, +82, 21, 35, 132, 327752, -69, +82, 22, 35, 136, 327752, -69, +82, 23, 35, 140, 327752, -69, +82, 24, 35, 144, 327752, -69, +82, 25, 35, 148, 327752, -69, +82, 26, 35, 152, 327752, -69, +82, 27, 35, 156, 327752, -69, +82, 28, 35, 160, 196679, -69, +82, 3, 262215, -71, +84, 34, 0, 262215, -71, +84, 33, 16, 262215, -103, +116, 34, 1, 262215, -103, +116, 33, 22, 262215, -187, +283, 11, 27, 262215, -188, +284, 11, 26, 262215, -229, -34, -1, -262215, -229, -33, -7, -262215, -258, +328, 6, 16, 327752, -259, +329, 0, 35, 0, 196679, -259, +329, 3, 262215, -261, +331, 34, 1, 262215, -261, +331, 33, -8, +7, 262215, -292, +346, +34, +1, +262215, +346, +33, +26, +262215, +581, 6, 16, 262216, -293, +582, 0, 5, 327752, -293, +582, 0, 35, 0, 327752, -293, +582, 0, 7, 16, 327752, -293, +582, 1, 35, 64, 327752, -293, +582, 2, 35, 80, 327752, -293, +582, 3, 35, 96, 196679, -293, +582, 3, 262215, -295, +584, 34, 0, 262215, -295, +584, 33, 27, 262215, -296, +585, 11, 25, 131091, @@ -32022,24 +30880,40 @@ const std::vector compute_tangents = {119734787, 15, 17, 15, -262187, -14, +262167, 59, -3, -262176, +6, +2, +327713, 60, +59, +8, +8, +262176, +65, 7, 6, +458785, +66, +2, +8, +8, +65, +65, +262187, +14, +73, +3, 262187, 6, -63, +76, 0, 262187, 14, -68, +81, 64, 2031646, -69, +82, 7, 7, 7, @@ -32070,31 +30944,31 @@ const std::vector compute_tangents = {119734787, 16, 16, 262176, -70, +83, 2, -69, +82, 262203, -70, -71, +83, +84, 2, 262187, 16, -72, +85, 24, 262176, -73, +86, 2, 14, 262187, 16, -87, +100, 25, 262187, 14, -90, +103, 1, 589849, -100, +113, 14, 5, 0, @@ -32103,130 +30977,252 @@ const std::vector compute_tangents = {119734787, 1, 0, 196635, -101, -100, +114, +113, 262176, -102, +115, 0, -101, +114, 262203, -102, -103, +115, +116, 0, 262167, -107, +121, 14, 4, 262187, 14, -109, +123, 0, 262187, 16, -163, +179, 64, +262187, +6, +212, +1056964608, +327724, +59, +213, +212, +212, +262187, +6, +216, +1065353216, +327724, +59, +217, +216, +76, +327724, +59, +225, +76, +216, +327724, +59, +228, +76, +76, 262167, -185, +231, +6, +3, +262176, +232, +7, +231, +262187, +6, +242, +869711765, +262176, +252, +7, +59, +262167, +281, 14, 3, 262176, -186, +282, 1, -185, +281, 262203, -186, -187, +282, +283, 1, 262203, -186, -188, +282, +284, 1, 262176, -197, +293, 1, 14, 262172, -225, +324, 7, -68, +81, 262176, -226, +325, 4, -225, +324, 262203, -226, -227, +325, +326, 4, +196637, +328, +7, +196638, +329, +328, +262176, +330, +2, +329, 262203, -102, -229, +330, +331, +2, +262187, +16, +332, 0, 262176, -234, +334, +2, +7, +262176, +337, 4, 7, -262187, -14, -236, -4062, -262167, -244, +262172, +339, 6, -3, +81, 262176, -245, -7, -244, -196637, -258, -7, -196638, -259, -258, +340, +4, +339, +262203, +340, +341, +4, +589849, +343, +6, +5, +0, +0, +0, +1, +0, +196635, +344, +343, 262176, -260, -2, -259, +345, +0, +344, 262203, -260, -261, +345, +346, +0, +262176, +352, +4, +6, +262187, +14, +354, +2, +262176, +355, +2, +6, +458796, +7, +376, +76, +76, +76, +76, +262187, +14, +393, +20, +262187, +6, +396, +1101004800, +262187, +16, +406, +1, +262187, +16, +413, 2, 262187, 16, -262, -0, +421, +3, +262187, +16, +458, +7, +262187, +6, +475, +1073741824, +262187, +16, +493, +4, 262176, -266, +494, 2, +16, +262176, +571, 7, +9, +196650, +9, +573, 262168, -291, +580, 7, 4, 262172, -292, +581, 6, -59, +73, 393246, -293, -291, +582, +580, 7, 16, -292, +581, 262176, -294, +583, 2, -293, +582, 262203, -294, -295, +583, +584, 2, 393260, -185, -296, -68, -90, -90, +281, +585, +81, +103, +103, 327734, 2, 4, @@ -32236,490 +31232,1392 @@ const std::vector compute_tangents = {119734787, 5, 262203, 15, -189, +285, 7, 262203, 15, -190, +286, 7, 262203, 17, -191, +287, 7, 262203, 15, -192, +288, 7, 262203, 15, -193, +289, 7, 262203, 15, -194, +290, 7, 262203, 15, -195, +291, 7, 262203, 15, -196, +292, 7, 262203, 15, -200, +296, 7, 262203, 15, -203, +299, 7, 262203, 15, -205, +301, 7, 262203, 17, -207, +303, 7, 262203, 15, -209, +305, 7, 262203, 15, -211, +307, 7, 262203, 15, -213, +309, 7, 262203, 15, -215, +311, 7, 262203, 15, -237, +321, 7, 262203, -245, -246, +8, +375, 7, 262203, -245, -271, +65, +377, +7, +262203, +65, +391, +7, +262203, +232, +398, +7, +262203, +17, +427, +7, +262203, +232, +436, +7, +262203, +232, +449, +7, +262203, +17, +472, +7, +262203, +17, +479, +7, +262203, +17, +486, +7, +262203, +17, +498, +7, +262203, +8, +520, +7, +262203, +8, +523, +7, +262203, +65, +526, +7, +262203, +65, +529, +7, +262203, +8, +554, +7, +262203, +8, +557, +7, +262203, +65, +560, +7, +262203, +65, +563, +7, +262203, +571, +572, +7, +327745, +293, +294, +283, +123, +262205, +14, +295, +294, +196670, +292, +295, +327745, +293, +297, +284, +123, +262205, +14, +298, +297, +196670, +296, +298, +262205, +14, +300, +285, +196670, +299, +300, +262205, +14, +302, +286, +196670, +301, +302, +262205, +16, +304, +287, +196670, +303, +304, +262205, +14, +306, +288, +196670, +305, +306, +262205, +14, +308, +289, +196670, +307, +308, +262205, +14, +310, +290, +196670, +309, +310, +262205, +14, +312, +291, +196670, +311, +312, +852025, +2, +313, +28, +292, +296, +299, +301, +303, +305, +307, +309, +311, +262205, +14, +314, +299, +196670, +285, +314, +262205, +14, +315, +301, +196670, +286, +315, +262205, +16, +316, +303, +196670, +287, +316, +262205, +14, +317, +305, +196670, +288, +317, +262205, +14, +318, +307, +196670, +289, +318, +262205, +14, +319, +309, +196670, +290, +319, +262205, +14, +320, +311, +196670, +291, +320, +327745, +86, +322, +84, +85, +262205, +14, +323, +322, +196670, +321, +323, +262205, +14, +327, +290, +262205, +16, +333, +287, +393281, +334, +335, +331, +332, +333, +262205, +7, +336, +335, +327745, +337, +338, +326, +327, +196670, +338, +336, +262205, +14, +342, +290, +262205, +344, +347, +346, +262205, +16, +348, +287, +262244, +343, +349, +347, +327775, +7, +350, +349, +348, +327761, +6, +351, +350, +0, +327745, +352, +353, +341, +342, +196670, +353, +351, +262368, +354, +103, +123, +393281, +355, +356, +84, +332, +123, +262205, +6, +357, +356, +327862, +9, +358, +357, +76, +262312, +9, +359, +358, +196855, +361, +0, +262394, +359, +360, +361, +131320, +360, +393281, +355, +362, +84, +332, +103, +262205, +6, +363, +362, +327862, +9, +364, +363, +76, +131321, +361, +131320, +361, +458997, +9, +365, +358, +5, +364, +360, +262312, +9, +366, +365, +196855, +368, +0, +262394, +366, +367, +368, +131320, +367, +393281, +355, +369, +84, +332, +354, +262205, +6, +370, +369, +327862, +9, +371, +370, +76, +131321, +368, +131320, +368, +458997, +9, +372, +365, +361, +371, +367, +196855, +374, +0, +262394, +372, +373, +374, +131320, +373, +196670, +375, +376, +393281, +355, +378, +84, +332, +73, +262205, +6, +379, +378, +196670, +377, +379, +262205, +14, +380, +288, +327854, +9, +381, +380, +354, +196855, +383, +0, +262394, +381, +382, +383, +131320, +382, +262205, +14, +384, +288, +262205, +14, +385, +289, +327810, +14, +386, +385, +103, +327856, +9, +387, +384, +386, +131321, +383, +131320, +383, +458997, +9, +388, +381, +373, +387, +382, +196855, +390, +0, +262394, +388, +389, +390, +131320, +389, +262205, +14, +392, +285, +327817, +14, +394, +392, +393, +262256, +6, +395, +394, +327816, +6, +397, +395, +396, +196670, +391, +397, +262205, +6, +399, +391, +327745, +334, +400, +84, +332, +262205, +7, +401, +400, +524367, +231, +402, +401, +401, +0, +1, +2, +327822, +231, +403, +402, +399, +262205, +6, +404, +391, +327811, +6, +405, +216, +404, +327745, +334, +407, +84, +406, +262205, +7, +408, +407, +524367, +231, +409, +408, +408, +0, +1, +2, +327822, +231, +410, +409, +405, +327809, +231, +411, +403, +410, +262205, +6, +412, +391, +327745, +334, +414, +84, +413, +262205, +7, +415, +414, +524367, +231, +416, +415, +415, +0, +1, +2, +327822, +231, +417, +416, +412, +327809, +231, +418, +411, +417, +262205, +6, +419, +391, +327811, +6, +420, +216, +419, +327745, +334, +422, +84, +421, +262205, +7, +423, +422, +524367, +231, +424, +423, +423, +0, +1, +2, +327822, +231, +425, +424, +420, +327809, +231, +426, +418, +425, +196670, +398, +426, +262205, +14, +428, +288, +262268, +16, +429, +428, +262205, +14, +430, +321, +262268, +16, +431, +430, +327812, +16, +432, +429, +431, +262205, +14, +433, +286, +262268, +16, +434, +433, +327808, +16, +435, +432, +434, +196670, +427, +435, +262205, +16, +437, +427, +327745, +337, +438, +326, +437, +262205, +7, +439, +438, +524367, +231, +440, +439, +439, +0, +1, +2, +262205, +16, +441, +427, +262268, +14, +442, +441, +262205, +14, +443, +321, +327808, +14, +444, +442, +443, +327745, +337, +445, +326, +444, +262205, +7, +446, +445, +524367, +231, +447, +446, +446, +0, +1, +2, +327811, +231, +448, +440, +447, +196670, +436, +448, +262205, +231, +450, +436, +262205, +231, +451, +398, +458764, +231, +452, +1, +68, +450, +451, +262205, +231, +453, +436, +458764, +231, +454, +1, +68, +452, +453, +262271, +231, +455, +454, +196670, +449, +455, +262205, +16, +456, +427, +262205, +231, +457, +449, +327745, +355, +459, +84, +458, +262205, +6, +460, +459, +327822, +231, +461, +457, +460, +327745, +355, +462, +84, +458, +262205, +6, +463, +462, +327822, +231, +464, +461, +463, +327745, +337, +465, +326, +456, +262205, +7, +466, +465, +524367, +231, +467, +466, +466, +0, +1, +2, +327809, +231, +468, +467, +464, +327745, +337, +469, +326, +456, +262205, 7, -262203, -245, -278, +470, +469, +589903, 7, -327745, -197, -198, -187, -109, -262205, -14, -199, -198, +471, +470, +468, +4, +5, +6, +3, 196670, -196, -199, -327745, -197, -201, -188, -109, +469, +471, +131321, +390, +131320, +390, +131321, +374, +131320, +374, +262368, +354, +103, +123, 262205, 14, -202, -201, +473, +289, +262256, +6, +474, +473, +327816, +6, +476, +474, +475, +393228, +6, +477, +1, +8, +476, +262254, +16, +478, +477, 196670, -200, -202, +472, +478, 262205, 14, -204, -189, +480, +289, +262256, +6, +481, +480, +327811, +6, +482, +481, +216, +327816, +6, +483, +482, +475, +393228, +6, +484, +1, +8, +483, +262254, +16, +485, +484, 196670, -203, -204, -262205, -14, -206, -190, +479, +485, 196670, -205, -206, +486, +332, +131321, +487, +131320, +487, +262390, +489, +490, +0, +131321, +491, +131320, +491, 262205, 16, -208, -191, -196670, -207, -208, +492, +486, +327745, +494, +495, +84, +493, 262205, -14, -210, -192, -196670, -209, -210, +16, +496, +495, +327857, +9, +497, +492, +496, +262394, +497, +488, +489, +131320, +488, 262205, 14, -212, -193, -196670, -211, -212, +499, +288, +262268, +16, +500, +499, +327812, +16, +501, +413, +500, 262205, 14, -214, -194, -196670, -213, -214, +502, +321, +262268, +16, +503, +502, +327812, +16, +504, +501, +503, 262205, 14, -216, -195, +505, +286, +262268, +16, +506, +505, +327808, +16, +507, +504, +506, 196670, -215, -216, -852025, -2, -217, -39, -196, -200, -203, -205, -207, -209, -211, -213, -215, +498, +507, 262205, 14, -218, -203, -196670, -189, -218, +508, +288, 262205, +16, +509, +472, +262268, 14, -219, -205, -196670, -190, -219, +510, +509, +327856, +9, +511, +508, +510, +196855, +513, +0, +262394, +511, +512, +513, +131320, +512, 262205, 16, -220, -207, -196670, -191, -220, +514, +498, 262205, +16, +515, +498, +262268, 14, -221, -209, -196670, -192, -221, +516, +515, 262205, 14, -222, -211, -196670, -193, -222, -262205, +517, +321, +327808, 14, -223, -213, +518, +516, +517, +262205, +16, +519, +498, +327745, +337, +521, +326, +514, +262205, +7, +522, +521, 196670, -194, -223, +520, +522, +327745, +337, +524, +326, +518, 262205, -14, -224, -215, +7, +525, +524, 196670, -195, -224, +523, +525, +327745, +352, +527, +341, +519, 262205, -14, -228, -194, +6, +528, +527, +196670, +526, +528, +196670, +529, +216, +524345, +2, +530, +71, +520, +523, +526, +529, 262205, -101, -230, -229, +7, +531, +520, +327745, +337, +532, +326, +514, +196670, +532, +531, 262205, -16, -231, -191, -327775, -107, -232, -230, -231, -262256, 7, -233, -232, +533, +523, 327745, -234, -235, -227, -228, +337, +534, +326, +518, 196670, -235, -233, -196833, -90, -236, +534, +533, +131321, +513, +131320, +513, 262368, -90, -90, -109, -327745, -73, -238, -71, -72, +354, +103, +123, 262205, 14, -239, -238, -196670, -237, -239, +535, +288, 262205, +16, +536, +479, +262268, 14, -240, -192, -327850, +537, +536, +327856, 9, -241, -240, -109, +538, +535, +537, 196855, -243, +540, 0, 262394, -241, -242, -270, +538, +539, +540, 131320, -242, +539, 262205, +16, +541, +498, +262268, 14, -247, -194, +542, +541, 262205, 14, -248, -237, +543, +321, 327808, 14, -249, -247, -248, -327745, -234, -250, -227, -249, -262205, -7, -251, -250, -524367, -244, -252, -251, -251, -0, -1, -2, -262205, -14, -253, -194, -327745, -234, -254, -227, -253, -262205, -7, -255, -254, -524367, -244, -256, -255, -255, -0, -1, -2, -327811, -244, -257, -252, -256, -196670, -246, -257, +544, +542, +543, 262205, 16, -263, -191, -262205, -244, -264, -246, -393228, -244, -265, -1, -69, -264, -393281, -266, -267, -261, -262, -263, +545, +498, +262268, +14, +546, +545, 262205, -7, -268, -267, -589903, -7, -269, -268, -265, -4, -5, -6, -3, -196670, -267, -269, -131321, -243, -131320, -270, +14, +547, +321, +327812, +14, +548, +547, +354, +327808, +14, +549, +546, +548, 262205, +16, +550, +498, +262268, 14, -272, -194, +551, +550, 262205, 14, -273, -237, -327810, +552, +321, +327808, 14, -274, -272, -273, +553, +551, +552, 327745, -234, -275, -227, -274, +337, +555, +326, +544, 262205, 7, -276, -275, -524367, -244, -277, -276, -276, -0, -1, -2, +556, +555, 196670, -271, -277, -262205, -14, -279, -194, +554, +556, 327745, -234, -280, -227, -279, +337, +558, +326, +549, 262205, 7, -281, -280, -524367, -244, -282, -281, -281, -0, -1, +559, +558, +196670, +557, +559, +327745, +352, +561, +341, +553, +262205, +6, +562, +561, +196670, +560, +562, +196670, +563, +216, +524345, 2, +564, +71, +554, +557, +560, +563, +262205, +7, +565, +554, +327745, +337, +566, +326, +544, 196670, -278, -282, +566, +565, 262205, -16, -283, -191, +7, +567, +557, +327745, +337, +568, +326, +549, +196670, +568, +567, +131321, +540, +131320, +540, +262368, +354, +103, +123, +131321, +490, +131320, +490, 262205, -244, -284, -278, +16, +569, +486, +327808, +16, +570, +569, +406, +196670, +486, +570, +131321, +487, +131320, +489, +196670, +572, +573, 262205, -244, -285, -271, -327811, -244, -286, -284, -285, -393228, -244, +16, +574, 287, -1, -69, -286, -393281, -266, -288, -261, -262, -283, 262205, -7, -289, -288, -589903, -7, +14, +575, 290, -289, -287, -4, -5, -6, -3, +327745, +337, +576, +326, +575, +262205, +7, +577, +576, +393281, +334, +578, +331, +332, +574, 196670, -288, -290, -131321, -243, -131320, -243, +578, +577, 65789, 65592, 327734, @@ -32733,21 +32631,21 @@ const std::vector compute_tangents = {119734787, 131320, 13, 327745, -60, -61, +65, +74, 11, -59, +73, 262205, 6, -62, -61, +75, +74, 327866, 9, -64, -62, -63, +77, +75, +76, 131326, -64, +77, 65592, 327734, 2, @@ -32785,189 +32683,193 @@ const std::vector compute_tangents = {119734787, 29, 262205, 14, -67, +80, 19, 196670, 26, -67, +80, 327745, -73, -74, -71, -72, +86, +87, +84, +85, 262205, 14, -75, -74, +88, +87, 327814, 14, -76, -68, -75, +89, +81, +88, 196670, 25, -76, +89, 262205, 14, -77, +90, 19, 327745, -73, -78, -71, -72, +86, +91, +84, +85, 262205, 14, -79, -78, +92, +91, 327817, 14, -80, -77, -79, +93, +90, +92, 196670, 22, -80, +93, 262205, 14, -81, +94, 20, 327745, -73, -82, -71, -72, +86, +95, +84, +85, 262205, 14, -83, -82, +96, +95, 327812, 14, -84, -81, -83, +97, +94, +96, 262205, 14, -85, +98, 22, 327808, 14, -86, -84, -85, +99, +97, +98, 196670, 21, -86, +99, 327745, -73, -88, -71, -87, +86, +101, +84, +100, 262205, 14, -89, -88, +102, +101, 327808, 14, -91, -89, -90, +104, +102, +103, 262205, 14, -92, +105, 21, 327812, 14, -93, -92, -91, +106, +105, +104, 196670, 21, -93, +106, 262205, 14, -94, +107, 19, 262205, 14, -95, +108, 22, 327810, 14, -96, -94, -95, +109, +107, +108, 327745, -73, -97, -71, -72, +86, +110, +84, +85, 262205, 14, -98, -97, +111, +110, 327814, 14, -99, -96, -98, +112, +109, +111, 196670, 24, -99, +112, 262205, -101, -104, -103, +114, +117, +116, 262205, 14, -105, +118, 21, 262268, 16, -106, -105, +119, +118, +262244, +113, +120, +117, 327775, -107, -108, -104, -106, +121, +122, +120, +119, 327761, 14, -110, -108, +124, +122, 0, 196670, 27, -110, +124, 262205, 14, -111, +125, 21, 262205, 14, -112, +126, 25, 327812, 14, -113, -111, -112, +127, +125, +126, 262205, 14, -114, +128, 24, 327808, 14, -115, -113, -114, +129, +127, +128, 262268, 16, -116, -115, +130, +129, 196670, 23, -116, +130, 65789, 65592, 327734, @@ -33006,163 +32908,167 @@ const std::vector compute_tangents = {119734787, 40, 262205, 14, -117, +131, 30, 196670, 37, -117, +131, 327745, -73, -118, -71, -72, +86, +132, +84, +85, 262205, 14, -119, -118, +133, +132, 327814, 14, -120, -68, -119, +134, +81, +133, 196670, 36, -120, +134, 262205, 14, -121, +135, 30, 327745, -73, -122, -71, -72, +86, +136, +84, +85, 262205, 14, -123, -122, +137, +136, 327817, 14, -124, -121, -123, +138, +135, +137, 196670, 33, -124, +138, 262205, 14, -125, +139, 31, 327745, -73, -126, -71, -72, +86, +140, +84, +85, 262205, 14, -127, -126, +141, +140, 327812, -14, -128, -125, -127, +14, +142, +139, +141, 262205, 14, -129, +143, 33, 327808, 14, -130, -128, -129, +144, +142, +143, 196670, 32, -130, +144, 262205, 14, -131, +145, 30, 262205, 14, -132, +146, 33, 327810, 14, -133, -131, -132, +147, +145, +146, 327745, -73, -134, -71, -72, +86, +148, +84, +85, 262205, 14, -135, -134, +149, +148, 327814, 14, -136, -133, -135, +150, +147, +149, 196670, 35, -136, +150, 262205, -101, -137, -103, +114, +151, +116, 262205, 14, -138, +152, 32, 262268, 16, -139, -138, +153, +152, +262244, +113, +154, +151, 327775, -107, -140, -137, -139, +121, +155, +154, +153, 327761, 14, -141, -140, +156, +155, 0, 196670, 38, -141, +156, 262205, 14, -142, +157, 32, 262205, 14, -143, +158, 36, 327812, 14, -144, -142, -143, +159, +157, +158, 262205, 14, -145, +160, 35, 327808, 14, -146, -144, -145, +161, +159, +160, 262268, 16, -147, -146, +162, +161, 196670, 34, -147, +162, 65789, 65592, 327734, @@ -33192,226 +33098,629 @@ const std::vector compute_tangents = {119734787, 49, 262205, 14, -148, +163, 43, 327812, 14, -149, -68, -148, +164, +81, +163, 262205, 14, -150, +165, 42, 327808, 14, -151, -149, -150, +166, +164, +165, 196670, 44, -151, +166, 327745, -73, -152, -71, -72, +86, +167, +84, +85, 262205, 14, -153, -152, +168, +167, 327814, 14, -154, +169, +81, +168, +196670, +45, +169, +262205, +114, +170, +116, +262205, +14, +171, +44, +262268, +16, +172, +171, +262244, +113, +173, +170, +327775, +121, +174, +173, +172, +327761, +14, +175, +174, +0, +196670, +47, +175, +262205, +14, +176, +44, +262205, +14, +177, +45, +327812, +14, +178, +176, +177, +196670, +46, +178, +65789, +65592, +327734, +2, +57, +0, +50, +196663, +17, +51, +196663, +17, +52, +196663, +17, +53, +196663, +15, +54, +196663, +17, +55, +196663, +15, +56, +131320, +58, +262205, +16, +180, +52, +327812, +16, +181, +179, +180, +262205, +16, +182, +51, +327808, +16, +183, +181, +182, +196670, +53, +183, +327745, +86, +184, +84, +100, +262205, +14, +185, +184, +327808, +14, +186, +185, +103, +262268, +16, +187, +186, +262205, +16, +188, +53, +327812, +16, +189, +188, +187, +196670, +53, +189, +327745, +86, +190, +84, +85, +262205, +14, +191, +190, +327814, +14, +192, +81, +191, +196670, +54, +192, +262205, +114, +193, +116, +262205, +16, +194, +53, +262244, +113, +195, +193, +327775, +121, +196, +195, +194, +327761, +14, +197, +196, +0, +196670, +56, +197, +262205, +16, +198, +53, +262205, +14, +199, +54, +262268, +16, +200, +199, +327812, +16, +201, +198, +200, +196670, +55, +201, +65789, +65592, +327734, +59, +63, +0, +60, +196663, +8, +61, +196663, +8, +62, +131320, +64, +262203, +8, +202, +7, +262203, +8, +207, +7, +262203, +8, +220, +7, +262205, +7, +203, +61, +196670, +202, +203, +327737, +9, +204, +12, +202, +196855, +206, +0, +262394, +204, +205, +219, +131320, +205, +262205, +7, +208, +62, +196670, +207, +208, +327737, +9, +209, +12, +207, +196855, +211, +0, +262394, +209, +210, +215, +131320, +210, +131326, +213, +131320, +215, +131326, +217, +131320, +211, +131321, +206, +131320, +219, +262205, +7, +221, +62, +196670, +220, +221, +327737, +9, +222, +12, +220, +196855, +224, +0, +262394, +222, +223, +227, +131320, +223, +131326, +225, +131320, +227, +131326, +228, +131320, +224, +131321, +206, +131320, +206, +196609, +59, +230, +131326, +230, +65592, +327734, +2, +71, +0, +66, +196663, +8, +67, +196663, +8, 68, -153, +196663, +65, +69, +196663, +65, +70, +131320, +72, +262203, +232, +233, +7, +262203, +65, +239, +7, +262203, +65, +244, +7, +262203, +252, +253, +7, +262203, +8, +254, +7, +262203, +8, +256, +7, +262205, +7, +234, +68, +524367, +231, +235, +234, +234, +0, +1, +2, +262205, +7, +236, +67, +524367, +231, +237, +236, +236, +0, +1, +2, +327811, +231, +238, +235, +237, +196670, +233, +238, +262205, +231, +240, +233, +393228, +6, +241, +1, +66, +240, +458764, +6, +243, +1, +40, +241, +242, 196670, -45, -154, +239, +243, 262205, -101, -155, -103, +6, +245, +69, 262205, -14, -156, -44, -262268, -16, -157, -156, -327775, -107, -158, -155, -157, -327761, -14, -159, -158, -0, +6, +246, +239, +327816, +6, +247, +245, +246, +327811, +6, +248, +216, +247, 196670, -47, -159, +244, +248, 262205, -14, -160, -44, +6, +249, +244, 262205, -14, -161, -45, -327812, -14, -162, -160, -161, +231, +250, +233, +327822, +231, +251, +250, +249, 196670, -46, -162, -65789, -65592, -327734, -2, -57, -0, -50, -196663, -17, -51, -196663, -17, -52, -196663, -17, -53, -196663, -15, -54, -196663, -17, -55, -196663, -15, -56, -131320, -58, +233, +251, 262205, -16, -164, -52, -327812, -16, -165, -163, -164, +7, +255, +67, +196670, +254, +255, 262205, -16, -166, -51, -327808, -16, -167, -165, -166, +7, +257, +68, 196670, -53, -167, +256, +257, +393273, +59, +258, +63, +254, +256, +196670, +253, +258, 327745, -73, -168, -71, -87, +65, +259, +253, +123, 262205, -14, -169, -168, -327808, -14, -170, -169, -90, -262268, -16, -171, -170, +6, +260, +259, 262205, -16, -172, -53, -327812, -16, -173, -172, -171, +231, +261, +233, +327822, +231, +262, +261, +260, +262205, +6, +263, +70, +327822, +231, +264, +262, +263, +262205, +7, +265, +67, +524367, +231, +266, +265, +265, +0, +1, +2, +327809, +231, +267, +266, +264, +262205, +7, +268, +67, +589903, +7, +269, +268, +267, +4, +5, +6, +3, 196670, -53, -173, +67, +269, 327745, -73, -174, -71, -72, +65, +270, +253, +103, 262205, -14, -175, -174, -327814, -14, -176, -68, -175, -196670, -54, -176, +6, +271, +270, 262205, -101, -177, -103, +231, +272, +233, +327822, +231, +273, +272, +271, 262205, -16, -178, -53, -327775, -107, -179, -177, -178, -327761, -14, -180, -179, -0, -196670, -56, -180, +6, +274, +70, +327822, +231, +275, +273, +274, 262205, -16, -181, -53, +7, +276, +68, +524367, +231, +277, +276, +276, +0, +1, +2, +327811, +231, +278, +277, +275, 262205, -14, -182, -54, -262268, -16, -183, -182, -327812, -16, -184, -181, -183, +7, +279, +68, +589903, +7, +280, +279, +278, +4, +5, +6, +3, 196670, -55, -184, +68, +280, 65789, 65592, }; const std::vector prepare_follow_hair = {119734787, 65536, 524289, -271, +276, 0, 131089, 1, @@ -33431,8 +33740,8 @@ const std::vector prepare_follow_hair = {119734787, 4, 1852399981, 0, -187, -188, +191, +192, 393232, 4, 17, @@ -34001,7 +34310,7 @@ const std::vector prepare_follow_hair = {119734787, 1701869908, 0, 524293, -187, +191, 1281322087, 1818321775, 1870032457, @@ -34009,41 +34318,41 @@ const std::vector prepare_follow_hair = {119734787, 1145663087, 0, 393221, -188, +192, 1465871463, 1198223983, 1886744434, 17481, 458757, -189, +193, 1651469415, 1951624289, 1684955506, 1701080649, 120, 458757, -190, +194, 1633906540, 1920226156, 1231318625, 2019910766, 0, 458757, -191, +195, 1651469415, 1700162657, 2019914866, 1701080649, 120, 458757, -192, +196, 1633906540, 1919243884, 1232627060, 2019910766, 0, 524293, -193, +197, 1450014062, 1769239141, 1232299363, @@ -34051,31 +34360,23 @@ const std::vector prepare_follow_hair = {119734787, 1634890835, 25710, 458757, -194, +198, 1701080681, 1919895160, 1918986323, 1699570789, 109, 327685, -195, +199, 1634890867, 2035573870, 25968, 262149, -196, -1634886000, -109, -262149, 200, 1634886000, 109, 262149, -203, -1634886000, -109, -262149, -205, +204, 1634886000, 109, 262149, @@ -34098,11 +34399,19 @@ const std::vector prepare_follow_hair = {119734787, 215, 1634886000, 109, +262149, +217, +1634886000, +109, +262149, +219, +1634886000, +109, 196613, -225, +229, 105, 524293, -237, +241, 1651469415, 1866886241, 2003790956, @@ -34110,11 +34419,11 @@ const std::vector prepare_follow_hair = {119734787, 1850308709, 7890276, 262149, -246, +250, 1919508840, 7565136, 524293, -250, +254, 1632132967, 1700164201, 2019914866, @@ -34122,7 +34431,7 @@ const std::vector prepare_follow_hair = {119734787, 1852795252, 115, 524293, -255, +260, 1953067639, 1818386789, 1936674917, @@ -34130,7 +34439,7 @@ const std::vector prepare_follow_hair = {119734787, 1701990510, 118, 655366, -255, +260, 0, 1632132967, 1700164201, @@ -34140,16 +34449,16 @@ const std::vector prepare_follow_hair = {119734787, 1701990515, 118, 196613, -257, +262, 0, 393221, -267, +272, 1684104520, 1851880020, 1919903347, 109, 589830, -267, +272, 0, 1867341671, 1416389988, @@ -34158,7 +34467,7 @@ const std::vector prepare_follow_hair = {119734787, 1215459142, 6578533, 589830, -267, +272, 1, 1867341671, 1382835556, @@ -34167,7 +34476,7 @@ const std::vector prepare_follow_hair = {119734787, 1684104520, 0, 589830, -267, +272, 2, 1852396386, 1214606439, @@ -34176,12 +34485,12 @@ const std::vector prepare_follow_hair = {119734787, 1836216166, 0, 327686, -267, +272, 3, 1684300144, 6778473, 196613, -269, +274, 0, 327752, 69, @@ -34348,87 +34657,87 @@ const std::vector prepare_follow_hair = {119734787, 33, 22, 262215, -187, +191, 11, 27, 262215, -188, +192, 11, 26, 262215, -250, +254, 34, 1, 262215, -250, +254, 33, 7, 262215, -254, +259, 6, 16, 327752, -255, +260, 0, 35, 0, 196679, -255, +260, 3, 262215, -257, +262, 34, 1, 262215, -257, +262, 33, 20, 262215, -266, +271, 6, 16, 262216, -267, +272, 0, 5, 327752, -267, +272, 0, 35, 0, 327752, -267, +272, 0, 7, 16, 327752, -267, +272, 1, 35, 64, 327752, -267, +272, 2, 35, 80, 327752, -267, +272, 3, 35, 96, 196679, -267, +272, 3, 262215, -269, +274, 34, 0, 262215, -269, +274, 33, 27, 262215, -270, +275, 11, 25, 131091, @@ -34591,47 +34900,47 @@ const std::vector prepare_follow_hair = {119734787, 103, 0, 262167, -107, +108, 14, 4, 262187, 14, -109, +110, 0, 262187, 16, -163, +166, 64, 262167, -185, +189, 14, 3, 262176, -186, +190, 1, -185, +189, 262203, -186, -187, +190, +191, 1, 262203, -186, -188, +190, +192, 1, 262176, -197, +201, 1, 14, 262187, 16, -226, +230, 0, 262187, 16, -242, +246, 1, 589849, -247, +251, 6, 5, 0, @@ -34640,59 +34949,59 @@ const std::vector prepare_follow_hair = {119734787, 1, 0, 196635, -248, -247, +252, +251, 262176, -249, +253, 0, -248, +252, 262203, -249, -250, +253, +254, 0, 196637, -254, +259, 7, 196638, -255, -254, +260, +259, 262176, -256, +261, 2, -255, +260, 262203, -256, -257, +261, +262, 2, 262176, -260, +265, 2, 7, 262168, -265, +270, 7, 4, 262172, -266, +271, 6, 59, 393246, -267, -265, +272, +270, 7, 16, -266, +271, 262176, -268, +273, 2, -267, +272, 262203, -268, -269, +273, +274, 2, 393260, -185, -270, +189, +275, 68, 90, 90, @@ -34705,345 +35014,349 @@ const std::vector prepare_follow_hair = {119734787, 5, 262203, 15, -189, +193, 7, 262203, 15, -190, +194, 7, 262203, 17, -191, +195, 7, 262203, 15, -192, +196, 7, 262203, 15, -193, +197, 7, 262203, 15, -194, +198, 7, 262203, 15, -195, +199, 7, 262203, 15, -196, +200, 7, 262203, 15, -200, +204, 7, 262203, 15, -203, +207, 7, 262203, 15, -205, +209, 7, 262203, 17, -207, +211, 7, 262203, 15, -209, +213, 7, 262203, 15, -211, +215, 7, 262203, 15, -213, +217, 7, 262203, 15, -215, +219, 7, 262203, 17, -225, +229, 7, 262203, 17, -237, +241, 7, 262203, 8, -246, +250, 7, 327745, -197, -198, -187, -109, -262205, -14, -199, -198, -196670, -196, -199, -327745, -197, 201, -188, -109, +202, +191, +110, 262205, 14, +203, 202, -201, 196670, 200, -202, -262205, -14, -204, -189, -196670, 203, -204, +327745, +201, +205, +192, +110, 262205, 14, 206, -190, -196670, 205, +196670, +204, 206, 262205, -16, +14, 208, -191, +193, 196670, 207, 208, 262205, 14, 210, -192, +194, 196670, 209, 210, 262205, -14, +16, 212, -193, +195, 196670, 211, 212, 262205, 14, 214, -194, +196, 196670, 213, 214, 262205, 14, 216, -195, +197, 196670, 215, 216, -852025, -2, -217, -28, -196, -200, -203, -205, -207, -209, -211, -213, -215, 262205, 14, 218, -203, +198, 196670, -189, +217, 218, 262205, 14, -219, -205, -196670, -190, -219, -262205, -16, 220, -207, +199, 196670, -191, +219, 220, -262205, -14, +852025, +2, 221, +28, +200, +204, +207, 209, -196670, -192, -221, +211, +213, +215, +217, +219, 262205, 14, 222, -211, +207, 196670, 193, 222, 262205, 14, 223, -213, +209, 196670, 194, 223, 262205, -14, +16, 224, -215, +211, 196670, 195, 224, +262205, +14, +225, +213, 196670, +196, 225, +262205, +14, 226, -131321, +215, +196670, +197, +226, +262205, +14, 227, -131320, +217, +196670, +198, 227, -262390, +262205, +14, +228, +219, +196670, +199, +228, +196670, 229, 230, -0, 131321, 231, 131320, 231, +262390, +233, +234, +0, +131321, +235, +131320, +235, 262205, 16, -232, -225, +236, +229, 262268, 14, -233, -232, +237, +236, 327745, 73, -234, +238, 71, 87, 262205, 14, -235, -234, +239, +238, 327856, 9, -236, -233, -235, +240, +237, +239, 262394, -236, -228, -229, +240, +232, +233, 131320, -228, +232, 262205, 16, -238, -191, +242, +195, 262205, 14, -239, -193, +243, +197, 262268, 16, -240, -239, +244, +243, 262205, 16, -241, -225, +245, +229, 327808, 16, -243, -241, -242, +247, +245, +246, 327812, 16, +248, 244, -240, -243, +247, 327808, 16, -245, -238, -244, +249, +242, +248, 196670, -237, -245, +241, +249, 262205, -248, -251, -250, +252, +255, +254, 262205, 16, -252, -237, +256, +241, +262244, +251, +257, +255, 327775, 7, -253, -251, -252, +258, +257, +256, 196670, -246, -253, +250, +258, 262205, 16, -258, -237, +263, +241, 262205, 7, -259, -246, +264, +250, 393281, -260, -261, -257, -226, -258, +265, +266, +262, +230, +263, 196670, -261, -259, +266, +264, 131321, -230, +234, 131320, -230, +234, 262205, 16, -262, -225, +267, +229, 327808, 16, -263, -262, -242, +268, +267, +246, 196670, -225, -263, +229, +268, 131321, -227, +231, 131320, -229, +233, 65789, 65592, 327734, @@ -35250,48 +35563,52 @@ const std::vector prepare_follow_hair = {119734787, 16, 106, 105, -327775, +262244, +100, 107, -108, 104, +327775, +108, +109, +107, 106, 327761, 14, -110, -108, +111, +109, 0, 196670, 27, -110, +111, 262205, 14, -111, +112, 21, 262205, 14, -112, +113, 25, 327812, 14, -113, -111, +114, 112, +113, 262205, 14, -114, +115, 24, 327808, 14, -115, -113, +116, 114, +115, 262268, 16, +117, 116, -115, 196670, 23, -116, +117, 65789, 65592, 327734, @@ -35330,163 +35647,167 @@ const std::vector prepare_follow_hair = {119734787, 40, 262205, 14, -117, +118, 30, 196670, 37, -117, +118, 327745, 73, -118, +119, 71, 72, 262205, 14, +120, 119, -118, 327814, 14, -120, +121, 68, -119, +120, 196670, 36, -120, +121, 262205, 14, -121, +122, 30, 327745, 73, -122, +123, 71, 72, 262205, 14, +124, 123, -122, 327817, 14, +125, +122, 124, -121, -123, 196670, 33, -124, +125, 262205, 14, -125, +126, 31, 327745, 73, -126, +127, 71, 72, 262205, 14, +128, 127, -126, 327812, 14, +129, +126, 128, -125, -127, 262205, 14, -129, +130, 33, 327808, 14, -130, -128, +131, 129, +130, 196670, 32, -130, +131, 262205, 14, -131, +132, 30, 262205, 14, -132, +133, 33, 327810, 14, -133, -131, +134, 132, +133, 327745, 73, -134, +135, 71, 72, 262205, 14, +136, 135, -134, 327814, 14, +137, +134, 136, -133, -135, 196670, 35, -136, +137, 262205, 101, -137, +138, 103, 262205, 14, -138, +139, 32, 262268, 16, +140, 139, +262244, +100, +141, 138, 327775, -107, +108, +142, +141, 140, -137, -139, 327761, 14, -141, -140, +143, +142, 0, 196670, 38, -141, +143, 262205, 14, -142, +144, 32, 262205, 14, -143, +145, 36, 327812, 14, +146, 144, -142, -143, +145, 262205, 14, -145, +147, 35, 327808, 14, +148, 146, -144, -145, +147, 262268, 16, -147, -146, +149, +148, 196670, 34, -147, +149, 65789, 65592, 327734, @@ -35516,83 +35837,87 @@ const std::vector prepare_follow_hair = {119734787, 49, 262205, 14, -148, +150, 43, 327812, 14, -149, +151, 68, -148, +150, 262205, 14, -150, +152, 42, 327808, 14, +153, 151, -149, -150, +152, 196670, 44, -151, +153, 327745, 73, -152, +154, 71, 72, 262205, 14, -153, -152, +155, +154, 327814, 14, -154, +156, 68, -153, +155, 196670, 45, -154, +156, 262205, 101, -155, +157, 103, 262205, 14, -156, +158, 44, 262268, 16, -157, -156, -327775, -107, +159, 158, -155, +262244, +100, +160, 157, +327775, +108, +161, +160, +159, 327761, 14, -159, -158, +162, +161, 0, 196670, 47, -159, +162, 262205, 14, -160, +163, 44, 262205, 14, -161, +164, 45, 327812, 14, -162, -160, -161, +165, +163, +164, 196670, 46, -162, +165, 65789, 65592, 327734, @@ -35622,120 +35947,124 @@ const std::vector prepare_follow_hair = {119734787, 58, 262205, 16, -164, +167, 52, 327812, 16, -165, -163, -164, +168, +166, +167, 262205, 16, -166, +169, 51, 327808, 16, -167, -165, -166, +170, +168, +169, 196670, 53, -167, +170, 327745, 73, -168, +171, 71, 87, 262205, 14, -169, -168, +172, +171, 327808, 14, -170, -169, +173, +172, 90, 262268, 16, -171, -170, +174, +173, 262205, 16, -172, +175, 53, 327812, 16, -173, -172, -171, +176, +175, +174, 196670, 53, -173, +176, 327745, 73, -174, +177, 71, 72, 262205, 14, -175, -174, +178, +177, 327814, 14, -176, +179, 68, -175, +178, 196670, 54, -176, +179, 262205, 101, -177, +180, 103, 262205, 16, -178, +181, 53, +262244, +100, +182, +180, 327775, -107, -179, -177, -178, +108, +183, +182, +181, 327761, 14, -180, -179, +184, +183, 0, 196670, 56, -180, +184, 262205, 16, -181, +185, 53, 262205, 14, -182, +186, 54, 262268, 16, -183, -182, +187, +186, 327812, 16, -184, -181, -183, +188, +185, +187, 196670, 55, -184, +188, 65789, 65592, }; const std::vector update_follow_hair = {119734787, 65536, 524289, -312, +317, 0, 131089, 1, @@ -35755,8 +36084,8 @@ const std::vector update_follow_hair = {119734787, 4, 1852399981, 0, -187, -188, +191, +192, 393232, 4, 17, @@ -36325,7 +36654,7 @@ const std::vector update_follow_hair = {119734787, 1701869908, 0, 524293, -187, +191, 1281322087, 1818321775, 1870032457, @@ -36333,41 +36662,41 @@ const std::vector update_follow_hair = {119734787, 1145663087, 0, 393221, -188, +192, 1465871463, 1198223983, 1886744434, 17481, 458757, -189, +193, 1651469415, 1951624289, 1684955506, 1701080649, 120, 458757, -190, +194, 1633906540, 1920226156, 1231318625, 2019910766, 0, 458757, -191, +195, 1651469415, 1700162657, 2019914866, 1701080649, 120, 458757, -192, +196, 1633906540, 1919243884, 1232627060, 2019910766, 0, 524293, -193, +197, 1450014062, 1769239141, 1232299363, @@ -36375,31 +36704,23 @@ const std::vector update_follow_hair = {119734787, 1634890835, 25710, 458757, -194, +198, 1701080681, 1919895160, 1918986323, 1699570789, 109, 327685, -195, +199, 1634890867, 2035573870, 25968, 262149, -196, -1634886000, -109, -262149, 200, 1634886000, 109, 262149, -203, -1634886000, -109, -262149, -205, +204, 1634886000, 109, 262149, @@ -36422,20 +36743,28 @@ const std::vector update_follow_hair = {119734787, 215, 1634886000, 109, +262149, +217, +1634886000, +109, +262149, +219, +1634886000, +109, 327685, -227, +231, 1918986355, 1867539557, 115, 458757, -230, +234, 1953067639, 1818386789, 1936674917, 1869182057, 29550, 589830, -230, +234, 0, 1632132967, 1700164201, @@ -36444,13 +36773,13 @@ const std::vector update_follow_hair = {119734787, 1852795252, 115, 196613, -232, +236, 0, 196613, -241, +245, 105, 524293, -252, +256, 1651469415, 1866886241, 2003790956, @@ -36458,7 +36787,7 @@ const std::vector update_follow_hair = {119734787, 1850308709, 7890276, 524293, -261, +265, 1651469415, 1866886241, 2003790956, @@ -36466,16 +36795,16 @@ const std::vector update_follow_hair = {119734787, 1850303598, 7890276, 262149, -267, +271, 1952670054, 29295, 327685, -282, +286, 1819045734, 1867544431, 115, 524293, -291, +295, 1866882919, 2003790956, 1919508808, @@ -36483,13 +36812,13 @@ const std::vector update_follow_hair = {119734787, 1936090703, 29797, 393221, -308, +313, 1684104520, 1851880020, 1919903347, 109, 589830, -308, +313, 0, 1867341671, 1416389988, @@ -36498,7 +36827,7 @@ const std::vector update_follow_hair = {119734787, 1215459142, 6578533, 589830, -308, +313, 1, 1867341671, 1382835556, @@ -36507,7 +36836,7 @@ const std::vector update_follow_hair = {119734787, 1684104520, 0, 589830, -308, +313, 2, 1852396386, 1214606439, @@ -36516,12 +36845,12 @@ const std::vector update_follow_hair = {119734787, 1836216166, 0, 327686, -308, +313, 3, 1684300144, 6778473, 196613, -310, +315, 0, 327752, 69, @@ -36688,87 +37017,87 @@ const std::vector update_follow_hair = {119734787, 33, 22, 262215, -187, +191, 11, 27, 262215, -188, +192, 11, 26, 262215, -229, +233, 6, 16, 327752, -230, +234, 0, 35, 0, 196679, -230, +234, 3, 262215, -232, +236, 34, 1, 262215, -232, +236, 33, 7, 262215, -291, +295, 34, 1, 262215, -291, +295, 33, 25, 262215, -307, +312, 6, 16, 262216, -308, +313, 0, 5, 327752, -308, +313, 0, 35, 0, 327752, -308, +313, 0, 7, 16, 327752, -308, +313, 1, 35, 64, 327752, -308, +313, 2, 35, 80, 327752, -308, +313, 3, 35, 96, 196679, -308, +313, 3, 262215, -310, +315, 34, 0, 262215, -310, +315, 33, 27, 262215, -311, +316, 11, 25, 131091, @@ -36931,105 +37260,105 @@ const std::vector update_follow_hair = {119734787, 103, 0, 262167, -107, +108, 14, 4, 262187, 14, -109, +110, 0, 262187, 16, -163, +166, 64, 262167, -185, +189, 14, 3, 262176, -186, +190, 1, -185, +189, 262203, -186, -187, +190, +191, 1, 262203, -186, -188, +190, +192, 1, 262176, -197, +201, 1, 14, 262172, -225, +229, 7, 68, 262176, -226, +230, 4, -225, +229, 262203, -226, -227, +230, +231, 4, 196637, -229, +233, 7, 196638, -230, -229, +234, +233, 262176, -231, +235, 2, -230, +234, 262203, -231, -232, +235, +236, 2, 262187, 16, -233, +237, 0, 262176, -235, +239, 2, 7, 262176, -238, +242, 4, 7, 262187, 14, -240, -4062, +244, +2, 262187, 16, -257, +261, 1, 262187, 16, -268, +272, 26, 262176, -269, +273, 2, 6, 262187, 6, -278, +282, 1065353216, 262167, -280, +284, 6, 3, 262176, -281, +285, 7, -280, +284, 589849, -288, +292, 6, 5, 0, @@ -37038,41 +37367,41 @@ const std::vector update_follow_hair = {119734787, 1, 0, 196635, -289, -288, +293, +292, 262176, -290, +294, 0, -289, +293, 262203, -290, -291, +294, +295, 0, 262168, -306, +311, 7, 4, 262172, -307, +312, 6, 59, 393246, -308, -306, +313, +311, 7, 16, -307, +312, 262176, -309, +314, 2, -308, +313, 262203, -309, -310, +314, +315, 2, 393260, -185, -311, +189, +316, 68, 90, 90, @@ -37085,510 +37414,511 @@ const std::vector update_follow_hair = {119734787, 5, 262203, 15, -189, +193, 7, 262203, 15, -190, +194, 7, 262203, 17, -191, +195, 7, 262203, 15, -192, +196, 7, 262203, 15, -193, +197, 7, 262203, 15, -194, +198, 7, 262203, 15, -195, +199, 7, 262203, 15, -196, +200, 7, 262203, 15, -200, +204, 7, 262203, 15, -203, +207, 7, 262203, 15, -205, +209, 7, 262203, 17, -207, +211, 7, 262203, 15, -209, +213, 7, 262203, 15, -211, +215, 7, 262203, 15, -213, +217, 7, 262203, 15, -215, +219, 7, 262203, 17, -241, +245, 7, 262203, 17, -252, +256, 7, 262203, 17, -261, +265, 7, 262203, 60, -267, +271, 7, 262203, -281, -282, +285, +286, 7, 327745, -197, -198, -187, -109, -262205, -14, -199, -198, -196670, -196, -199, -327745, -197, 201, -188, -109, +202, +191, +110, 262205, 14, +203, 202, -201, 196670, 200, -202, -262205, -14, -204, -189, -196670, 203, -204, +327745, +201, +205, +192, +110, 262205, 14, 206, -190, -196670, 205, +196670, +204, 206, 262205, -16, +14, 208, -191, +193, 196670, 207, 208, 262205, 14, 210, -192, +194, 196670, 209, 210, 262205, -14, +16, 212, -193, +195, 196670, 211, 212, 262205, 14, 214, -194, +196, 196670, 213, 214, 262205, 14, 216, -195, +197, 196670, 215, 216, -852025, -2, -217, -28, -196, -200, -203, -205, -207, -209, -211, -213, -215, 262205, 14, 218, -203, +198, 196670, -189, +217, 218, 262205, 14, -219, -205, -196670, -190, -219, -262205, -16, 220, -207, +199, 196670, -191, +219, 220, -262205, -14, +852025, +2, 221, +28, +200, +204, +207, 209, -196670, -192, -221, +211, +213, +215, +217, +219, 262205, 14, 222, -211, +207, 196670, 193, 222, 262205, 14, 223, -213, +209, 196670, 194, 223, 262205, -14, +16, 224, -215, +211, 196670, 195, 224, 262205, 14, +225, +213, +196670, +196, +225, +262205, +14, +226, +215, +196670, +197, +226, +262205, +14, +227, +217, +196670, +198, +227, +262205, +14, 228, -194, +219, +196670, +199, +228, +262205, +14, +232, +198, 262205, 16, -234, -191, +238, +195, 393281, -235, +239, +240, 236, -232, -233, -234, +237, +238, 262205, 7, -237, -236, +241, +240, 327745, -238, -239, -227, -228, +242, +243, +231, +232, 196670, -239, -237, -196833, -90, -240, +243, +241, 262368, +244, 90, -90, -109, +110, 196670, -241, -233, +245, +237, 131321, -242, +246, 131320, -242, +246, 262390, -244, -245, +248, +249, 0, 131321, -246, +250, 131320, -246, +250, 262205, 16, -247, -241, +251, +245, 262268, 14, -248, -247, +252, +251, 327745, 73, -249, +253, 71, 87, 262205, 14, -250, -249, +254, +253, 327856, 9, -251, -248, -250, +255, +252, +254, 262394, -251, -243, -244, +255, +247, +248, 131320, -243, +247, 262205, 16, -253, -191, +257, +195, 262205, 14, -254, -193, +258, +197, 262268, 16, -255, -254, +259, +258, 262205, 16, -256, -241, +260, +245, 327808, 16, -258, -256, -257, +262, +260, +261, 327812, 16, +263, 259, -255, -258, +262, 327808, 16, -260, -253, -259, +264, +257, +263, 196670, -252, -260, +256, +264, 262205, 14, -262, -189, +266, +193, 262268, 16, -263, -262, +267, +266, 262205, 16, -264, -241, +268, +245, 327808, 16, -265, -263, -264, +269, +267, +268, 327808, 16, -266, -265, -257, -196670, -261, -266, -327745, +270, 269, +261, +196670, +265, 270, +327745, +273, +274, 71, -268, +272, 262205, 6, -271, -270, +275, +274, 262205, 14, -272, -192, +276, +196, 262256, 6, -273, -272, +277, +276, 262205, 14, -274, -193, +278, +197, 262256, 6, -275, -274, +279, +278, 327816, 6, -276, -273, -275, +280, +277, +279, 327813, 6, -277, -271, -276, +281, +275, +280, 327809, 6, -279, -277, -278, +283, +281, +282, 196670, -267, -279, +271, +283, 262205, 14, -283, -194, +287, +198, 327745, -238, -284, -227, -283, +242, +288, +231, +287, 262205, 7, -285, -284, +289, +288, 524367, -280, -286, -285, -285, +284, +290, +289, +289, 0, 1, 2, 262205, 6, -287, -267, -262205, -289, -292, 291, +271, 262205, -16, 293, -261, +296, +295, +262205, +16, +297, +265, +262244, +292, +298, +296, 327775, 7, -294, -292, -293, +299, +298, +297, 524367, -280, -295, -294, -294, +284, +300, +299, +299, 0, 1, 2, 327822, -280, -296, -295, -287, +284, +301, +300, +291, 327809, -280, -297, -286, -296, +284, +302, +290, +301, 196670, -282, -297, +286, +302, 262205, 16, -298, -252, +303, +256, 262205, -280, -299, -282, +284, +304, +286, 393281, -235, -300, -232, -233, -298, +239, +305, +236, +237, +303, 262205, 7, -301, -300, +306, +305, 589903, 7, -302, -301, -299, +307, +306, +304, 4, 5, 6, 3, 196670, -300, -302, +305, +307, 131321, -245, +249, 131320, -245, +249, 262205, 16, -303, -241, +308, +245, 327808, 16, -304, -303, -257, +309, +308, +261, 196670, -241, -304, +245, +309, 131321, -242, +246, 131320, -244, +248, 65789, 65592, 327734, @@ -37795,48 +38125,52 @@ const std::vector update_follow_hair = {119734787, 16, 106, 105, -327775, +262244, +100, 107, -108, 104, +327775, +108, +109, +107, 106, 327761, 14, -110, -108, +111, +109, 0, 196670, 27, -110, +111, 262205, 14, -111, +112, 21, 262205, 14, -112, +113, 25, 327812, 14, -113, -111, +114, 112, +113, 262205, 14, -114, +115, 24, 327808, 14, -115, -113, +116, 114, +115, 262268, 16, +117, 116, -115, 196670, 23, -116, +117, 65789, 65592, 327734, @@ -37875,163 +38209,167 @@ const std::vector update_follow_hair = {119734787, 40, 262205, 14, -117, +118, 30, 196670, 37, -117, +118, 327745, 73, -118, +119, 71, 72, 262205, 14, +120, 119, -118, 327814, 14, -120, +121, 68, -119, +120, 196670, 36, -120, +121, 262205, 14, -121, +122, 30, 327745, 73, -122, +123, 71, 72, 262205, 14, +124, 123, -122, 327817, 14, +125, +122, 124, -121, -123, 196670, 33, -124, +125, 262205, 14, -125, +126, 31, 327745, 73, -126, +127, 71, 72, 262205, 14, +128, 127, -126, 327812, 14, +129, +126, 128, -125, -127, 262205, 14, -129, +130, 33, 327808, 14, -130, -128, +131, 129, +130, 196670, 32, -130, +131, 262205, 14, -131, +132, 30, 262205, 14, -132, +133, 33, 327810, 14, -133, -131, +134, 132, +133, 327745, 73, -134, +135, 71, 72, 262205, 14, +136, 135, -134, 327814, 14, +137, +134, 136, -133, -135, 196670, 35, -136, +137, 262205, 101, -137, +138, 103, 262205, 14, -138, +139, 32, 262268, 16, +140, 139, +262244, +100, +141, 138, 327775, -107, +108, +142, +141, 140, -137, -139, 327761, 14, -141, -140, +143, +142, 0, 196670, 38, -141, +143, 262205, 14, -142, +144, 32, 262205, 14, -143, +145, 36, 327812, 14, +146, 144, -142, -143, +145, 262205, 14, -145, +147, 35, 327808, 14, +148, 146, -144, -145, +147, 262268, 16, -147, -146, +149, +148, 196670, 34, -147, +149, 65789, 65592, 327734, @@ -38061,83 +38399,87 @@ const std::vector update_follow_hair = {119734787, 49, 262205, 14, -148, +150, 43, 327812, 14, -149, +151, 68, -148, +150, 262205, 14, -150, +152, 42, 327808, 14, +153, 151, -149, -150, +152, 196670, 44, -151, +153, 327745, 73, -152, +154, 71, 72, 262205, 14, -153, -152, +155, +154, 327814, 14, -154, +156, 68, -153, +155, 196670, 45, -154, +156, 262205, 101, -155, +157, 103, 262205, 14, -156, +158, 44, 262268, 16, -157, -156, -327775, -107, +159, 158, -155, +262244, +100, +160, 157, +327775, +108, +161, +160, +159, 327761, 14, -159, -158, +162, +161, 0, 196670, 47, -159, +162, 262205, 14, -160, +163, 44, 262205, 14, -161, +164, 45, 327812, 14, -162, -160, -161, +165, +163, +164, 196670, 46, -162, +165, 65789, 65592, 327734, @@ -38167,113 +38509,117 @@ const std::vector update_follow_hair = {119734787, 58, 262205, 16, -164, +167, 52, 327812, 16, -165, -163, -164, +168, +166, +167, 262205, 16, -166, +169, 51, 327808, 16, -167, -165, -166, +170, +168, +169, 196670, 53, -167, +170, 327745, 73, -168, +171, 71, 87, 262205, 14, -169, -168, +172, +171, 327808, 14, -170, -169, +173, +172, 90, 262268, 16, -171, -170, +174, +173, 262205, 16, -172, +175, 53, 327812, 16, -173, -172, -171, +176, +175, +174, 196670, 53, -173, +176, 327745, 73, -174, +177, 71, 72, 262205, 14, -175, -174, +178, +177, 327814, 14, -176, +179, 68, -175, +178, 196670, 54, -176, +179, 262205, 101, -177, +180, 103, 262205, 16, -178, +181, 53, +262244, +100, +182, +180, 327775, -107, -179, -177, -178, +108, +183, +182, +181, 327761, 14, -180, -179, +184, +183, 0, 196670, 56, -180, +184, 262205, 16, -181, +185, 53, 262205, 14, -182, +186, 54, 262268, 16, -183, -182, +187, +186, 327812, 16, -184, -181, -183, +188, +185, +187, 196670, 55, -184, +188, 65789, 65592, }; diff --git a/amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp b/amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp index ce36111..6b5076b 100644 --- a/amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp +++ b/amd_tressfx_vulkan/src/TressFXRendererVulkan.cpp @@ -32,16 +32,8 @@ #include "TressFXPrecompiledShadersVulkan.h" #include "UtilVulkan.h" -#ifndef AMD_V_RETURN -#define AMD_V_RETURN(x) \ - { \ - vr = (x); \ - if (vr != VK_SUCCESS) \ - { \ - return vr; \ - } \ - } -#endif +// Number of depth layers to use. 2 or 3 supported. +#define SHORTCUT_NUM_DEPTHS 3 // unreferenced formal parameter #pragma warning(disable : 4100) @@ -124,12 +116,15 @@ struct PPLL_BUFFERS VkBuffer pAtomicCounterPLL_Buffer; VkDeviceMemory pAtomicCounterPLL_Memory; + // If possible PLLL head, PPLL and atomic counter use same memory block + VkDeviceMemory pSharedMemory; + int width; int height; int refCount; // reference count - delete buffers when 0 }; -PPLL_BUFFERS g_PPLBuffers = {nullptr, nullptr, nullptr, 0, 0, 0}; +PPLL_BUFFERS g_PPLBuffers = {VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, 0}; const static UINT g_HairTotalLayers = 32; @@ -142,17 +137,17 @@ namespace // Create the render pass used for the non shortcut algorithm // //---------------------------------------------------------------------------------- -VkRenderPass CreateRenderPass(VkDevice dev) +VkRenderPass CreateRenderPass(VkDevice dev, VkFormat depthStencilFormat, VkFormat colorFormat) { const VkAttachmentDescription attachments[] = { // Depth Buffer - {0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_1_BIT, + {0, depthStencilFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, // color texture - {0, VK_FORMAT_R8G8B8A8_SRGB, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, + {0, colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}}; @@ -231,7 +226,7 @@ namespace AMD // //-------------------------------------------------------------------------------------- VkResult TressFXRenderer::CreateTextureAndViews( - VkDevice pvkDevice, uint32_t texture_memory_index, VkCommandBuffer commandBuffer, + VkDevice pvkDevice, VkPhysicalDeviceMemoryProperties memProperties, VkCommandBuffer commandBuffer, VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) { VkResult vr; @@ -241,17 +236,10 @@ VkResult TressFXRenderer::CreateTextureAndViews( VkImageCreateInfo hairShadowMapInfo = getImageCreateInfo( VK_FORMAT_D32_SFLOAT, SM_HAIR_WIDTH, SM_HAIR_HEIGHT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateImage(pvkDevice, &hairShadowMapInfo, nullptr, &m_pSMHairTexture)); - VkMemoryRequirements mem_requirement; - vkGetImageMemoryRequirements(pvkDevice, m_pSMHairTexture, &mem_requirement); - VkMemoryAllocateInfo memoryAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - nullptr, mem_requirement.size, - texture_memory_index}; - AMD_V_RETURN( - vkAllocateMemory(pvkDevice, &memoryAllocateInfo, nullptr, &m_pSMHairMemory)); - AMD_V_RETURN(vkBindImageMemory(pvkDevice, m_pSMHairTexture, m_pSMHairMemory, 0)); + m_pSMHairMemory = allocImageMemory(pvkDevice, m_pSMHairTexture, memProperties); VkImageViewCreateInfo dsvDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; dsvDesc.format = VK_FORMAT_D32_SFLOAT; @@ -260,11 +248,11 @@ VkResult TressFXRenderer::CreateTextureAndViews( dsvDesc.subresourceRange.layerCount = 1; dsvDesc.subresourceRange.levelCount = 1; dsvDesc.image = m_pSMHairTexture; - AMD_V_RETURN(vkCreateImageView(pvkDevice, &dsvDesc, nullptr, &m_pSMHairView)); + AMD_CHECKED_VULKAN_CALL(vkCreateImageView(pvkDevice, &dsvDesc, nullptr, &m_pSMHairView)); VkImageMemoryBarrier defineHairSMLayoutBarrier[] = {getImageMemoryBarrier( m_pSMHairTexture, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT)}; + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, VK_IMAGE_ASPECT_DEPTH_BIT)}; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, @@ -277,17 +265,9 @@ VkResult TressFXRenderer::CreateTextureAndViews( VkImageCreateInfo noiseTextureInfo = getImageCreateInfo( VK_FORMAT_R32G32B32A32_SFLOAT, 512, 512, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateImage(pvkDevice, &noiseTextureInfo, nullptr, &m_pNoiseTexture)); - - VkMemoryRequirements mem_requirement; - vkGetImageMemoryRequirements(pvkDevice, m_pNoiseTexture, &mem_requirement); - VkMemoryAllocateInfo memoryAllocateInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - nullptr, mem_requirement.size, - texture_memory_index}; - AMD_V_RETURN( - vkAllocateMemory(pvkDevice, &memoryAllocateInfo, nullptr, &m_pNoiseMemory)); - AMD_V_RETURN(vkBindImageMemory(pvkDevice, m_pNoiseTexture, m_pNoiseMemory, 0)); + m_pNoiseMemory = allocImageMemory(pvkDevice, m_pNoiseTexture, memProperties); XMFLOAT4 *noiseArray = new XMFLOAT4[512 * 512]; for (UINT i = 0; i < 512 * 512; i++) @@ -307,10 +287,10 @@ VkResult TressFXRenderer::CreateTextureAndViews( VkImageMemoryBarrier makeNoiseTextureTransferableBarrier[] = { getImageMemoryBarrier(m_pNoiseTexture, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)}; + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, VK_IMAGE_ASPECT_COLOR_BIT)}; - vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, AMD_ARRAY_SIZE(makeNoiseTextureTransferableBarrier), makeNoiseTextureTransferableBarrier); @@ -327,10 +307,10 @@ VkResult TressFXRenderer::CreateTextureAndViews( VkImageMemoryBarrier makeNoiseTextureSampleableBarrier[] = {getImageMemoryBarrier( m_pNoiseTexture, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)}; + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, VK_IMAGE_ASPECT_COLOR_BIT)}; - vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, AMD_ARRAY_SIZE(makeNoiseTextureSampleableBarrier), makeNoiseTextureSampleableBarrier); @@ -344,66 +324,12 @@ VkResult TressFXRenderer::CreateTextureAndViews( srDesc.subresourceRange.levelCount = 1; srDesc.image = m_pNoiseTexture; - AMD_V_RETURN(vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pNoiseView)); + AMD_CHECKED_VULKAN_CALL(vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pNoiseView)); } return VK_SUCCESS; } -//-------------------------------------------------------------------------------------- -// -// CreateVertexBuffers -// -// Creates the vertex buffers for hair rendering -// -//-------------------------------------------------------------------------------------- -VkResult TressFXRenderer::CreateVertexBuffers( - VkDevice pvkDevice, uint32_t texture_memory_index, VkCommandBuffer commandBuffer, - VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) -{ - VkResult vr; - // Create the screen quad vertex buffer(use StandardVertex for simplicity) - const StandardVertex screenQuad[6] = { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), - XMFLOAT2(0.0f, 1.0f)}, // 0 - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), - XMFLOAT2(0.0f, 0.0f)}, // 1 - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), - XMFLOAT2(1.0f, 1.0f)}, // 2 - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), - XMFLOAT2(1.0f, 1.0f)}, // 2 - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), - XMFLOAT2(0.0f, 0.0f)}, // 1 - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), - XMFLOAT2(1.0f, 0.0f)} // 3 - }; - - VkBufferCreateInfo bd{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; - bd.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - bd.size = sizeof(StandardVertex) * 6; - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &bd, nullptr, &m_pScreenQuadVB)); - - VkMemoryRequirements memReq; - vkGetBufferMemoryRequirements(pvkDevice, m_pScreenQuadVB, &memReq); - VkMemoryAllocateInfo allocInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; - allocInfo.allocationSize = memReq.size; - allocInfo.memoryTypeIndex = texture_memory_index; - AMD_V_RETURN(vkAllocateMemory(pvkDevice, &allocInfo, nullptr, &m_pScreenQuadMemory)); - AMD_V_RETURN(vkBindBufferMemory(pvkDevice, m_pScreenQuadVB, m_pScreenQuadMemory, 0)); - - void *memoryPointer; - vkMapMemory(pvkDevice, scratchMemory, offsetInScratchBuffer, - 6 * sizeof(StandardVertex), 0, &memoryPointer); - memcpy(memoryPointer, screenQuad, 6 * sizeof(StandardVertex)); - - VkBufferCopy region{offsetInScratchBuffer, 0, 6 * sizeof(StandardVertex)}; - vkCmdCopyBuffer(commandBuffer, scratchBuffer, m_pScreenQuadVB, 1, ®ion); - offsetInScratchBuffer += 6 * sizeof(StandardVertex); - vkUnmapMemory(pvkDevice, scratchMemory); - - return VK_SUCCESS; -} - //-------------------------------------------------------------------------------------- // // CreateConstantBuffers @@ -413,14 +339,14 @@ VkResult TressFXRenderer::CreateVertexBuffers( //-------------------------------------------------------------------------------------- VkResult TressFXRenderer::CreateConstantBuffer(VkDevice pvkDevice, uint32_t maxUniformBuffer, - uint32_t cpu_memory_index) + VkPhysicalDeviceMemoryProperties memProperties) { VkResult vr; VkBufferCreateInfo cbDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; cbDesc.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; cbDesc.size = maxUniformBuffer * sizeof(CB_PER_FRAME); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &cbDesc, nullptr, &m_pcbPerFrame)); - m_pcbPerFrameMemory = allocBufferMemory(pvkDevice, m_pcbPerFrame, cpu_memory_index); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &cbDesc, nullptr, &m_pcbPerFrame)); + m_pcbPerFrameMemory = allocBufferMemory(pvkDevice, m_pcbPerFrame, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); return VK_SUCCESS; } @@ -443,7 +369,7 @@ VkResult TressFXRenderer::CreateFrameBuffer(VkDevice pvkDevice, info.width = width; info.height = height; info.layers = 1; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_renderHairFramebuffer)); } @@ -455,7 +381,7 @@ VkResult TressFXRenderer::CreateFrameBuffer(VkDevice pvkDevice, info.width = SM_HAIR_WIDTH; info.height = SM_HAIR_HEIGHT; info.layers = 1; - AMD_V_RETURN(vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_shadowFrameBuffer)); + AMD_CHECKED_VULKAN_CALL(vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_shadowFrameBuffer)); return VK_SUCCESS; } @@ -474,13 +400,13 @@ VkResult TressFXRenderer::CreateSamplers(VkDevice pvkDevice) samDesc.compareOp = VK_COMPARE_OP_NEVER; samDesc.minLod = 0.f; samDesc.maxLod = 1000.f; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateSampler(pvkDevice, &samDesc, nullptr, &m_pSamplerStateLinearWrap)); samDesc.minFilter = VK_FILTER_NEAREST; samDesc.magFilter = VK_FILTER_NEAREST; samDesc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateSampler(pvkDevice, &samDesc, nullptr, &m_pSamplerStatePointClamp)); samDesc.minFilter = VK_FILTER_LINEAR; @@ -491,7 +417,7 @@ VkResult TressFXRenderer::CreateSamplers(VkDevice pvkDevice) samDesc.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; samDesc.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; samDesc.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; - AMD_V_RETURN(vkCreateSampler(pvkDevice, &samDesc, nullptr, &m_pSamplerStateCmpLess)); + AMD_CHECKED_VULKAN_CALL(vkCreateSampler(pvkDevice, &samDesc, nullptr, &m_pSamplerStateCmpLess)); return VK_SUCCESS; } @@ -503,11 +429,11 @@ VkResult TressFXRenderer::CreateSamplers(VkDevice pvkDevice) // Creates the render state objects for hair rendering // //-------------------------------------------------------------------------------------- -VkResult TressFXRenderer::CreateRenderStateObjects(VkDevice pvkDevice) +VkResult TressFXRenderer::CreateRenderStateObjects(VkDevice pvkDevice, VkFormat depthStencilFormat, VkFormat colorFormat) { VkResult vr; - m_pRPHairRendering = CreateRenderPass(pvkDevice); + m_pRPHairRendering = CreateRenderPass(pvkDevice, depthStencilFormat, colorFormat); ShaderModule fragmentShadersModule(pvkDevice, pass1_fragment); ShaderModule vertexShadersModule(pvkDevice, render_hair_aa_strand_copies_vertex); @@ -615,7 +541,7 @@ VkResult TressFXRenderer::CreateRenderStateObjects(VkDevice pvkDevice) VkPipeline pipelineArray[6] = {}; - AMD_V_RETURN(vkCreateGraphicsPipelines(pvkDevice, VK_NULL_HANDLE, + AMD_CHECKED_VULKAN_CALL(vkCreateGraphicsPipelines(pvkDevice, VK_NULL_HANDLE, AMD_ARRAY_SIZE(pipelineInfoArray), pipelineInfoArray, nullptr, pipelineArray)); @@ -638,29 +564,27 @@ VkResult TressFXRenderer::CreateRenderStateObjects(VkDevice pvkDevice) //-------------------------------------------------------------------------------------- VkResult TressFXRenderer::OnCreateDevice( VkDevice pvkDevice, int winWidth, int winHeight, bool bShortCutOn, - uint32_t maxUniformBuffer, uint32_t cpu_memory_index, uint32_t texture_memory_index, + uint32_t maxUniformBuffer, VkPhysicalDeviceMemoryProperties memProperties, VkImageView depthTexture, VkImageView colorTexture, VkCommandBuffer commandBuffer, - VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) + VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer, + VkFormat depthStencilFormat, VkFormat colorFormat) { m_pvkDevice = pvkDevice; VkResult vr; - AMD_V_RETURN(CreateTextureAndViews(pvkDevice, texture_memory_index, commandBuffer, + AMD_CHECKED_VULKAN_CALL(CreateTextureAndViews(pvkDevice, memProperties, commandBuffer, scratchMemory, scratchBuffer, offsetInScratchBuffer)); - AMD_V_RETURN(CreateConstantBuffer(pvkDevice, maxUniformBuffer, cpu_memory_index)); - AMD_V_RETURN(CreateVertexBuffers(pvkDevice, texture_memory_index, commandBuffer, - scratchMemory, scratchBuffer, - offsetInScratchBuffer)); - AMD_V_RETURN(CreateSamplers(pvkDevice)); - AMD_V_RETURN(CreateLayouts(pvkDevice)); + AMD_CHECKED_VULKAN_CALL(CreateConstantBuffer(pvkDevice, maxUniformBuffer, memProperties)); + AMD_CHECKED_VULKAN_CALL(CreateSamplers(pvkDevice)); + AMD_CHECKED_VULKAN_CALL(CreateLayouts(pvkDevice)); if (!bShortCutOn) { - AMD_V_RETURN( - CreatePPLL(pvkDevice, winWidth, winHeight, false, texture_memory_index)); + AMD_CHECKED_VULKAN_CALL( + CreatePPLL(pvkDevice, winWidth, winHeight, false, memProperties)); VkImageMemoryBarrier defineHeadPPLLBarrier[] = {getImageMemoryBarrier( m_pHeadPPLLTexture, 0, VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL)}; + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 1, VK_IMAGE_ASPECT_COLOR_BIT)}; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, AMD_ARRAY_SIZE(defineHeadPPLLBarrier), @@ -672,31 +596,32 @@ VkResult TressFXRenderer::OnCreateDevice( m_pSamplerStateLinearWrap, m_pSamplerStatePointClamp, depthTexture, colorTexture, m_pcbPerFrame, sizeof(CB_PER_FRAME), m_pNoiseView, m_pSMHairView, - texture_memory_index, winWidth, winHeight); + memProperties, winWidth, winHeight, depthStencilFormat, colorFormat); VkImageMemoryBarrier barriers[] = { getImageMemoryBarrier(m_ShortCut.m_pAccumInvAlphaTexture, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, VK_IMAGE_ASPECT_COLOR_BIT), getImageMemoryBarrier(m_ShortCut.m_pFragmentDepthsTexture, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL), + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, + SHORTCUT_NUM_DEPTHS, VK_IMAGE_ASPECT_COLOR_BIT), getImageMemoryBarrier(m_ShortCut.m_pFragmentColorsTexture, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)}; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, VK_IMAGE_ASPECT_COLOR_BIT)}; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, AMD_ARRAY_SIZE(barriers), barriers); } - AMD_V_RETURN(CreateRenderStateObjects(pvkDevice)); - AMD_V_RETURN(AllocateAndPopulateSets(pvkDevice, bShortCutOn)); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL(CreateRenderStateObjects(pvkDevice, depthStencilFormat, colorFormat)); + AMD_CHECKED_VULKAN_CALL(AllocateAndPopulateSets(pvkDevice, bShortCutOn)); + AMD_CHECKED_VULKAN_CALL( CreateFrameBuffer(pvkDevice, depthTexture, colorTexture, winWidth, winHeight)); return VK_SUCCESS; @@ -726,7 +651,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) {IDSRV_HAIR_THICKNESSES, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT}, }; - AMD_V_RETURN(getDescriptorLayout(pvkDevice, pass1_hair_bindings, + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, pass1_hair_bindings, AMD_ARRAY_SIZE(pass1_hair_bindings), m_pass1_hair_set_layout)); } @@ -753,7 +678,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) {IDSRV_NOISEMAP, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT}, }; - AMD_V_RETURN(getDescriptorLayout(pvkDevice, pass1_config_bindings, + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, pass1_config_bindings, AMD_ARRAY_SIZE(pass1_config_bindings), m_pass1_config_set_layout)); } @@ -763,7 +688,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) VkPipelineLayoutCreateInfo pipelineLayoutInfo{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, AMD_ARRAY_SIZE(pass1_descriptor_set_layouts), pass1_descriptor_set_layouts}; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreatePipelineLayout(pvkDevice, &pipelineLayoutInfo, nullptr, &m_pass1_layout)); // Pass 2 set layout @@ -785,7 +710,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) {IDSRV_SHADOW_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &m_pSamplerStatePointClamp}, }; - AMD_V_RETURN(getDescriptorLayout(pvkDevice, pass2_bindings, + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, pass2_bindings, AMD_ARRAY_SIZE(pass2_bindings), m_pass2_set_layout)); } @@ -793,7 +718,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) VkPipelineLayoutCreateInfo pass2PipelineLayoutInfo{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &m_pass2_set_layout}; - AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &pass2PipelineLayoutInfo, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreatePipelineLayout(pvkDevice, &pass2PipelineLayoutInfo, nullptr, &m_pass2_layout)); // Shadow pass model dependent set layout @@ -803,7 +728,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT}, }; - AMD_V_RETURN(getDescriptorLayout(pvkDevice, shadow_pass_hair_bindings, + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, shadow_pass_hair_bindings, AMD_ARRAY_SIZE(shadow_pass_hair_bindings), m_shadow_pass_hair_set_layout)); } @@ -814,7 +739,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) // TressFX parameters {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT}}; - AMD_V_RETURN(getDescriptorLayout(pvkDevice, shadow_pass_config_bindings, + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, shadow_pass_config_bindings, AMD_ARRAY_SIZE(shadow_pass_config_bindings), m_shadow_pass_config_set_layout)); } @@ -825,7 +750,7 @@ VkResult TressFXRenderer::CreateLayouts(VkDevice pvkDevice) VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, AMD_ARRAY_SIZE(shadow_pass_descriptor_set_layouts), shadow_pass_descriptor_set_layouts}; - AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &shadowPassPipelineLayoutInfo, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreatePipelineLayout(pvkDevice, &shadowPassPipelineLayoutInfo, nullptr, &m_shadow_pass_layout)); return VK_SUCCESS; @@ -854,43 +779,27 @@ VkResult TressFXRenderer::AllocateAndPopulateSets(VkDevice pvkDevice, bool isSho descriptorPoolCreateInfo.maxSets = 3; descriptorPoolCreateInfo.poolSizeCount = AMD_ARRAY_SIZE(descriptorPoolSize); descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSize; - AMD_V_RETURN(vkCreateDescriptorPool(pvkDevice, &descriptorPoolCreateInfo, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateDescriptorPool(pvkDevice, &descriptorPoolCreateInfo, nullptr, &m_descriptorStorage)); + VkDescriptorBufferInfo bufferDescriptor{m_pcbPerFrame, 0, sizeof(CB_PER_FRAME)}; + VkDescriptorSetAllocateInfo allocateInfo{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + allocateInfo.descriptorPool = m_descriptorStorage; + allocateInfo.descriptorSetCount = 1; + allocateInfo.pSetLayouts = &m_shadow_pass_config_set_layout; + AMD_CHECKED_VULKAN_CALL( + vkAllocateDescriptorSets(pvkDevice, &allocateInfo, &m_shadow_pass_set)); if (!isShortcut) { - VkDescriptorSetAllocateInfo allocateInfo{ - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; - allocateInfo.descriptorPool = m_descriptorStorage; allocateInfo.descriptorSetCount = 1; allocateInfo.pSetLayouts = &m_pass1_config_set_layout; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkAllocateDescriptorSets(pvkDevice, &allocateInfo, &m_pass1_config_set)); - } - - if (!isShortcut) - { - VkDescriptorSetAllocateInfo allocate2Info{ - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; - allocate2Info.descriptorPool = m_descriptorStorage; - allocate2Info.descriptorSetCount = 1; - allocate2Info.pSetLayouts = &m_pass2_set_layout; - AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &allocate2Info, &m_pass2_set)); - } - { - VkDescriptorSetAllocateInfo allocate3Info{ - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; - allocate3Info.descriptorPool = m_descriptorStorage; - allocate3Info.descriptorSetCount = 1; - allocate3Info.pSetLayouts = &m_shadow_pass_config_set_layout; - AMD_V_RETURN( - vkAllocateDescriptorSets(pvkDevice, &allocate3Info, &m_shadow_pass_set)); - } - - VkDescriptorBufferInfo bufferDescriptor{m_pcbPerFrame, 0, sizeof(CB_PER_FRAME)}; - if (!isShortcut) - { + allocateInfo.descriptorSetCount = 1; + allocateInfo.pSetLayouts = &m_pass2_set_layout; + AMD_CHECKED_VULKAN_CALL(vkAllocateDescriptorSets(pvkDevice, &allocateInfo, &m_pass2_set)); VkDescriptorBufferInfo atomicCounterDescriptor{m_pAtomicCounterPPLLBuffer, 0, sizeof(unsigned int)}; @@ -960,7 +869,7 @@ VkResult TressFXRenderer::AllocateAndPopulateSets(VkDevice pvkDevice, bool isSho // //-------------------------------------------------------------------------------------- VkResult TressFXRenderer::CreatePPLL(VkDevice pvkDevice, int winWidth, int winHeight, - bool resize, uint32_t texture_memory_index) + bool resize, VkPhysicalDeviceMemoryProperties memProperties) { VkResult vr; @@ -968,52 +877,78 @@ VkResult TressFXRenderer::CreatePPLL(VkDevice pvkDevice, int winWidth, int winHe if ((winWidth != g_PPLBuffers.width) || (winHeight != g_PPLBuffers.height) || (g_PPLBuffers.refCount == 0)) { - // Release any previously allocated buffers - // AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_Buffer); - // AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_SRV); - // AMD_SAFE_RELEASE(g_PPLBuffers.pHeadPPLL_UAV); - // AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_Buffer); - // AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_UAV); - // AMD_SAFE_RELEASE(g_PPLBuffers.pPPLL_SRV); - // linked list head texture VkImageCreateInfo headPPLLInfo = getImageCreateInfo(VK_FORMAT_R32_UINT, winWidth, winHeight, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT); - AMD_V_RETURN(vkCreateImage(pvkDevice, &headPPLLInfo, nullptr, + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + AMD_CHECKED_VULKAN_CALL(vkCreateImage(pvkDevice, &headPPLLInfo, nullptr, &g_PPLBuffers.pHeadPPLL_Buffer)); - g_PPLBuffers.pHeadPPLL_Memory = allocImageMemory( - pvkDevice, g_PPLBuffers.pHeadPPLL_Buffer, texture_memory_index); - - // View for linked list head - VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; - srDesc.format = VK_FORMAT_R32_UINT; - srDesc.viewType = VK_IMAGE_VIEW_TYPE_2D; - srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - srDesc.subresourceRange.layerCount = 1; - srDesc.subresourceRange.levelCount = 1; - srDesc.image = g_PPLBuffers.pHeadPPLL_Buffer; - AMD_V_RETURN( - vkCreateImageView(pvkDevice, &srDesc, nullptr, &g_PPLBuffers.pHeadPPLL_View)); // Per-pixel Linked List (PPLL) buffer VkBufferCreateInfo BufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; BufferDesc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; BufferDesc.size = (DWORD)(g_HairTotalLayers * winWidth * winHeight * sizeof(PER_PIXEL_LINKED_LIST_STRUCT)); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateBuffer(pvkDevice, &BufferDesc, nullptr, &g_PPLBuffers.pPPLL_Buffer)); - g_PPLBuffers.pPPLL_Memory = - allocBufferMemory(pvkDevice, g_PPLBuffers.pPPLL_Buffer, texture_memory_index); // Atomic counter buffer BufferDesc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; BufferDesc.size = sizeof(unsigned int); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &BufferDesc, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &BufferDesc, nullptr, &g_PPLBuffers.pAtomicCounterPLL_Buffer)); - g_PPLBuffers.pAtomicCounterPLL_Memory = allocBufferMemory( - pvkDevice, g_PPLBuffers.pAtomicCounterPLL_Buffer, texture_memory_index); + + VkMemoryRequirements headPPLLMemReq; + vkGetImageMemoryRequirements(pvkDevice, g_PPLBuffers.pHeadPPLL_Buffer, &headPPLLMemReq); + VkMemoryRequirements PPLBufferMemReq; + vkGetBufferMemoryRequirements(pvkDevice, g_PPLBuffers.pPPLL_Buffer, &PPLBufferMemReq); + VkMemoryRequirements atomicBufferMemReq; + vkGetBufferMemoryRequirements(pvkDevice, g_PPLBuffers.pAtomicCounterPLL_Buffer, &atomicBufferMemReq); + + uint32_t typeBits = headPPLLMemReq.memoryTypeBits & PPLBufferMemReq.memoryTypeBits & atomicBufferMemReq.memoryTypeBits; + uint32_t memoryType = getMemoryTypeIndex(typeBits, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + if (memoryType == -1) + { + // Split in 3 + g_PPLBuffers.pHeadPPLL_Memory = allocImageMemory( + pvkDevice, g_PPLBuffers.pHeadPPLL_Buffer, memProperties); + + g_PPLBuffers.pPPLL_Memory = + allocBufferMemory(pvkDevice, g_PPLBuffers.pPPLL_Buffer, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + g_PPLBuffers.pAtomicCounterPLL_Memory = allocBufferMemory( + pvkDevice, g_PPLBuffers.pAtomicCounterPLL_Buffer, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + } + else + { + VkDeviceSize PPLBufferOffset = align(headPPLLMemReq.size, PPLBufferMemReq.alignment); + VkDeviceSize atomicBufferOffset = align(PPLBufferOffset + PPLBufferMemReq.size, atomicBufferMemReq.alignment); + VkDeviceSize totalSize = atomicBufferOffset + atomicBufferMemReq.size; + + VkMemoryAllocateInfo allocate{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + allocate.allocationSize = totalSize; + allocate.memoryTypeIndex = memoryType; + AMD_CHECKED_VULKAN_CALL(vkAllocateMemory(pvkDevice, &allocate, NULL, &g_PPLBuffers.pSharedMemory)); + + AMD_CHECKED_VULKAN_CALL(vkBindImageMemory(pvkDevice, g_PPLBuffers.pHeadPPLL_Buffer, g_PPLBuffers.pSharedMemory, 0)); + AMD_CHECKED_VULKAN_CALL(vkBindBufferMemory(pvkDevice, g_PPLBuffers.pPPLL_Buffer, g_PPLBuffers.pSharedMemory, PPLBufferOffset)); + AMD_CHECKED_VULKAN_CALL(vkBindBufferMemory(pvkDevice, g_PPLBuffers.pAtomicCounterPLL_Buffer, g_PPLBuffers.pSharedMemory, atomicBufferOffset)); + } + + + // View for linked list head + VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + srDesc.format = VK_FORMAT_R32_UINT; + srDesc.viewType = VK_IMAGE_VIEW_TYPE_2D; + srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + srDesc.subresourceRange.layerCount = 1; + srDesc.subresourceRange.levelCount = 1; + srDesc.image = g_PPLBuffers.pHeadPPLL_Buffer; + AMD_CHECKED_VULKAN_CALL( + vkCreateImageView(pvkDevice, &srDesc, nullptr, &g_PPLBuffers.pHeadPPLL_View)); + + // update the width and height g_PPLBuffers.width = winWidth; @@ -1071,6 +1006,7 @@ void TressFXRenderer::DeletePPLL(VkDevice pvkDevice) AMD_SAFE_RELEASE(g_PPLBuffers.pAtomicCounterPLL_Buffer, vkDestroyBuffer, pvkDevice); AMD_SAFE_RELEASE(g_PPLBuffers.pAtomicCounterPLL_Memory, vkFreeMemory, pvkDevice); + AMD_SAFE_RELEASE(g_PPLBuffers.pSharedMemory, vkFreeMemory, pvkDevice); g_PPLBuffers.width = 0; g_PPLBuffers.height = 0; @@ -1087,16 +1023,16 @@ void TressFXRenderer::DeletePPLL(VkDevice pvkDevice) //-------------------------------------------------------------------------------------- VkResult TressFXRenderer::OnResizedSwapChain(VkDevice pvkDevice, int width, int height, bool bShortCutOn, - uint32_t texture_memory_index) + VkPhysicalDeviceMemoryProperties memProperties) { VkResult vr; if (bShortCutOn) { - // AMD_V_RETURN(m_ShortCut.OnResizedSwapChain(pd3dDevice, width, height)); + // AMD_CHECKED_VULKAN_CALL(m_ShortCut.OnResizedSwapChain(pd3dDevice, width, height)); } else { - AMD_V_RETURN(CreatePPLL(pvkDevice, width, height, true, texture_memory_index)); + AMD_CHECKED_VULKAN_CALL(CreatePPLL(pvkDevice, width, height, true, memProperties)); } return VK_SUCCESS; } @@ -1230,7 +1166,7 @@ void TressFXRenderer::BeginHairFrame( // // RenderScreenQuad // -// Renders a full screen quad +// Renders a triangle big enough to cover whole screen // ////-------------------------------------------------------------------------------------- void TressFXRenderer::RenderScreenQuad(VkCommandBuffer cmdbuffer, VkPipeline pPipeline) @@ -1238,11 +1174,8 @@ void TressFXRenderer::RenderScreenQuad(VkCommandBuffer cmdbuffer, VkPipeline pPi // set shader vkCmdBindPipeline(cmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pPipeline); - VkDeviceSize offsets = 0; - vkCmdBindVertexBuffers(cmdbuffer, 0, 1, &m_pScreenQuadVB, &offsets); - - // Draw full screen quad - vkCmdDraw(cmdbuffer, 6, 1, 0, 0); + // Draw full screen triangle + vkCmdDraw(cmdbuffer, 3, 1, 0, 0); } //-------------------------------------------------------------------------------------- @@ -1252,8 +1185,10 @@ void TressFXRenderer::RenderScreenQuad(VkCommandBuffer cmdbuffer, VkPipeline pPi // Renders the hair from the point of view of the light into a shadow map // //-------------------------------------------------------------------------------------- -void TressFXRenderer::GenerateShadowMap(VkDevice pvkDevice, VkCommandBuffer commandBuffer, - float density, uint32_t uniformBufferIndex) +void TressFXRenderer::GenerateShadowMap(VkDevice pvkDevice, + VkCommandBuffer commandBuffer, + float density, uint32_t uniformBufferIndex, + const DebugMarkerPointer& markerCallbacks) { VkViewport viewport{0.f, 0.f, SM_HAIR_WIDTH, SM_HAIR_HEIGHT, 0.f, 1.f}; vkCmdSetViewport(commandBuffer, 0, 1, &viewport); @@ -1268,6 +1203,7 @@ void TressFXRenderer::GenerateShadowMap(VkDevice pvkDevice, VkCommandBuffer comm depthClear.depthStencil.depth = 1.f; info.pClearValues = &depthClear; info.renderArea.extent = {SM_HAIR_WIDTH, SM_HAIR_HEIGHT}; + markerCallbacks.markBeginRegion(commandBuffer, "Shadowmap"); vkCmdBeginRenderPass(commandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pPLGenerateHairSM); @@ -1281,6 +1217,7 @@ void TressFXRenderer::GenerateShadowMap(VkDevice pvkDevice, VkCommandBuffer comm vkCmdDrawIndexed(commandBuffer, UINT(density * m_pTressFXMesh->m_TotalIndexCount), 1, 0, 0, 0); vkCmdEndRenderPass(commandBuffer); + markerCallbacks.markEndRegion(commandBuffer); } //-------------------------------------------------------------------------------------- @@ -1295,13 +1232,16 @@ void TressFXRenderer::GenerateShadowMap(VkDevice pvkDevice, VkCommandBuffer comm // and blends the nearest k fragments (K-buffer) in back to front order. // ////-------------------------------------------------------------------------------------- -void TressFXRenderer::RenderHair(VkDevice pvkDevice, VkCommandBuffer commandBuffer, - uint32_t width, uint32_t height, - uint32_t uniformBufferIndex) +void TressFXRenderer::RenderHair(VkDevice pvkDevice, + VkCommandBuffer commandBuffer, + uint32_t width, + uint32_t height, + uint32_t uniformBufferIndex, const DebugMarkerPointer& markerCallbacks) { // Caller must rebind original render target and depth stencil view after call // render hair + markerCallbacks.markBeginRegion(commandBuffer, "RenderHair"); // Clear HeadPPLL buffer as it's not an attachment VkClearColorValue dwClearDataMinusOne{}; @@ -1385,11 +1325,14 @@ void TressFXRenderer::RenderHair(VkDevice pvkDevice, VkCommandBuffer commandBuff AMD_ARRAY_SIZE(descriptorOffsets), descriptorOffsets); RenderScreenQuad(commandBuffer, m_pPLResolveKBuffer); vkCmdEndRenderPass(commandBuffer); + markerCallbacks.markEndRegion(commandBuffer); } void TressFXRenderer::RenderHairShortcut(VkDevice pvkDevice, - VkCommandBuffer commandBuffer, uint32_t width, - uint32_t height, uint32_t uniformBufferIndex) + + VkCommandBuffer commandBuffer, + uint32_t width, + uint32_t height, uint32_t uniformBufferIndex, const DebugMarkerPointer& markerCallbacks) { m_ShortCut.SetupDepthPass(pvkDevice, commandBuffer, width, height); @@ -1513,9 +1456,6 @@ void TressFXRenderer::OnDestroy() { m_ShortCut.OnDestroy(true); - AMD_SAFE_RELEASE(m_pScreenQuadVB, vkDestroyBuffer, m_pvkDevice); - AMD_SAFE_RELEASE(m_pScreenQuadMemory, vkFreeMemory, m_pvkDevice); - { AMD_SAFE_RELEASE(m_pPLRenderHairAAStrandCopies, vkDestroyPipeline, m_pvkDevice); AMD_SAFE_RELEASE(m_pPLRenderHairAA, vkDestroyPipeline, m_pvkDevice); diff --git a/amd_tressfx_vulkan/src/TressFXRendererVulkan.h b/amd_tressfx_vulkan/src/TressFXRendererVulkan.h index c373db8..1bff44f 100644 --- a/amd_tressfx_vulkan/src/TressFXRendererVulkan.h +++ b/amd_tressfx_vulkan/src/TressFXRendererVulkan.h @@ -97,10 +97,6 @@ class TressFXRenderer VkDeviceMemory m_pSMHairMemory; VkImageView m_pSMHairView; - // vertex buffer for full screen quad - VkBuffer m_pScreenQuadVB; - VkDeviceMemory m_pScreenQuadMemory; - TressFXShortCut m_ShortCut; VkImageView m_depthBuffer; @@ -122,20 +118,16 @@ class TressFXRenderer VkResult CreateFrameBuffer(VkDevice pvkDevice, VkImageView depthTextureView, VkImageView colorTextureView, uint32_t width, uint32_t height); - VkResult CreateTextureAndViews(VkDevice pvkDevice, uint32_t MemoryIndexGPU, + VkResult CreateTextureAndViews(VkDevice pvkDevice, VkPhysicalDeviceMemoryProperties memProperties, VkCommandBuffer commandBuffer, VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer); VkResult CreateConstantBuffer(VkDevice pvkDevice, uint32_t maxUniformBuffer, - uint32_t MemoryIndexCPU); - VkResult CreateVertexBuffers(VkDevice pvkDevice, uint32_t MemoryIndexGPU, - VkCommandBuffer commandBuffer, - VkDeviceMemory scratchMemory, VkBuffer scratchBuffer, - size_t &offsetInScratchBuffer); + VkPhysicalDeviceMemoryProperties memProperties); VkResult CreateSamplers(VkDevice pvkDevice); - VkResult CreateRenderStateObjects(VkDevice pvkDevice); + VkResult CreateRenderStateObjects(VkDevice pvkDevice, VkFormat depthStencilFormat, VkFormat colorFormat); VkResult CreatePPLL(VkDevice pvkDevice, int winWidth, int winHeight, bool resize, - uint32_t MemoryIndexGPU); + VkPhysicalDeviceMemoryProperties memProperties); VkResult CreateLayouts(VkDevice pvkDevice); VkResult AllocateAndPopulateSets(VkDevice pvkDevice, bool isShortcut); void DeletePPLL(VkDevice pvkDevice); @@ -148,12 +140,13 @@ class TressFXRenderer VkImageView GetShadowMapSRV() { return m_pSMHairView; }; VkResult OnCreateDevice(VkDevice pvkDevice, int winWidth, int winHeight, bool bShortCutOn, uint32_t maxUniformBuffer, - uint32_t MemoryIndexCPU, uint32_t MemoryIndexGPU, + VkPhysicalDeviceMemoryProperties memProperties, VkImageView depthTexture, VkImageView colorTexture, VkCommandBuffer commandBuffer, VkDeviceMemory scratchMemory, - VkBuffer scratchBuffer, size_t &offsetInScratchBuffer); + VkBuffer scratchBuffer, size_t &offsetInScratchBuffer, + VkFormat depthStencilFormat, VkFormat colorFormat); VkResult OnResizedSwapChain(VkDevice pvkDevice, int winWidth, int WinHeight, - bool bShortCutOn, uint32_t MemoryIndexGPU); + bool bShortCutOn, VkPhysicalDeviceMemoryProperties memProperties); void BeginHairFrame(VkDevice pvkDevice, DirectX::XMVECTOR eyePoint, DirectX::XMVECTOR lightPosition, DirectX::XMMATRIX *pModelTrasnsformForHead, @@ -161,12 +154,18 @@ class TressFXRenderer DirectX::XMMATRIX *pViewProjLightOut, float screenWidth, float screenHeight, bool singleHeadTransform, uint32_t uniformBufferIndex); - void GenerateShadowMap(VkDevice pvkDevice, VkCommandBuffer commandBuffer, - float density, uint32_t uniformBufferIndex); - void RenderHair(VkDevice pvkDevice, VkCommandBuffer commandBuffer, uint32_t width, - uint32_t height, uint32_t uniformBufferIndex); - void RenderHairShortcut(VkDevice pvkDevice, VkCommandBuffer commandBuffer, - uint32_t width, uint32_t height, uint32_t uniformBufferIndex); + void GenerateShadowMap(VkDevice pvkDevice, + VkCommandBuffer commandBuffer, + float density, uint32_t uniformBufferIndex, + const DebugMarkerPointer& markerCallbacks); + void RenderHair(VkDevice pvkDevice, VkCommandBuffer commandBuffer, + uint32_t width, + uint32_t height, uint32_t uniformBufferIndex, + const DebugMarkerPointer& markerCallbacks); + void RenderHairShortcut(VkDevice pvkDevice, + VkCommandBuffer commandBuffer, + uint32_t width, uint32_t height, uint32_t uniformBufferIndex, + const DebugMarkerPointer& markerCallbacks); void EndHairFrame(VkDevice pvkDevice); void OnDestroy(); }; diff --git a/amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp index 852e76f..2a91d61 100644 --- a/amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp +++ b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.cpp @@ -32,17 +32,6 @@ #include "UtilVulkan.h" #include -#ifndef AMD_V_RETURN -#define AMD_V_RETURN(x) \ - { \ - vr = (x); \ - if (vr != VK_SUCCESS) \ - { \ - return vr; \ - } \ - } -#endif - // unreferenced formal parameter #pragma warning(disable : 4100) @@ -73,7 +62,7 @@ VkResult GPUOnlyStructuredBuffer::Create(VkDevice pvkDevice, uint32_t structSize VkBufferCreateInfo BufferDesc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; BufferDesc.size = structCount * structSize; BufferDesc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &BufferDesc, NULL, &m_pBuffer)); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &BufferDesc, NULL, &m_pBuffer)); m_pvkDevice = pvkDevice; return VK_SUCCESS; @@ -87,7 +76,7 @@ void GPUOnlyStructuredBuffer::Destroy() VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidth, int winHeight, - uint32_t texture_memory_index) + VkPhysicalDeviceMemoryProperties memProperties) { m_pvkDevice = pvkDevice; VkResult vr; @@ -96,10 +85,10 @@ VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidt VK_FORMAT_R16_SFLOAT, winWidth, winHeight, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); - AMD_V_RETURN(vkCreateImage(pvkDevice, &accumInvAlphaInfo, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateImage(pvkDevice, &accumInvAlphaInfo, nullptr, &m_pAccumInvAlphaTexture)); m_pAccumInvAlphaMemory = - allocImageMemory(pvkDevice, m_pAccumInvAlphaTexture, texture_memory_index); + allocImageMemory(pvkDevice, m_pAccumInvAlphaTexture, memProperties); VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; srDesc.format = VK_FORMAT_R16_SFLOAT; @@ -108,7 +97,7 @@ VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidt srDesc.subresourceRange.layerCount = 1; srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; srDesc.image = m_pAccumInvAlphaTexture; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pAccumInvAlphaView)); } @@ -118,11 +107,11 @@ VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidt VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, SHORTCUT_NUM_DEPTHS); - AMD_V_RETURN(vkCreateImage(pvkDevice, &fragmentDepthInfo, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateImage(pvkDevice, &fragmentDepthInfo, nullptr, &m_pFragmentDepthsTexture)); m_pFragmentDepthsMemory = - allocImageMemory(pvkDevice, m_pFragmentDepthsTexture, texture_memory_index); + allocImageMemory(pvkDevice, m_pFragmentDepthsTexture, memProperties); VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; srDesc.format = VK_FORMAT_R32_UINT; @@ -131,7 +120,7 @@ VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidt srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; srDesc.subresourceRange.layerCount = SHORTCUT_NUM_DEPTHS; srDesc.image = m_pFragmentDepthsTexture; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pFragmentDepthsView)); } @@ -141,11 +130,11 @@ VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidt VK_FORMAT_R16G16B16A16_SFLOAT, winWidth, winHeight, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); - AMD_V_RETURN(vkCreateImage(pvkDevice, &fragmentColorInfo, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreateImage(pvkDevice, &fragmentColorInfo, nullptr, &m_pFragmentColorsTexture)); m_pFragmentColorsMemory = - allocImageMemory(pvkDevice, m_pFragmentColorsTexture, texture_memory_index); + allocImageMemory(pvkDevice, m_pFragmentColorsTexture, memProperties); VkImageViewCreateInfo srDesc{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; srDesc.format = VK_FORMAT_R16G16B16A16_SFLOAT; @@ -154,7 +143,7 @@ VkResult TressFXShortCut::CreateScreenSizedItems(VkDevice pvkDevice, int winWidt srDesc.subresourceRange.layerCount = 1; srDesc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; srDesc.image = m_pFragmentColorsTexture; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateImageView(pvkDevice, &srDesc, nullptr, &m_pFragmentColorsView)); } #else @@ -195,13 +184,13 @@ VkAttachmentDescription getAttachmentDescription( inoutLayout}; } -VkRenderPass createRenderPass(VkDevice pvkDevice) +VkRenderPass createRenderPass(VkDevice pvkDevice, VkFormat depthStencilFormat, VkFormat colorFormat) { VkRenderPassCreateInfo info{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO}; const VkAttachmentDescription attachments[] = { // DS - getAttachmentDescription(VK_FORMAT_D24_UNORM_S8_UINT, VK_ATTACHMENT_LOAD_OP_LOAD, + getAttachmentDescription(depthStencilFormat, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR, @@ -219,7 +208,7 @@ VkRenderPass createRenderPass(VkDevice pvkDevice) // TODO #endif // Result - getAttachmentDescription(VK_FORMAT_R8G8B8A8_SNORM, VK_ATTACHMENT_LOAD_OP_LOAD, + getAttachmentDescription(colorFormat, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), @@ -305,9 +294,9 @@ VkRenderPass createRenderPass(VkDevice pvkDevice) // Creates the pipelines for hair rendering // //-------------------------------------------------------------------------------------- -VkResult TressFXShortCut::CreateRenderStateObjects(VkDevice pvkDevice) +VkResult TressFXShortCut::CreateRenderStateObjects(VkDevice pvkDevice, VkFormat depthStencilFormat, VkFormat colorFormat) { - m_pRPRenderHair = createRenderPass(pvkDevice); + m_pRPRenderHair = createRenderPass(pvkDevice, depthStencilFormat, colorFormat); ShaderModule m_pPSDepthsAlpha(pvkDevice, depth_hair_data); ShaderModule m_pPSFillColors(pvkDevice, fillcolors_hair_data); @@ -508,7 +497,7 @@ VkResult TressFXShortCut::CreateRenderStateObjects(VkDevice pvkDevice) VkPipeline pipelines[AMD_ARRAY_SIZE(pipelinesDesc)]; VkResult vr; - AMD_V_RETURN(vkCreateGraphicsPipelines(pvkDevice, VK_NULL_HANDLE, + AMD_CHECKED_VULKAN_CALL(vkCreateGraphicsPipelines(pvkDevice, VK_NULL_HANDLE, AMD_ARRAY_SIZE(pipelinesDesc), pipelinesDesc, nullptr, pipelines)); @@ -559,7 +548,7 @@ VkResult TressFXShortCut::CreateLayouts(VkDevice pvkDevice, }; info.bindingCount = AMD_ARRAY_SIZE(bindings); info.pBindings = bindings; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateDescriptorSetLayout(pvkDevice, &info, nullptr, &m_pSLDepthAlpha)); } @@ -598,7 +587,7 @@ VkResult TressFXShortCut::CreateLayouts(VkDevice pvkDevice, }; info.bindingCount = AMD_ARRAY_SIZE(bindings); info.pBindings = bindings; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateDescriptorSetLayout(pvkDevice, &info, nullptr, &m_pSLColors)); } @@ -608,7 +597,7 @@ VkResult TressFXShortCut::CreateLayouts(VkDevice pvkDevice, info.setLayoutCount = AMD_ARRAY_SIZE(set_layout); info.pSetLayouts = set_layout; - AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &info, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreatePipelineLayout(pvkDevice, &info, nullptr, &m_depthPassPipelineLayout)); } @@ -618,7 +607,7 @@ VkResult TressFXShortCut::CreateLayouts(VkDevice pvkDevice, info.setLayoutCount = AMD_ARRAY_SIZE(set_layout); info.pSetLayouts = set_layout; - AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &info, nullptr, + AMD_CHECKED_VULKAN_CALL(vkCreatePipelineLayout(pvkDevice, &info, nullptr, &m_colorPassPipelineLayout)); } @@ -652,7 +641,7 @@ VkResult TressFXShortCut::CreateFramebuffer(VkDevice pvkDevice, #else // TODO #endif - AMD_V_RETURN(vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_pFBRenderHair)); + AMD_CHECKED_VULKAN_CALL(vkCreateFramebuffer(pvkDevice, &info, nullptr, &m_pFBRenderHair)); } return VK_SUCCESS; } @@ -682,7 +671,7 @@ VkResult TressFXShortCut::AllocateAndPopulateSets(VkDevice pvkDevice, info.maxSets = 2; info.poolSizeCount = AMD_ARRAY_SIZE(sizes); info.pPoolSizes = sizes; - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( vkCreateDescriptorPool(pvkDevice, &info, nullptr, &m_pDPShortcutPool)); } @@ -693,7 +682,7 @@ VkResult TressFXShortCut::AllocateAndPopulateSets(VkDevice pvkDevice, info.descriptorSetCount = AMD_ARRAY_SIZE(setLayout); info.pSetLayouts = setLayout; VkDescriptorSet sets[AMD_ARRAY_SIZE(setLayout)]; - AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &info, sets)); + AMD_CHECKED_VULKAN_CALL(vkAllocateDescriptorSets(pvkDevice, &info, sets)); m_depthPassSet = sets[0]; m_colorPassSet = sets[1]; } @@ -745,19 +734,19 @@ VkResult TressFXShortCut::OnCreateDevice( VkDevice pd3dDevice, int winWidth, int winHeight, VkDescriptorSetLayout mesh_layout, VkSampler noiseSamplerRef, VkSampler shadowSamplerRef, VkImageView depthStencilView, VkImageView colorView, VkBuffer configBuffer, uint64_t configBufferSize, - VkImageView noiseMap, VkImageView hairShadowMap, uint32_t deviceLocalMemoryIndex, - uint32_t width, uint32_t height) + VkImageView noiseMap, VkImageView hairShadowMap, VkPhysicalDeviceMemoryProperties memProperties, + uint32_t width, uint32_t height, VkFormat depthStencilFormat, VkFormat colorFormat) { VkResult vr; - AMD_V_RETURN( - CreateScreenSizedItems(pd3dDevice, winWidth, winHeight, deviceLocalMemoryIndex)); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL( + CreateScreenSizedItems(pd3dDevice, winWidth, winHeight, memProperties)); + AMD_CHECKED_VULKAN_CALL( CreateLayouts(pd3dDevice, mesh_layout, noiseSamplerRef, shadowSamplerRef)); - AMD_V_RETURN(CreateRenderStateObjects(pd3dDevice)); - AMD_V_RETURN( + AMD_CHECKED_VULKAN_CALL(CreateRenderStateObjects(pd3dDevice, depthStencilFormat, colorFormat)); + AMD_CHECKED_VULKAN_CALL( CreateFramebuffer(pd3dDevice, depthStencilView, colorView, width, height)); - AMD_V_RETURN(AllocateAndPopulateSets(pd3dDevice, configBuffer, configBufferSize, + AMD_CHECKED_VULKAN_CALL(AllocateAndPopulateSets(pd3dDevice, configBuffer, configBufferSize, noiseMap, hairShadowMap)) return VK_SUCCESS; @@ -765,13 +754,13 @@ VkResult TressFXShortCut::OnCreateDevice( VkResult TressFXShortCut::OnResizedSwapChain(VkDevice pd3dDevice, int winWidth, int winHeight, - uint32_t deviceLocalMemoryIndex) + VkPhysicalDeviceMemoryProperties memProperties) { DestroyScreenSizedItems(); VkResult vr; - AMD_V_RETURN( - CreateScreenSizedItems(pd3dDevice, winWidth, winHeight, deviceLocalMemoryIndex)); + AMD_CHECKED_VULKAN_CALL( + CreateScreenSizedItems(pd3dDevice, winWidth, winHeight, memProperties)); return VK_SUCCESS; } diff --git a/amd_tressfx_vulkan/src/TressFXShortCutVulkan.h b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.h index 89c5a6d..354a989 100644 --- a/amd_tressfx_vulkan/src/TressFXShortCutVulkan.h +++ b/amd_tressfx_vulkan/src/TressFXShortCutVulkan.h @@ -34,7 +34,7 @@ namespace AMD { struct GPUOnlyStructuredBuffer { - GPUOnlyStructuredBuffer() : m_pBuffer(nullptr), m_pvkDevice(nullptr) {} + GPUOnlyStructuredBuffer() : m_pBuffer(VK_NULL_HANDLE), m_pvkDevice(nullptr) {} VkResult Create(VkDevice pd3dDevice, uint32_t structCount, uint32_t structSize); void Destroy(); @@ -92,9 +92,9 @@ class TressFXShortCut GPUOnlyStructuredBuffer m_FragmentColors; VkResult CreateScreenSizedItems(VkDevice pvkDevice, int winWidth, int winHeight, - uint32_t MemoryIndexGPU); + VkPhysicalDeviceMemoryProperties memProperties); void DestroyScreenSizedItems(); - VkResult CreateRenderStateObjects(VkDevice pvkDevice); + VkResult CreateRenderStateObjects(VkDevice pvkDevice, VkFormat depthStencilFormat, VkFormat colorFormat); VkResult CreateLayouts(VkDevice pvkDevice, VkDescriptorSetLayout SLMesh, VkSampler noiseSamplerRef, VkSampler shadowSamplerRef); VkResult CreateFramebuffer(VkDevice pvkDevice, VkImageView depthStencilView, @@ -105,11 +105,11 @@ class TressFXShortCut public: TressFXShortCut(void) - : m_pFragmentColorsTexture(nullptr), m_pFragmentColorsMemory(nullptr), - m_pFragmentColorsView(nullptr), m_pFragmentDepthsTexture(nullptr), - m_pFragmentDepthsMemory(nullptr), m_pFragmentDepthsView(nullptr), - m_pAccumInvAlphaTexture(nullptr), m_pAccumInvAlphaMemory(nullptr), - m_pAccumInvAlphaView(nullptr) + : m_pFragmentColorsTexture(VK_NULL_HANDLE), m_pFragmentColorsMemory(VK_NULL_HANDLE), + m_pFragmentColorsView(VK_NULL_HANDLE), m_pFragmentDepthsTexture(VK_NULL_HANDLE), + m_pFragmentDepthsMemory(VK_NULL_HANDLE), m_pFragmentDepthsView(VK_NULL_HANDLE), + m_pAccumInvAlphaTexture(VK_NULL_HANDLE), m_pAccumInvAlphaMemory(VK_NULL_HANDLE), + m_pAccumInvAlphaView(VK_NULL_HANDLE) { } ~TressFXShortCut(void){}; @@ -119,10 +119,10 @@ class TressFXShortCut VkSampler shadowSamplerRef, VkImageView depthStencilView, VkImageView colorView, VkBuffer configBuffer, uint64_t configBufferSize, VkImageView noiseMap, - VkImageView hairShadowMap, uint32_t deviceLocalMemoryIndex, - uint32_t width, uint32_t height); + VkImageView hairShadowMap, VkPhysicalDeviceMemoryProperties memProperties, + uint32_t width, uint32_t height, VkFormat depthStencilFormat, VkFormat colorFormat); VkResult OnResizedSwapChain(VkDevice pvkDevice, int winWidth, int WinHeight, - uint32_t deviceLocalMemoryIndex); + VkPhysicalDeviceMemoryProperties memProperties); // Individual render pass setups. // Each basically sets up render state, UAVs, SRVs, and returns pixel diff --git a/amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp index e422ae4..d83c388 100644 --- a/amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp +++ b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.cpp @@ -99,7 +99,6 @@ struct ConstBufferCS_HeadTransform namespace AMD { - //-------------------------------------------------------------------------------------- // // Constructor @@ -139,9 +138,9 @@ TressFXSimulation::~TressFXSimulation(void) {} namespace { VkComputePipelineCreateInfo getComputePipelineInfo(VkPipelineLayout layout, - VkShaderModule computeShader) + VkShaderModule computeShader) { - VkComputePipelineCreateInfo result{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO}; + VkComputePipelineCreateInfo result{ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; result.layout = layout; result.stage.module = computeShader; result.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -154,16 +153,16 @@ VkComputePipelineCreateInfo getComputePipelineInfo(VkPipelineLayout layout, namespace { VkResult getPipelineLayout(VkDevice pvkDevice, VkDescriptorSetLayout configSetLayout, - VkDescriptorSetLayout secondSetLayout, - VkPipelineLayout &result) + VkDescriptorSetLayout secondSetLayout, + VkPipelineLayout &result) { VkPipelineLayoutCreateInfo pipelineInfo{ - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO}; - VkDescriptorSetLayout setLayouts[] = {configSetLayout, secondSetLayout}; + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + VkDescriptorSetLayout setLayouts[] = { configSetLayout, secondSetLayout }; pipelineInfo.setLayoutCount = AMD_ARRAY_SIZE(setLayouts); pipelineInfo.pSetLayouts = setLayouts; VkResult vr; - AMD_V_RETURN(vkCreatePipelineLayout(pvkDevice, &pipelineInfo, nullptr, &result)); + AMD_CHECKED_VULKAN_CALL(vkCreatePipelineLayout(pvkDevice, &pipelineInfo, nullptr, &result)); return VK_SUCCESS; } } @@ -174,126 +173,126 @@ VkResult TressFXSimulation::CreateDescriptorSet(VkDevice pvkDevice) const VkDescriptorSetLayoutBinding global_constraints_bindings[] = { {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_VERTEX_INITIAL_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, }; const VkDescriptorSetLayoutBinding local_constraints_bindings[] = { {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_GLOBAL_ROTATION, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_LOCAL_REF_VEC, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, }; const VkDescriptorSetLayoutBinding length_wind_collision_bindings[] = { {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_LENGTH, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, }; const VkDescriptorSetLayoutBinding prepare_follow_hair_bindings[] = { {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_PREVIOUS_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, }; const VkDescriptorSetLayoutBinding update_follow_hair_bindings[] = { {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_ROOT_OFFSET, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, }; const VkDescriptorSetLayoutBinding compute_tangent_bindings[] = { {IDSRV_HAIR_VERTEX_POSITIONS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_STRAND_TYPE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HAIR_TANGENTS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, }; - AMD_V_RETURN(getDescriptorLayout(pvkDevice, global_constraints_bindings, - AMD_ARRAY_SIZE(global_constraints_bindings), - m_GlobalConstraintsSetLayout)); - AMD_V_RETURN(getDescriptorLayout(pvkDevice, local_constraints_bindings, - AMD_ARRAY_SIZE(local_constraints_bindings), - m_LocalConstraintsSetLayout)); - AMD_V_RETURN(getDescriptorLayout(pvkDevice, length_wind_collision_bindings, - AMD_ARRAY_SIZE(length_wind_collision_bindings), - m_LenghtWindTangentSetLayout)); - AMD_V_RETURN(getDescriptorLayout(pvkDevice, prepare_follow_hair_bindings, - AMD_ARRAY_SIZE(prepare_follow_hair_bindings), - m_PrepareFollowHairSetLayout)); - AMD_V_RETURN(getDescriptorLayout(pvkDevice, update_follow_hair_bindings, - AMD_ARRAY_SIZE(update_follow_hair_bindings), - m_UpdateFollowHaitSetLayout)); - AMD_V_RETURN(getDescriptorLayout(pvkDevice, compute_tangent_bindings, - AMD_ARRAY_SIZE(compute_tangent_bindings), - m_ComputeTangentSetLayout)); + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, global_constraints_bindings, + AMD_ARRAY_SIZE(global_constraints_bindings), + m_GlobalConstraintsSetLayout)); + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, local_constraints_bindings, + AMD_ARRAY_SIZE(local_constraints_bindings), + m_LocalConstraintsSetLayout)); + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, length_wind_collision_bindings, + AMD_ARRAY_SIZE(length_wind_collision_bindings), + m_LenghtWindTangentSetLayout)); + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, prepare_follow_hair_bindings, + AMD_ARRAY_SIZE(prepare_follow_hair_bindings), + m_PrepareFollowHairSetLayout)); + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, update_follow_hair_bindings, + AMD_ARRAY_SIZE(update_follow_hair_bindings), + m_UpdateFollowHaitSetLayout)); + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, compute_tangent_bindings, + AMD_ARRAY_SIZE(compute_tangent_bindings), + m_ComputeTangentSetLayout)); const VkDescriptorSetLayoutBinding configBindings[] = { {IDSRV_CONSTANTS_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, - VK_SHADER_STAGE_COMPUTE_BIT}, + VK_SHADER_STAGE_COMPUTE_BIT}, {IDSRV_HEAD_TRANSFORM, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_COMPUTE_BIT}}; - AMD_V_RETURN(getDescriptorLayout(pvkDevice, configBindings, - AMD_ARRAY_SIZE(configBindings), m_configSetLayout)); - - AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, - m_GlobalConstraintsSetLayout, - m_CSIntegrationAndGlobalShapeConstraintsLayout)); - AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, - m_LocalConstraintsSetLayout, - m_CSLocalShapeConstraintsLayout)); - AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, - m_LocalConstraintsSetLayout, - m_CSLocalShapeConstraintsSingleDispatchLayout)); - AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, - m_LenghtWindTangentSetLayout, - m_CSLengthConstriantsWindAndCollisionLayout)); - AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, - m_PrepareFollowHairSetLayout, - m_CSPrepareFollowHairBeforeTurningIntoGuideLayout)); - AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, - m_UpdateFollowHaitSetLayout, - m_CSUpdateFollowHairVerticesLayout)); - AMD_V_RETURN(getPipelineLayout(pvkDevice, m_configSetLayout, - m_ComputeTangentSetLayout, m_CSComputeTangentsLayout)); - - VkDescriptorPoolSize poolSizes[] = {{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1}, - {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}}; + VK_SHADER_STAGE_COMPUTE_BIT} }; + AMD_CHECKED_VULKAN_CALL(getDescriptorLayout(pvkDevice, configBindings, + AMD_ARRAY_SIZE(configBindings), m_configSetLayout)); + + AMD_CHECKED_VULKAN_CALL(getPipelineLayout(pvkDevice, m_configSetLayout, + m_GlobalConstraintsSetLayout, + m_CSIntegrationAndGlobalShapeConstraintsLayout)); + AMD_CHECKED_VULKAN_CALL(getPipelineLayout(pvkDevice, m_configSetLayout, + m_LocalConstraintsSetLayout, + m_CSLocalShapeConstraintsLayout)); + AMD_CHECKED_VULKAN_CALL(getPipelineLayout(pvkDevice, m_configSetLayout, + m_LocalConstraintsSetLayout, + m_CSLocalShapeConstraintsSingleDispatchLayout)); + AMD_CHECKED_VULKAN_CALL(getPipelineLayout(pvkDevice, m_configSetLayout, + m_LenghtWindTangentSetLayout, + m_CSLengthConstriantsWindAndCollisionLayout)); + AMD_CHECKED_VULKAN_CALL(getPipelineLayout(pvkDevice, m_configSetLayout, + m_PrepareFollowHairSetLayout, + m_CSPrepareFollowHairBeforeTurningIntoGuideLayout)); + AMD_CHECKED_VULKAN_CALL(getPipelineLayout(pvkDevice, m_configSetLayout, + m_UpdateFollowHaitSetLayout, + m_CSUpdateFollowHairVerticesLayout)); + AMD_CHECKED_VULKAN_CALL(getPipelineLayout(pvkDevice, m_configSetLayout, + m_ComputeTangentSetLayout, m_CSComputeTangentsLayout)); + + VkDescriptorPoolSize poolSizes[] = { {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1}, + {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1} }; VkDescriptorPoolCreateInfo descriptorPoolInfo{ - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; descriptorPoolInfo.maxSets = 1; descriptorPoolInfo.poolSizeCount = AMD_ARRAY_SIZE(poolSizes); descriptorPoolInfo.pPoolSizes = poolSizes; - AMD_V_RETURN(vkCreateDescriptorPool(pvkDevice, &descriptorPoolInfo, nullptr, - &m_descriptorPool)); + AMD_CHECKED_VULKAN_CALL(vkCreateDescriptorPool(pvkDevice, &descriptorPoolInfo, nullptr, + &m_descriptorPool)); - VkDescriptorSetAllocateInfo allocInfo{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + VkDescriptorSetAllocateInfo allocInfo{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; allocInfo.descriptorSetCount = 1; allocInfo.pSetLayouts = &m_configSetLayout; allocInfo.descriptorPool = m_descriptorPool; - AMD_V_RETURN(vkAllocateDescriptorSets(pvkDevice, &allocInfo, &m_configSet)); + AMD_CHECKED_VULKAN_CALL(vkAllocateDescriptorSets(pvkDevice, &allocInfo, &m_configSet)); return VK_SUCCESS; } @@ -307,29 +306,28 @@ VkResult TressFXSimulation::CreateDescriptorSet(VkDevice pvkDevice) // //-------------------------------------------------------------------------------------- VkResult TressFXSimulation::OnCreateDevice(VkDevice pvkDevice, - TressFX_CollisionCapsule *pCollision, - uint32_t maxUniformCount, - uint32_t cpu_memory_index, - uint32_t gpu_memory_index) + TressFX_CollisionCapsule *pCollision, + uint32_t maxUniformCount, + VkPhysicalDeviceMemoryProperties memProperties, const DebugMarkerPointer& markerCallbacks) { VkResult vr; - AMD_V_RETURN(CreateDescriptorSet(pvkDevice)); + AMD_CHECKED_VULKAN_CALL(CreateDescriptorSet(pvkDevice)); // reset m_elapsedTimeSinceLastSim to zero m_elapsedTimeSinceLastSim = 0; ShaderModule IntegrationAndGlobalShapeConstraints_Module(pvkDevice, - global_constraints); - // TODO + global_constraints); + ShaderModule ApplyHairTransformGlobally_Module(pvkDevice, global_constraints); ShaderModule ComputeTangents_Module(pvkDevice, compute_tangents); ShaderModule LocalShapeConstraints_Module(pvkDevice, local_constraints); ShaderModule LocalShapeConstraintsWithIteration_Module(pvkDevice, local_constraints); ShaderModule LengthConstraintsWindAndCollision_Module(pvkDevice, - length_wind_collision); + length_wind_collision); ShaderModule UpdateFollowHairVertices_Module(pvkDevice, update_follow_hair); ShaderModule PrepareFollowHairBeforeTurningIntoGuide_Data(pvkDevice, - prepare_follow_hair); - // TODO + prepare_follow_hair); + ShaderModule GenerateTransforms_Module(pvkDevice, global_constraints); VkComputePipelineCreateInfo computePipelineInfo[] = { @@ -337,44 +335,53 @@ VkResult TressFXSimulation::OnCreateDevice(VkDevice pvkDevice, m_CSIntegrationAndGlobalShapeConstraintsLayout, IntegrationAndGlobalShapeConstraints_Module.m_shaderModule), getComputePipelineInfo(m_CSIntegrationAndGlobalShapeConstraintsLayout, - ApplyHairTransformGlobally_Module.m_shaderModule), + ApplyHairTransformGlobally_Module.m_shaderModule), getComputePipelineInfo(m_CSComputeTangentsLayout, - ComputeTangents_Module.m_shaderModule), + ComputeTangents_Module.m_shaderModule), getComputePipelineInfo(m_CSLocalShapeConstraintsSingleDispatchLayout, - LocalShapeConstraints_Module.m_shaderModule), + LocalShapeConstraints_Module.m_shaderModule), getComputePipelineInfo(m_CSLocalShapeConstraintsLayout, - LocalShapeConstraintsWithIteration_Module.m_shaderModule), + LocalShapeConstraintsWithIteration_Module.m_shaderModule), getComputePipelineInfo(m_CSLengthConstriantsWindAndCollisionLayout, - LengthConstraintsWindAndCollision_Module.m_shaderModule), + LengthConstraintsWindAndCollision_Module.m_shaderModule), getComputePipelineInfo(m_CSUpdateFollowHairVerticesLayout, - UpdateFollowHairVertices_Module.m_shaderModule), + UpdateFollowHairVertices_Module.m_shaderModule), getComputePipelineInfo( m_CSPrepareFollowHairBeforeTurningIntoGuideLayout, PrepareFollowHairBeforeTurningIntoGuide_Data.m_shaderModule), getComputePipelineInfo(m_CSIntegrationAndGlobalShapeConstraintsLayout, - GenerateTransforms_Module.m_shaderModule), + GenerateTransforms_Module.m_shaderModule), }; VkPipeline pipelines[9]{}; - AMD_V_RETURN(vkCreateComputePipelines(pvkDevice, VK_NULL_HANDLE, - AMD_ARRAY_SIZE(computePipelineInfo), - computePipelineInfo, nullptr, pipelines)); + AMD_CHECKED_VULKAN_CALL(vkCreateComputePipelines(pvkDevice, VK_NULL_HANDLE, + AMD_ARRAY_SIZE(computePipelineInfo), + computePipelineInfo, nullptr, pipelines)); m_CSIntegrationAndGlobalShapeConstraints = pipelines[0]; + markerCallbacks.nameObject(m_CSIntegrationAndGlobalShapeConstraints, "CSIntegrationAndGlobalShapeConstraints"); m_CSApplyHairTransformGlobally = pipelines[1]; + markerCallbacks.nameObject(m_CSApplyHairTransformGlobally, "CSApplyHairTransformGlobally"); m_CSComputeTangents = pipelines[2]; + markerCallbacks.nameObject(m_CSComputeTangents, "CSComputeTangents"); m_CSLocalShapeConstraints = pipelines[3]; + markerCallbacks.nameObject(m_CSLocalShapeConstraints, "CSLocalShapeConstraints"); m_CSLocalShapeConstraintsSingleDispatch = pipelines[4]; + markerCallbacks.nameObject(m_CSLocalShapeConstraintsSingleDispatch, "CSLocalShapeConstraintsSingleDispatch"); m_CSLengthConstriantsWindAndCollision = pipelines[5]; + markerCallbacks.nameObject(m_CSLengthConstriantsWindAndCollision, "CSLengthConstriantsWindAndCollision"); m_CSUpdateFollowHairVertices = pipelines[6]; + markerCallbacks.nameObject(m_CSUpdateFollowHairVertices, "CSUpdateFollowHairVertices"); m_CSPrepareFollowHairBeforeTurningIntoGuide = pipelines[7]; + markerCallbacks.nameObject(m_CSPrepareFollowHairBeforeTurningIntoGuide, "CSPrepareFollowHairBeforeTurningIntoGuide"); m_CSGenerateTransforms = pipelines[8]; + markerCallbacks.nameObject(m_CSGenerateTransforms, "CSGenerateTransforms"); //------------------------- // Create constant buffers //------------------------- - AMD_V_RETURN(CreateComputeShaderConstantBuffers( - pvkDevice, pCollision, maxUniformCount, cpu_memory_index, gpu_memory_index)); + AMD_CHECKED_VULKAN_CALL(CreateComputeShaderConstantBuffers( + pvkDevice, pCollision, maxUniformCount, memProperties)); return VK_SUCCESS; } @@ -572,7 +579,7 @@ const float MATH_PI2 = 3.14159265359f; // //-------------------------------------------------------------------------------------- void ComputeWindPyramid(float4 &wind, float4 &wind1, float4 &wind2, float4 &wind3, - const float windMag, const tressfx_vec3 &windDir) + const float windMag, const tressfx_vec3 &windDir) { static int frame = 0; @@ -646,14 +653,13 @@ float getScaledStiffness(float s0, float s_min_scale, float h, float h0) // ////-------------------------------------------------------------------------------------- VkResult TressFXSimulation::Simulate(VkDevice pvkDevice, VkCommandBuffer commandBuffer, - float fElapsedTime, float density, - tressfx_vec3 &windDir, float windMag, - XMMATRIX *pModelTransformForHead, - ID3D11UnorderedAccessView *pSkinningTransforms, - float targetFrameRate, bool singleHeadTransform, - bool warp, uint32_t uniformBufferIndex) + float fElapsedTime, float density, + tressfx_vec3 &windDir, float windMag, + XMMATRIX *pModelTransformForHead, + float targetFrameRate, bool singleHeadTransform, + bool warp, uint32_t uniformBufferIndex, + const DebugMarkerPointer& markerCallbacks) { - (void)pSkinningTransforms; m_elapsedTimeSinceLastSim += fElapsedTime; bool bFullSimulate = true; @@ -677,148 +683,40 @@ VkResult TressFXSimulation::Simulate(VkDevice pvkDevice, VkCommandBuffer command ConstBufferCS_Per_Frame *pCSPerFrame; vkMapMemory(pvkDevice, m_pCBCSPerFrameMemory, - uniformBufferIndex * sizeof(ConstBufferCS_Per_Frame), - sizeof(ConstBufferCS_Per_Frame), 0, - reinterpret_cast(&pCSPerFrame)); - - { - pCSPerFrame->bWarp = warp; - - if (bFullSimulate) - { - pCSPerFrame->NumLengthConstraintIterations = - m_simParams.numLengthConstraintIterations; - } - else - { - pCSPerFrame->NumLengthConstraintIterations = 1; - } - - pCSPerFrame->bCollision = (m_simParams.bCollision == true) ? 1 : 0; - - pCSPerFrame->GravityMagnitude = m_simParams.gravityMagnitude; + uniformBufferIndex * sizeof(ConstBufferCS_Per_Frame), + sizeof(ConstBufferCS_Per_Frame), 0, + reinterpret_cast(&pCSPerFrame)); - pCSPerFrame->timeStep = targetFrameRate; - - pCSPerFrame->NumOfStrandsPerThreadGroup = numOfStrandsPerThreadGroup; - pCSPerFrame->NumFollowHairsPerGuideHair = - (m_bGuideFollowHairPrev - ? m_pTressFXMesh->m_HairAsset.m_NumFollowHairsPerGuideHair - : 0); - pCSPerFrame->TipSeparationFactor = - m_pTressFXMesh->m_HairAsset.m_TipSeparationFactor; - - ComputeWindPyramid(pCSPerFrame->Wind, pCSPerFrame->Wind1, pCSPerFrame->Wind2, - pCSPerFrame->Wind3, windMag, windDir); - - int numSections = m_simParams.numHairSections; - - // hair section 0 - if (numSections > 0) - { - pCSPerFrame->Damping0 = m_simParams.perSectionShapeParams[0].damping; - pCSPerFrame->StiffnessForLocalShapeMatching0 = - m_simParams.perSectionShapeParams[0].stiffnessForLocalShapeMatching; - pCSPerFrame->StiffnessForGlobalShapeMatching0 = - m_simParams.perSectionShapeParams[0].stiffnessForGlobalShapeMatching; - pCSPerFrame->GlobalShapeMatchingEffectiveRange0 = - m_simParams.perSectionShapeParams[0].globalShapeMatchingEffectiveRange; - } - - // hair section 1 - if (numSections > 1) - { - pCSPerFrame->Damping1 = m_simParams.perSectionShapeParams[1].damping; - pCSPerFrame->StiffnessForLocalShapeMatching1 = - m_simParams.perSectionShapeParams[1].stiffnessForLocalShapeMatching; - pCSPerFrame->StiffnessForGlobalShapeMatching1 = - m_simParams.perSectionShapeParams[1].stiffnessForGlobalShapeMatching; - pCSPerFrame->GlobalShapeMatchingEffectiveRange1 = - m_simParams.perSectionShapeParams[1].globalShapeMatchingEffectiveRange; - } - - // hair section 2 - if (numSections > 2) - { - pCSPerFrame->Damping2 = m_simParams.perSectionShapeParams[2].damping; - pCSPerFrame->StiffnessForLocalShapeMatching2 = - m_simParams.perSectionShapeParams[2].stiffnessForLocalShapeMatching; - pCSPerFrame->StiffnessForGlobalShapeMatching2 = - m_simParams.perSectionShapeParams[2].stiffnessForGlobalShapeMatching; - pCSPerFrame->GlobalShapeMatchingEffectiveRange2 = - m_simParams.perSectionShapeParams[2].globalShapeMatchingEffectiveRange; - } - - // hair section 3 - if (numSections > 3) - { - pCSPerFrame->Damping3 = m_simParams.perSectionShapeParams[3].damping; - pCSPerFrame->StiffnessForLocalShapeMatching3 = - m_simParams.perSectionShapeParams[3].stiffnessForLocalShapeMatching; - pCSPerFrame->StiffnessForGlobalShapeMatching3 = - m_simParams.perSectionShapeParams[3].stiffnessForGlobalShapeMatching; - pCSPerFrame->GlobalShapeMatchingEffectiveRange3 = - m_simParams.perSectionShapeParams[3].globalShapeMatchingEffectiveRange; - } - - if (!bFullSimulate) - { - float h = fElapsedTime; - float h0 = targetFrameRate; - float s_min_scale = - 0.3f; // minimum stiffness = s_min_scale * current stiffness - - pCSPerFrame->StiffnessForLocalShapeMatching0 = getScaledStiffness( - m_simParams.perSectionShapeParams[0].stiffnessForLocalShapeMatching, - s_min_scale, h, h0); - pCSPerFrame->StiffnessForLocalShapeMatching1 = getScaledStiffness( - m_simParams.perSectionShapeParams[1].stiffnessForLocalShapeMatching, - s_min_scale, h, h0); - pCSPerFrame->StiffnessForLocalShapeMatching2 = getScaledStiffness( - m_simParams.perSectionShapeParams[2].stiffnessForLocalShapeMatching, - s_min_scale, h, h0); - pCSPerFrame->StiffnessForLocalShapeMatching3 = getScaledStiffness( - m_simParams.perSectionShapeParams[3].stiffnessForLocalShapeMatching, - s_min_scale, h, h0); - } - - if (bFullSimulate) - { - pCSPerFrame->NumLocalShapeMatchingIterations = - m_simParams.numLocalShapeMatchingIterations; - } - else - { - pCSPerFrame->NumLocalShapeMatchingIterations = 1; - } - - pCSPerFrame->NumVerticesPerStrand = g_TressFXNumVerticesPerStrand; - } + fillConstantBuffer(pCSPerFrame, warp, bFullSimulate, targetFrameRate, numOfStrandsPerThreadGroup, windMag, windDir, fElapsedTime); vkUnmapMemory(pvkDevice, m_pCBCSPerFrameMemory); // ConstBufferCS_HeadTransform ConstBufferCS_HeadTransform *pCSHeadTransform; - AMD_V_RETURN(vkMapMemory(pvkDevice, m_pCBHeadTransformsMemory, 0, - sizeof(ConstBufferCS_HeadTransform), 0, - reinterpret_cast(&pCSHeadTransform))); - { - pCSHeadTransform->bSingleHeadTransform = singleHeadTransform; - pCSHeadTransform->ModelRotateForHead = - XMQuaternionRotationMatrix(*pModelTransformForHead); - pCSHeadTransform->ModelTransformForHead = *pModelTransformForHead; - } + AMD_CHECKED_VULKAN_CALL(vkMapMemory(pvkDevice, m_pCBHeadTransformsMemory, 0, + sizeof(ConstBufferCS_HeadTransform), 0, + reinterpret_cast(&pCSHeadTransform))); + fillHeadConstantBuffer(pCSHeadTransform, singleHeadTransform, pModelTransformForHead); vkUnmapMemory(pvkDevice, m_pCBHeadTransformsMemory); + markerCallbacks.markBeginRegion(commandBuffer, "Simulation"); + fillSimulationCommands(commandBuffer, density, uniformBufferIndex); + markerCallbacks.markEndRegion(commandBuffer); + + return vr; +} + +void TressFXSimulation::fillSimulationCommands(const VkCommandBuffer &commandBuffer, float &density, const uint32_t &uniformBufferIndex) +{ VkBufferMemoryBarrier bufferBarrier[] = { getBufferBarrier(m_pCBCSPerFrame, VK_ACCESS_HOST_WRITE_BIT, - VK_ACCESS_UNIFORM_READ_BIT), + VK_ACCESS_UNIFORM_READ_BIT), getBufferBarrier(m_pCBHeadTransforms, VK_ACCESS_HOST_WRITE_BIT, - VK_ACCESS_UNIFORM_READ_BIT), + VK_ACCESS_UNIFORM_READ_BIT), }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(bufferBarrier), bufferBarrier, 0, nullptr); + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(bufferBarrier), bufferBarrier, 0, nullptr); //======= Run the compute shader ======= @@ -835,63 +733,63 @@ VkResult TressFXSimulation::Simulate(VkDevice pvkDevice, VkCommandBuffer command int numOfGroupsForCS_VertexLevel = (int)(((float)(m_bGuideFollowHairPrev - ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairVertices - : m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices) / - (float)THREAD_GROUP_SIZE) * - density); + ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairVertices + : m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices) / + (float)THREAD_GROUP_SIZE) * + density); - uint32_t descriptorOffset[] = {uniformBufferIndex * sizeof(ConstBufferCS_Per_Frame)}; + uint32_t descriptorOffset[] = { uniformBufferIndex * sizeof(ConstBufferCS_Per_Frame) }; // Prepare follow hair vertices before they are turning into guide ones. // One thread computes one vertex if (m_bGuideFollowHairPrev && !m_simParams.bGuideFollowSimulation) { VkDescriptorSet prepareFollowHairSets[] = { - m_configSet, m_pTressFXMesh->m_PrepareFollowHairSet}; + m_configSet, m_pTressFXMesh->m_PrepareFollowHairSet }; vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSPrepareFollowHairBeforeTurningIntoGuideLayout, 0, - AMD_ARRAY_SIZE(prepareFollowHairSets), - prepareFollowHairSets, AMD_ARRAY_SIZE(descriptorOffset), - descriptorOffset); + m_CSPrepareFollowHairBeforeTurningIntoGuideLayout, 0, + AMD_ARRAY_SIZE(prepareFollowHairSets), + prepareFollowHairSets, AMD_ARRAY_SIZE(descriptorOffset), + descriptorOffset); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSPrepareFollowHairBeforeTurningIntoGuide); + m_CSPrepareFollowHairBeforeTurningIntoGuide); vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); - VkBufferMemoryBarrier flushPrevPositionBarrier[] = {getBufferBarrier( + VkBufferMemoryBarrier flushPrevPositionBarrier[] = { getBufferBarrier( m_pTressFXMesh->m_HairVertexPositionsPrevBuffer, VK_ACCESS_MEMORY_WRITE_BIT, - VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT)}; + VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT) }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(flushPrevPositionBarrier), - flushPrevPositionBarrier, 0, nullptr); + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(flushPrevPositionBarrier), + flushPrevPositionBarrier, 0, nullptr); } // Integrate and global shape constraints // One thread computes one vertex - VkDescriptorSet globalConstraintSets[] = {m_configSet, - m_pTressFXMesh->m_GlobalConstraintsSet}; + VkDescriptorSet globalConstraintSets[] = { m_configSet, + m_pTressFXMesh->m_GlobalConstraintsSet }; vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSIntegrationAndGlobalShapeConstraintsLayout, 0, - AMD_ARRAY_SIZE(globalConstraintSets), globalConstraintSets, - AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); + m_CSIntegrationAndGlobalShapeConstraintsLayout, 0, + AMD_ARRAY_SIZE(globalConstraintSets), globalConstraintSets, + AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSIntegrationAndGlobalShapeConstraints); + m_CSIntegrationAndGlobalShapeConstraints); vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); VkBufferMemoryBarrier globalConstraintsBarriers[] = { getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT), + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT), getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsPrevBuffer, - VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - VK_ACCESS_SHADER_READ_BIT)}; + VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT) }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(globalConstraintsBarriers), - globalConstraintsBarriers, 0, nullptr); + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(globalConstraintsBarriers), + globalConstraintsBarriers, 0, nullptr); // Local shape constraints. If the hair is very curly, increase the iteration so that // hair style can be preserved well. @@ -901,149 +799,267 @@ VkResult TressFXSimulation::Simulate(VkDevice pvkDevice, VkCommandBuffer command if (g_TressFXNumVerticesPerStrand >= 16) { for (int iteration = 0; iteration < m_simParams.numLocalShapeMatchingIterations; - iteration++) + iteration++) { int numOfGroupsForCS_StrandLevel = (int)(((float)(m_bGuideFollowHairPrev - ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairStrands - : m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands) / - (float)THREAD_GROUP_SIZE) * - density); + ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairStrands + : m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands) / + (float)THREAD_GROUP_SIZE) * + density); VkDescriptorSet localConstraintSets[] = { - m_configSet, m_pTressFXMesh->m_LocalConstraintsSet}; + m_configSet, m_pTressFXMesh->m_LocalConstraintsSet }; vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSLocalShapeConstraintsSingleDispatchLayout, 0, - AMD_ARRAY_SIZE(localConstraintSets), - localConstraintSets, AMD_ARRAY_SIZE(descriptorOffset), - descriptorOffset); + m_CSLocalShapeConstraintsSingleDispatchLayout, 0, + AMD_ARRAY_SIZE(localConstraintSets), + localConstraintSets, AMD_ARRAY_SIZE(descriptorOffset), + descriptorOffset); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSLocalShapeConstraints); + m_CSLocalShapeConstraints); vkCmdDispatch(commandBuffer, numOfGroupsForCS_StrandLevel, 1, 1); VkBufferMemoryBarrier localBarrier[] = { getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT)}; + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT) }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(localBarrier), localBarrier, 0, nullptr); + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(localBarrier), localBarrier, 0, nullptr); } } else { int numOfGroupsForCS_StrandLevel = (int)(((float)(m_bGuideFollowHairPrev - ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairStrands - : m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands) / - (float)THREAD_GROUP_SIZE) * - density); - VkDescriptorSet localConstraintSets[] = {m_configSet, - m_pTressFXMesh->m_LocalConstraintsSet}; + ? m_pTressFXMesh->m_HairAsset.m_NumGuideHairStrands + : m_pTressFXMesh->m_HairAsset.m_NumTotalHairStrands) / + (float)THREAD_GROUP_SIZE) * + density); + VkDescriptorSet localConstraintSets[] = { m_configSet, + m_pTressFXMesh->m_LocalConstraintsSet }; vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSLocalShapeConstraintsSingleDispatchLayout, 0, - AMD_ARRAY_SIZE(localConstraintSets), localConstraintSets, - AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); + m_CSLocalShapeConstraintsSingleDispatchLayout, 0, + AMD_ARRAY_SIZE(localConstraintSets), localConstraintSets, + AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSLocalShapeConstraintsSingleDispatch); + m_CSLocalShapeConstraintsSingleDispatch); vkCmdDispatch(commandBuffer, numOfGroupsForCS_StrandLevel, 1, 1); VkBufferMemoryBarrier localBarrier[] = { getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT)}; + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT) }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(localBarrier), localBarrier, 0, nullptr); + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(localBarrier), localBarrier, 0, nullptr); } // Edge length constraints, wind and collisions // One thread computes one vertex VkDescriptorSet lengthWindCollisionSets[] = { - m_configSet, m_pTressFXMesh->m_LenghtWindCollisionSet}; + m_configSet, m_pTressFXMesh->m_LenghtWindCollisionSet }; vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSLengthConstriantsWindAndCollisionLayout, 0, - AMD_ARRAY_SIZE(lengthWindCollisionSets), - lengthWindCollisionSets, AMD_ARRAY_SIZE(descriptorOffset), - descriptorOffset); + m_CSLengthConstriantsWindAndCollisionLayout, 0, + AMD_ARRAY_SIZE(lengthWindCollisionSets), + lengthWindCollisionSets, AMD_ARRAY_SIZE(descriptorOffset), + descriptorOffset); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSLengthConstriantsWindAndCollision); + m_CSLengthConstriantsWindAndCollision); vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); VkBufferMemoryBarrier lengthWindCollisionBarriers[] = { getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT)}; + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT) }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(lengthWindCollisionBarriers), - lengthWindCollisionBarriers, 0, nullptr); + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(lengthWindCollisionBarriers), + lengthWindCollisionBarriers, 0, nullptr); // Update follow hair vertices // One thread computes one vertex if (m_bGuideFollowHairPrev) { - VkDescriptorSet updateFollowHairSets[] = {m_configSet, - m_pTressFXMesh->m_UpdateFollowHairSet}; + VkDescriptorSet updateFollowHairSets[] = { m_configSet, + m_pTressFXMesh->m_UpdateFollowHairSet }; vkCmdBindDescriptorSets( commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_CSUpdateFollowHairVerticesLayout, 0, AMD_ARRAY_SIZE(updateFollowHairSets), updateFollowHairSets, AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSUpdateFollowHairVertices); + m_CSUpdateFollowHairVertices); vkCmdDispatch(commandBuffer, numOfGroupsForCS_VertexLevel, 1, 1); VkBufferMemoryBarrier updateFollowHairBarriers[] = { getBufferBarrier(m_pTressFXMesh->m_HairVertexPositionsBuffer, - VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, - VK_ACCESS_SHADER_READ_BIT), + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT), + getBufferBarrier( + m_pTressFXMesh->m_HairVertexTangentsBuffer, VK_ACCESS_MEMORY_READ_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT) }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(updateFollowHairBarriers), - updateFollowHairBarriers, 0, nullptr); + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(updateFollowHairBarriers), + updateFollowHairBarriers, 0, nullptr); } + else + { + VkBufferMemoryBarrier makeTangentBarrier[] = { getBufferBarrier( + m_pTressFXMesh->m_HairVertexTangentsBuffer, VK_ACCESS_MEMORY_READ_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT) }; - VkBufferMemoryBarrier makeTangentBarrier[] = {getBufferBarrier( - m_pTressFXMesh->m_HairVertexTangentsBuffer, VK_ACCESS_MEMORY_READ_BIT, - VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT)}; - - vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(makeTangentBarrier), makeTangentBarrier, 0, - nullptr); + vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(makeTangentBarrier), makeTangentBarrier, 0, + nullptr); + } // Compute tangents for every vertex (guide + follow) { int numOfGroupsForCS_TotalVertexLevel = (int)(((float)(m_pTressFXMesh->m_HairAsset.m_NumTotalHairVertices) / - (float)THREAD_GROUP_SIZE) * - density); + (float)THREAD_GROUP_SIZE) * + density); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSComputeTangents); - VkDescriptorSet computeTangentSet[] = {m_configSet, - m_pTressFXMesh->m_ComputeTangentSet}; + m_CSComputeTangents); + VkDescriptorSet computeTangentSet[] = { m_configSet, + m_pTressFXMesh->m_ComputeTangentSet }; vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - m_CSComputeTangentsLayout, 0, - AMD_ARRAY_SIZE(computeTangentSet), computeTangentSet, - AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); + m_CSComputeTangentsLayout, 0, + AMD_ARRAY_SIZE(computeTangentSet), computeTangentSet, + AMD_ARRAY_SIZE(descriptorOffset), descriptorOffset); vkCmdDispatch(commandBuffer, numOfGroupsForCS_TotalVertexLevel, 1, 1); VkBufferMemoryBarrier computeTangentBarrier[] = { getBufferBarrier(m_pTressFXMesh->m_HairVertexTangentsBuffer, - VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, - VK_ACCESS_SHADER_READ_BIT)}; + VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT) }; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - AMD_ARRAY_SIZE(computeTangentBarrier), computeTangentBarrier, - 0, nullptr); + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, + AMD_ARRAY_SIZE(computeTangentBarrier), computeTangentBarrier, + 0, nullptr); } +} - return vr; +void TressFXSimulation::fillHeadConstantBuffer(ConstBufferCS_HeadTransform * pCSHeadTransform, bool singleHeadTransform, DirectX::XMMATRIX * pModelTransformForHead) +{ + pCSHeadTransform->bSingleHeadTransform = singleHeadTransform; + pCSHeadTransform->ModelRotateForHead = + XMQuaternionRotationMatrix(*pModelTransformForHead); + pCSHeadTransform->ModelTransformForHead = *pModelTransformForHead; +} + +void TressFXSimulation::fillConstantBuffer(ConstBufferCS_Per_Frame * pCSPerFrame, bool warp, bool bFullSimulate, float targetFrameRate, int numOfStrandsPerThreadGroup, float windMag, AMD::tressfx_vec3 & windDir, float fElapsedTime) +{ + pCSPerFrame->bWarp = warp; + + if (bFullSimulate) + { + pCSPerFrame->NumLengthConstraintIterations = + m_simParams.numLengthConstraintIterations; + } + else + { + pCSPerFrame->NumLengthConstraintIterations = 1; + } + + pCSPerFrame->bCollision = (m_simParams.bCollision == true) ? 1 : 0; + + pCSPerFrame->GravityMagnitude = m_simParams.gravityMagnitude; + + pCSPerFrame->timeStep = targetFrameRate; + + pCSPerFrame->NumOfStrandsPerThreadGroup = numOfStrandsPerThreadGroup; + pCSPerFrame->NumFollowHairsPerGuideHair = + (m_bGuideFollowHairPrev + ? m_pTressFXMesh->m_HairAsset.m_NumFollowHairsPerGuideHair + : 0); + pCSPerFrame->TipSeparationFactor = + m_pTressFXMesh->m_HairAsset.m_TipSeparationFactor; + + ComputeWindPyramid(pCSPerFrame->Wind, pCSPerFrame->Wind1, pCSPerFrame->Wind2, + pCSPerFrame->Wind3, windMag, windDir); + + int numSections = m_simParams.numHairSections; + + switch (numSections) + { + // hair section 3 + case 4: + pCSPerFrame->Damping3 = m_simParams.perSectionShapeParams[3].damping; + pCSPerFrame->StiffnessForLocalShapeMatching3 = + m_simParams.perSectionShapeParams[3].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching3 = + m_simParams.perSectionShapeParams[3].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange3 = + m_simParams.perSectionShapeParams[3].globalShapeMatchingEffectiveRange; + // hair section 2 + case 3: + pCSPerFrame->Damping2 = m_simParams.perSectionShapeParams[2].damping; + pCSPerFrame->StiffnessForLocalShapeMatching2 = + m_simParams.perSectionShapeParams[2].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching2 = + m_simParams.perSectionShapeParams[2].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange2 = + m_simParams.perSectionShapeParams[2].globalShapeMatchingEffectiveRange; + // hair section 1 + case 2: + pCSPerFrame->Damping1 = m_simParams.perSectionShapeParams[1].damping; + pCSPerFrame->StiffnessForLocalShapeMatching1 = + m_simParams.perSectionShapeParams[1].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching1 = + m_simParams.perSectionShapeParams[1].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange1 = + m_simParams.perSectionShapeParams[1].globalShapeMatchingEffectiveRange; + // hair section 0 + case 1: + pCSPerFrame->Damping0 = m_simParams.perSectionShapeParams[0].damping; + pCSPerFrame->StiffnessForLocalShapeMatching0 = + m_simParams.perSectionShapeParams[0].stiffnessForLocalShapeMatching; + pCSPerFrame->StiffnessForGlobalShapeMatching0 = + m_simParams.perSectionShapeParams[0].stiffnessForGlobalShapeMatching; + pCSPerFrame->GlobalShapeMatchingEffectiveRange0 = + m_simParams.perSectionShapeParams[0].globalShapeMatchingEffectiveRange; + } + + if (!bFullSimulate) + { + float h = fElapsedTime; + float h0 = targetFrameRate; + float s_min_scale = + 0.3f; // minimum stiffness = s_min_scale * current stiffness + + pCSPerFrame->StiffnessForLocalShapeMatching0 = getScaledStiffness( + m_simParams.perSectionShapeParams[0].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + pCSPerFrame->StiffnessForLocalShapeMatching1 = getScaledStiffness( + m_simParams.perSectionShapeParams[1].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + pCSPerFrame->StiffnessForLocalShapeMatching2 = getScaledStiffness( + m_simParams.perSectionShapeParams[2].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + pCSPerFrame->StiffnessForLocalShapeMatching3 = getScaledStiffness( + m_simParams.perSectionShapeParams[3].stiffnessForLocalShapeMatching, + s_min_scale, h, h0); + } + + if (bFullSimulate) + { + pCSPerFrame->NumLocalShapeMatchingIterations = + m_simParams.numLocalShapeMatchingIterations; + } + else + { + pCSPerFrame->NumLocalShapeMatchingIterations = 1; + } + + pCSPerFrame->NumVerticesPerStrand = g_TressFXNumVerticesPerStrand; } //-------------------------------------------------------------------------------------- @@ -1055,56 +1071,55 @@ VkResult TressFXSimulation::Simulate(VkDevice pvkDevice, VkCommandBuffer command //-------------------------------------------------------------------------------------- VkResult TressFXSimulation::CreateComputeShaderConstantBuffers( VkDevice pvkDevice, TressFX_CollisionCapsule *pCollision, - uint32_t maxUniformBufferCount, uint32_t cpu_memory_index, - uint32_t texture_memory_index) + uint32_t maxUniformBufferCount, VkPhysicalDeviceMemoryProperties memProperties) { (void)pCollision; VkResult vr = VK_SUCCESS; // const buffer for per frame data - VkBufferCreateInfo Desc{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + VkBufferCreateInfo Desc{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; // FIXME: Uniform buffer + compute shader crash nvidia driver Desc.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; Desc.size = maxUniformBufferCount * sizeof(ConstBufferCS_Per_Frame); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBCSPerFrame)); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBCSPerFrame)); m_pCBCSPerFrameMemory = - allocBufferMemory(pvkDevice, m_pCBCSPerFrame, cpu_memory_index); + allocBufferMemory(pvkDevice, m_pCBCSPerFrame, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); // const buffer for capsule collision Desc.size = sizeof(TressFX_CollisionCapsule); // data.pSysMem = (void *)pCollision; - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBCSCollisionCapsule)); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBCSCollisionCapsule)); m_pCBCSCollisionCapsuleMemory = - allocBufferMemory(pvkDevice, m_pCBCSCollisionCapsule, texture_memory_index); + allocBufferMemory(pvkDevice, m_pCBCSCollisionCapsule, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); /* void* scratch_buffer_mapped_memory; vkMapMemory(pvkDevice, ..., 0, sizeof(TressFX_CollisionCapsule), 0, - &scratch_buffer_mapped_memory); + &scratch_buffer_mapped_memory); memcpy(scratch_buffer_mapped_memory, pCollision, - sizeof(TressFX_CollisionCapsule)); + sizeof(TressFX_CollisionCapsule)); vkUnmapMemory(pvkDevice, ...); vkCmdCopyBuffer(..., ..., m_pCBCSCollisionCapsule, 1, );*/ - // const buffer for hair root transformation + // const buffer for hair root transformation Desc.size = sizeof(TransformConstantBuffer); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBGenerateTransforms)); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBGenerateTransforms)); m_pCBGenerateTransformsMemory = - allocBufferMemory(pvkDevice, m_pCBGenerateTransforms, cpu_memory_index); + allocBufferMemory(pvkDevice, m_pCBGenerateTransforms, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); // const buffer for head transformation Desc.size = sizeof(ConstBufferCS_HeadTransform); - AMD_V_RETURN(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBHeadTransforms)); + AMD_CHECKED_VULKAN_CALL(vkCreateBuffer(pvkDevice, &Desc, nullptr, &m_pCBHeadTransforms)); m_pCBHeadTransformsMemory = - allocBufferMemory(pvkDevice, m_pCBHeadTransforms, cpu_memory_index); + allocBufferMemory(pvkDevice, m_pCBHeadTransforms, memProperties, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - VkDescriptorBufferInfo perFrameCBCS{m_pCBCSPerFrame, 0, - sizeof(ConstBufferCS_Per_Frame)}; - VkDescriptorBufferInfo headTransform{m_pCBHeadTransforms, 0, - sizeof(ConstBufferCS_HeadTransform)}; + VkDescriptorBufferInfo perFrameCBCS{ m_pCBCSPerFrame, 0, + sizeof(ConstBufferCS_Per_Frame) }; + VkDescriptorBufferInfo headTransform{ m_pCBHeadTransforms, 0, + sizeof(ConstBufferCS_HeadTransform) }; VkWriteDescriptorSet writeSet[] = { getWriteDescriptor(m_configSet, IDSRV_CONSTANTS_BUFFER, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, &perFrameCBCS), + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, &perFrameCBCS), getWriteDescriptor(m_configSet, IDSRV_HEAD_TRANSFORM, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &headTransform), + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &headTransform), }; vkUpdateDescriptorSets(pvkDevice, AMD_ARRAY_SIZE(writeSet), writeSet, 0, nullptr); return VK_SUCCESS; @@ -1121,49 +1136,49 @@ void TressFXSimulation::OnDestroy(VkDevice pvkDevice) { { AMD_SAFE_RELEASE(m_CSIntegrationAndGlobalShapeConstraints, vkDestroyPipeline, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_CSApplyHairTransformGlobally, vkDestroyPipeline, pvkDevice); AMD_SAFE_RELEASE(m_CSComputeTangents, vkDestroyPipeline, pvkDevice); AMD_SAFE_RELEASE(m_CSLocalShapeConstraints, vkDestroyPipeline, pvkDevice); AMD_SAFE_RELEASE(m_CSLocalShapeConstraintsSingleDispatch, vkDestroyPipeline, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_CSLengthConstriantsWindAndCollision, vkDestroyPipeline, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_CSUpdateFollowHairVertices, vkDestroyPipeline, pvkDevice); AMD_SAFE_RELEASE(m_CSPrepareFollowHairBeforeTurningIntoGuide, vkDestroyPipeline, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_CSGenerateTransforms, vkDestroyPipeline, pvkDevice); AMD_SAFE_RELEASE(m_CSIntegrationAndGlobalShapeConstraintsLayout, - vkDestroyPipelineLayout, pvkDevice); + vkDestroyPipelineLayout, pvkDevice); // AMD_SAFE_RELEASE(m_CSApplyHairTransformGloballyLayout, vkDestroyPipelineLayout, // pvkDevice); AMD_SAFE_RELEASE(m_CSComputeTangentsLayout, vkDestroyPipelineLayout, pvkDevice); AMD_SAFE_RELEASE(m_CSLocalShapeConstraintsLayout, vkDestroyPipelineLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_CSLocalShapeConstraintsSingleDispatchLayout, - vkDestroyPipelineLayout, pvkDevice); + vkDestroyPipelineLayout, pvkDevice); AMD_SAFE_RELEASE(m_CSLengthConstriantsWindAndCollisionLayout, - vkDestroyPipelineLayout, pvkDevice); + vkDestroyPipelineLayout, pvkDevice); AMD_SAFE_RELEASE(m_CSUpdateFollowHairVerticesLayout, vkDestroyPipelineLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_CSPrepareFollowHairBeforeTurningIntoGuideLayout, - vkDestroyPipelineLayout, pvkDevice); + vkDestroyPipelineLayout, pvkDevice); // AMD_SAFE_RELEASE(m_CSGenerateTransformsLayout, vkDestroyPipelineLayout, // pvkDevice); AMD_SAFE_RELEASE(m_GlobalConstraintsSetLayout, vkDestroyDescriptorSetLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_LocalConstraintsSetLayout, vkDestroyDescriptorSetLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_LenghtWindTangentSetLayout, vkDestroyDescriptorSetLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_PrepareFollowHairSetLayout, vkDestroyDescriptorSetLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_UpdateFollowHaitSetLayout, vkDestroyDescriptorSetLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_ComputeTangentSetLayout, vkDestroyDescriptorSetLayout, - pvkDevice); + pvkDevice); AMD_SAFE_RELEASE(m_configSetLayout, vkDestroyDescriptorSetLayout, pvkDevice); } AMD_SAFE_RELEASE(m_descriptorPool, vkDestroyDescriptorPool, pvkDevice); @@ -1176,5 +1191,4 @@ void TressFXSimulation::OnDestroy(VkDevice pvkDevice) AMD_SAFE_RELEASE(m_pCBHeadTransforms, vkDestroyBuffer, pvkDevice); AMD_SAFE_RELEASE(m_pCBHeadTransformsMemory, vkFreeMemory, pvkDevice); } - } // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXSimulationVulkan.h b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.h index da6aec3..39f1dc8 100644 --- a/amd_tressfx_vulkan/src/TressFXSimulationVulkan.h +++ b/amd_tressfx_vulkan/src/TressFXSimulationVulkan.h @@ -38,31 +38,25 @@ typedef DirectX::XMFLOAT4 float4; typedef DirectX::XMFLOAT3 float3; +struct ConstBufferCS_Per_Frame; +struct ConstBufferCS_HeadTransform; + namespace AMD { - class TressFXSimulation { - public: +public: TressFXSimulation(void); ~TressFXSimulation(void); - VkResult OnCreateDevice(VkDevice pvkDevice, TressFX_CollisionCapsule *pCollision, - uint32_t maxUniformCount, uint32_t cpu_memory_index, - uint32_t gpu_memory_index); + VkResult OnCreateDevice(VkDevice pvkDevice, + TressFX_CollisionCapsule *pCollision, + uint32_t maxUniformCount, VkPhysicalDeviceMemoryProperties memProperties, const DebugMarkerPointer& markerCallbacks); VkResult Simulate(VkDevice pvkContext, VkCommandBuffer commandBuffer, - float fElapsedTime, float density, tressfx_vec3 &windDir, - float windMag, DirectX::XMMATRIX *pModelTransformForHead, - ID3D11UnorderedAccessView *pSkinningTransforms, - float targetFrameRate, bool singleHeadTransform, bool warp, - uint32_t uniformBufferIndex); - VkResult GenerateTransforms(VkDevice pvkContext, TressFX_SceneMesh sceneMesh, - ID3D11UnorderedAccessView **ppSkinningTransformationsUAV, - DirectX::XMMATRIX *pModelTransformForHead); - VkResult ApplyTransformGlobally(VkDevice pvkContext, - ID3D11UnorderedAccessView *pSkinningTransforms, - float density, bool singleHeadTransform, - DirectX::XMMATRIX *pModelTransformForHead); + float fElapsedTime, float density, tressfx_vec3 &windDir, + float windMag, DirectX::XMMATRIX *pModelTransformForHead, + float targetFrameRate, bool singleHeadTransform, bool warp, + uint32_t uniformBufferIndex, const DebugMarkerPointer& markerCallbacks); void OnDestroy(VkDevice pvkDevice); TressFXMesh *m_pTressFXMesh; float m_elapsedTimeSinceLastSim; @@ -75,7 +69,7 @@ class TressFXSimulation VkDescriptorSetLayout m_UpdateFollowHaitSetLayout; VkDescriptorSetLayout m_ComputeTangentSetLayout; - private: +private: bool m_bGuideFollowHairPrev; // hair simulation params @@ -117,17 +111,18 @@ class TressFXSimulation VkDeviceMemory m_pCBHeadTransformsMemory; VkResult CreateComputeShaderConstantBuffers(VkDevice pvkDevice, - TressFX_CollisionCapsule *pCollision, - uint32_t maxUniformBufferCount, - uint32_t memoryIndexCPU, - uint32_t memoryIndexGPU); + TressFX_CollisionCapsule *pCollision, + uint32_t maxUniformBufferCount, + VkPhysicalDeviceMemoryProperties memProps); VkResult CreateDescriptorSet(VkDevice pvkDevice); - public: + void fillConstantBuffer(ConstBufferCS_Per_Frame * pCSPerFrame, bool warp, bool bFullSimulate, float targetFrameRate, int numOfStrandsPerThreadGroup, float windMag, AMD::tressfx_vec3 & windDir, float fElapsedTime); + void fillHeadConstantBuffer(ConstBufferCS_HeadTransform * pCSHeadTransform, bool singleHeadTransform, DirectX::XMMATRIX * pModelTransformForHead); + void fillSimulationCommands(const VkCommandBuffer &commandBuffer, float &density, const uint32_t &uniformBufferIndex); +public: void SetSimulationParams(const TressFX_SimulationParams &simParams) { m_simParams = simParams; } }; - } // namespace AMD diff --git a/amd_tressfx_vulkan/src/TressFXVulkan.cpp b/amd_tressfx_vulkan/src/TressFXVulkan.cpp index 5faf793..a1048cb 100644 --- a/amd_tressfx_vulkan/src/TressFXVulkan.cpp +++ b/amd_tressfx_vulkan/src/TressFXVulkan.cpp @@ -79,9 +79,13 @@ TressFX_Initialize(TressFX_Desc &desc, VkImageView depthTexture, VkImageView col VkBuffer scratchBuffer, size_t &offsetInScratchBuffer) { desc.pOpaque = &gTressFXOpaqueDesc; - desc.pOpaque->Initialize(desc, depthTexture, colorTexture, commandBuffer, - scratchMemory, scratchBuffer, offsetInScratchBuffer, - desc.memoryIndexHostVisible, desc.memoryIndexDeviceLocal); + desc.pOpaque->Initialize(desc, depthTexture, + colorTexture, + commandBuffer, + scratchMemory, + scratchBuffer, + offsetInScratchBuffer, + desc.memoryProperties); desc.pTressFXMesh = NULL; desc.groupID = 0; @@ -135,8 +139,10 @@ TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_LoadProcessedAsset( pTressFXMesh = new TressFXMesh(); memcpy(desc.tressFXHair.pHair, pHairBlob->pHair, pHairBlob->size); desc.tressFXHair.size = pHairBlob->size; - pTressFXMesh->OnCreate(desc.pvkDevice, &desc.tressFXHair, sceneMesh, pTressFXTexture, - desc.memoryIndexDeviceLocal, uploadCmdBuffer, scratchBuffer, + pTressFXMesh->OnCreate(desc.pvkDevice, &desc.tressFXHair, sceneMesh, + pTressFXTexture, + desc.memoryProperties, uploadCmdBuffer, + scratchBuffer, scratchMemory, desc.pOpaque->tressFXSimulation.m_GlobalConstraintsSetLayout, desc.pOpaque->tressFXSimulation.m_LocalConstraintsSetLayout, @@ -145,7 +151,8 @@ TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_LoadProcessedAsset( desc.pOpaque->tressFXSimulation.m_UpdateFollowHaitSetLayout, desc.pOpaque->tressFXSimulation.m_ComputeTangentSetLayout, desc.pOpaque->tressFXRenderer.m_pass1_hair_set_layout, - desc.pOpaque->tressFXRenderer.m_shadow_pass_hair_set_layout); + desc.pOpaque->tressFXRenderer.m_shadow_pass_hair_set_layout, + desc.pOpaque->markerCallbacks); desc.numTotalHairStrands = pTressFXMesh->m_HairAsset.m_NumTotalHairStrands; desc.numTotalHairVertices = pTressFXMesh->m_HairAsset.m_NumTotalHairVertices; desc.pTressFXMesh = (void *)pTressFXMesh; @@ -169,7 +176,7 @@ TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_CreateProcessedAsset( VkDeviceMemory scratchMemory) { bool success = desc.pOpaque->CreateProcessedAsset( - desc, ppHairBlob, sceneMesh, hairTexture, desc.memoryIndexDeviceLocal, + desc, ppHairBlob, sceneMesh, hairTexture, desc.memoryProperties, uploadCmdBuffer, scratchBuffer, scratchMemory); desc.groupID = 0; return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); @@ -257,9 +264,9 @@ TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_End(TressFX_Desc &desc) // //-------------------------------------------------------------------------------------- TRESSFX_RETURN_CODE AMD_TRESSFX_DLL_API TressFX_Resize(TressFX_Desc &desc, - uint32_t texture_memory_index) + VkPhysicalDeviceMemoryProperties memProperties) { - bool success = desc.pOpaque->Resize(desc, texture_memory_index); + bool success = desc.pOpaque->Resize(desc, memProperties); return (success ? TRESSFX_RETURN_CODE_SUCCESS : TRESSFX_RETURN_CODE_FAIL); } diff --git a/amd_tressfx_vulkan/src/UtilVulkan.cpp b/amd_tressfx_vulkan/src/UtilVulkan.cpp index d39b907..3e43d8c 100644 --- a/amd_tressfx_vulkan/src/UtilVulkan.cpp +++ b/amd_tressfx_vulkan/src/UtilVulkan.cpp @@ -17,15 +17,39 @@ ShaderModule::~ShaderModule() vkDestroyShaderModule(m_pvkDevice, m_shaderModule, nullptr); } + +uint32_t getMemoryTypeIndex(uint32_t typeBits, const VkPhysicalDeviceMemoryProperties &memprops, VkMemoryPropertyFlags properties) +{ + // Iterate over all memory types available for the device used in this example + for (uint32_t i = 0; i < memprops.memoryTypeCount; i++) + { + if ((typeBits & 1) == 1) + { + if ((memprops.memoryTypes[i].propertyFlags & properties) == properties) + { + return i; + } + } + typeBits >>= 1; + } + return static_cast(-1); +} + +VkDeviceSize align(VkDeviceSize offset, VkDeviceSize alignment) +{ + return ((offset + alignment - 1) / alignment) * alignment; +} + + VkDeviceMemory allocBufferMemory(VkDevice dev, VkBuffer buffer, - uint32_t texture_memory_index) + const VkPhysicalDeviceMemoryProperties &memprops, VkMemoryPropertyFlags properties) { VkMemoryRequirements memReqs; vkGetBufferMemoryRequirements(dev, buffer, &memReqs); VkMemoryAllocateInfo allocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; allocateInfo.allocationSize = memReqs.size; - allocateInfo.memoryTypeIndex = texture_memory_index; + allocateInfo.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, memprops, properties); VkDeviceMemory result; vkAllocateMemory(dev, &allocateInfo, nullptr, &result); vkBindBufferMemory(dev, buffer, result, 0); @@ -33,14 +57,14 @@ VkDeviceMemory allocBufferMemory(VkDevice dev, VkBuffer buffer, } VkDeviceMemory allocImageMemory(VkDevice dev, VkImage image, - uint32_t texture_memory_index) + const VkPhysicalDeviceMemoryProperties &memprops) { VkMemoryRequirements memReqs; vkGetImageMemoryRequirements(dev, image, &memReqs); VkMemoryAllocateInfo allocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; allocateInfo.allocationSize = memReqs.size; - allocateInfo.memoryTypeIndex = texture_memory_index; + allocateInfo.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, memprops, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VkDeviceMemory result; vkAllocateMemory(dev, &allocateInfo, nullptr, &result); vkBindImageMemory(dev, image, result, 0); @@ -91,10 +115,10 @@ void fillInitialData(VkCommandBuffer commandBuffer, VkBuffer scratchBuffer, size_t &offsetInScratchBuffer, VkDeviceSize size) { memcpy(reinterpret_cast(pScratchBuffer) + offsetInScratchBuffer, - pDataToUpload, size); + pDataToUpload, static_cast(size)); VkBufferCopy copyInfo{offsetInScratchBuffer, 0, static_cast(size)}; vkCmdCopyBuffer(commandBuffer, scratchBuffer, destBuffer, 1, ©Info); - offsetInScratchBuffer += size; + offsetInScratchBuffer += static_cast(size); } VkResult getDescriptorLayout(VkDevice pvkDevice, const VkDescriptorSetLayoutBinding *ptr, @@ -106,13 +130,13 @@ VkResult getDescriptorLayout(VkDevice pvkDevice, const VkDescriptorSetLayoutBind info.pBindings = ptr; VkResult vr; - AMD_V_RETURN(vkCreateDescriptorSetLayout(pvkDevice, &info, nullptr, &result)); + AMD_CHECKED_VULKAN_CALL(vkCreateDescriptorSetLayout(pvkDevice, &info, nullptr, &result)); return VK_SUCCESS; } VkBufferMemoryBarrier getBufferBarrier(VkBuffer buffer, VkAccessFlags srcAccess, VkAccessFlags dstAccess, size_t offset, - size_t size) + uint64_t size) { VkBufferMemoryBarrier result{VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER}; result.buffer = buffer; @@ -214,7 +238,7 @@ VkGraphicsPipelineCreateInfo CommonPipelineState::getBasePipelineCreateInfo( namespace { VkPipelineDepthStencilStateCreateInfo -getSpecializedDSS(bool depth_test_enable, bool depth_write_enable, +getSpecializedDepthStencilState(bool depth_test_enable, bool depth_write_enable, bool stencil_test_enable, VkCompareOp stencil_op, VkStencilOp pass_op, uint32_t write_mask) { @@ -266,29 +290,20 @@ const VkPipelineColorBlendAttachmentState m_pSum_BS_render_target_0{ VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT}; - -// Full screen quad layout structure -const VkVertexInputBindingDescription layout_quad_bindings[1] = { - {0, 32, VK_VERTEX_INPUT_RATE_VERTEX}}; -const VkVertexInputAttributeDescription layout_quad[3] = { - {0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0}, // POSITION - {1, 0, VK_FORMAT_R32G32B32_SFLOAT, 12}, // TANGENT - {2, 0, VK_FORMAT_R32G32_SFLOAT, 24}, // TEXCOORD -}; } const VkPipelineDepthStencilStateCreateInfo CommonPipelineState::DepthTestEnabledDesc = - getSpecializedDSS(true, true, false, VK_COMPARE_OP_NEVER, VK_STENCIL_OP_KEEP, 0xff); + getSpecializedDepthStencilState(true, true, false, VK_COMPARE_OP_NEVER, VK_STENCIL_OP_KEEP, 0xff); const VkPipelineDepthStencilStateCreateInfo CommonPipelineState::DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc = - getSpecializedDSS(true, false, true, VK_COMPARE_OP_ALWAYS, + getSpecializedDepthStencilState(true, false, true, VK_COMPARE_OP_ALWAYS, VK_STENCIL_OP_INCREMENT_AND_WRAP, 0xff); const VkPipelineDepthStencilStateCreateInfo - CommonPipelineState::DepthTestDisabledStencilTestLessDSS = getSpecializedDSS( + CommonPipelineState::DepthTestDisabledStencilTestLessDSS = getSpecializedDepthStencilState( false, false, true, VK_COMPARE_OP_LESS, VK_STENCIL_OP_KEEP, 0x00); const VkPipelineDepthStencilStateCreateInfo CommonPipelineState::m_pDepthWriteEnabledStencilTestLess_DSS = - getSpecializedDSS(true, true, true, VK_COMPARE_OP_LESS, VK_STENCIL_OP_KEEP, 0x0); + getSpecializedDepthStencilState(true, true, true, VK_COMPARE_OP_LESS, VK_STENCIL_OP_KEEP, 0x0); // disable color write if there is no need for fragments counting const VkPipelineColorBlendStateCreateInfo CommonPipelineState::ColorWritesOff{ @@ -334,14 +349,14 @@ const VkPipelineVertexInputStateCreateInfo CommonPipelineState::m_pLayoutQuad{ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, nullptr, 0, - 1, - layout_quad_bindings, - 3, - layout_quad}; + 0, + nullptr, + 0, + nullptr}; VkImageMemoryBarrier getImageMemoryBarrier(VkImage image, VkAccessFlags srcMask, VkAccessFlags dstMask, VkImageLayout oldLayout, - VkImageLayout newLayout, + VkImageLayout newLayout, uint32_t layoutCount, VkImageAspectFlags aspect) { VkImageMemoryBarrier memoryBarrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER}; @@ -351,8 +366,8 @@ VkImageMemoryBarrier getImageMemoryBarrier(VkImage image, VkAccessFlags srcMask, memoryBarrier.newLayout = newLayout; memoryBarrier.image = image; memoryBarrier.subresourceRange.aspectMask = aspect; - memoryBarrier.subresourceRange.levelCount = - memoryBarrier.subresourceRange.layerCount = 1; + memoryBarrier.subresourceRange.levelCount = 1; + memoryBarrier.subresourceRange.layerCount = layoutCount; return memoryBarrier; } diff --git a/amd_tressfx_vulkan/src/UtilVulkan.h b/amd_tressfx_vulkan/src/UtilVulkan.h index 046f58b..b5c396b 100644 --- a/amd_tressfx_vulkan/src/UtilVulkan.h +++ b/amd_tressfx_vulkan/src/UtilVulkan.h @@ -3,7 +3,7 @@ #include #include -#define AMD_V_RETURN(x) \ +#define AMD_CHECKED_VULKAN_CALL(x) \ { \ vr = (x); \ if (vr != VK_SUCCESS) \ @@ -12,103 +12,185 @@ } \ } -namespace AMD -{ -struct ShaderModule -{ - VkShaderModule m_shaderModule; - - ShaderModule(VkDevice dev, const std::vector &code); - ~ShaderModule(); - - private: - VkDevice m_pvkDevice; -}; - -VkDeviceMemory allocBufferMemory(VkDevice dev, VkBuffer buffer, - uint32_t texture_memory_index); -VkDeviceMemory allocImageMemory(VkDevice dev, VkImage image, - uint32_t texture_memory_index); - -VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, - VkDescriptorType descriptorType, - const VkBufferView *texelBufferView); +#undef AMD_SAFE_RELEASE +#define AMD_SAFE_RELEASE(object, releaseFunction, device) if (object != VK_NULL_HANDLE) releaseFunction(device, object, nullptr); -VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, - VkDescriptorType descriptorType, - const VkDescriptorBufferInfo *Bufferdescriptor); - -VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, - VkDescriptorType descriptorType, - const VkDescriptorImageInfo *descriptor); - -void fillInitialData(VkCommandBuffer commandBuffer, VkBuffer scratchBuffer, - void *pScratchBuffer, void *pDataToUpload, VkBuffer destBuffer, - size_t &offsetInScratchBuffer, VkDeviceSize size); - -VkResult getDescriptorLayout(VkDevice pvkDevice, const VkDescriptorSetLayoutBinding *ptr, - size_t count, VkDescriptorSetLayout &result); -VkBufferMemoryBarrier getBufferBarrier(VkBuffer buffer, VkAccessFlags srcAccess, - VkAccessFlags dstAccess, size_t offset = 0, - size_t size = VK_WHOLE_SIZE); - -VkPipelineShaderStageCreateInfo getShaderStageCreateInfo(VkShaderModule module, - VkShaderStageFlagBits stage, - const char *shaderName); - -VkImageCreateInfo getImageCreateInfo(VkFormat format, uint32_t width, uint32_t height, - VkImageUsageFlags usage, uint32_t layers = 1); - -struct CommonPipelineState +namespace AMD { - // No tesselation - static const VkPipelineTessellationStateCreateInfo tessellationState; - // One viewport and scissor - static const VkDynamicState dynamicStates[2]; - static const VkPipelineDynamicStateCreateInfo dynamicState; - // One sample - static const VkPipelineMultisampleStateCreateInfo multisampleState; - // One viewport - static const VkPipelineViewportStateCreateInfo viewportState; - static const VkPipelineRasterizationStateCreateInfo rasterizationCreateInfo; - - static const VkPipelineVertexInputStateCreateInfo m_pLayoutHair; - // Full screen quad layout structure - static const VkPipelineVertexInputStateCreateInfo m_pLayoutQuad; - - // Triangles list - static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyTriangle; - // Lines list - static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyLine; - - static VkGraphicsPipelineCreateInfo getBasePipelineCreateInfo( - const VkPipelineVertexInputStateCreateInfo *vertex_input_state, - const VkPipelineDepthStencilStateCreateInfo *depth_stencil_state, - const VkPipelineColorBlendStateCreateInfo *color_blend_state, - const VkPipelineInputAssemblyStateCreateInfo *input_assembly, - const VkPipelineShaderStageCreateInfo *stages, VkPipelineLayout layout, - VkRenderPass render_pass, uint32_t subpass); - - static const VkPipelineDepthStencilStateCreateInfo DepthTestEnabledDesc; - // Enable depth test to use early z, disable depth write to make sure required layers - // won't be clipped out in early z - static const VkPipelineDepthStencilStateCreateInfo - DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc; - static const VkPipelineDepthStencilStateCreateInfo - DepthTestDisabledStencilTestLessDSS; - static const VkPipelineDepthStencilStateCreateInfo - m_pDepthWriteEnabledStencilTestLess_DSS; - - // disable color write if there is no need for fragments counting - static const VkPipelineColorBlendStateCreateInfo ColorWritesOff; - static const VkPipelineColorBlendStateCreateInfo BlendStateBlendToBg; - static const VkPipelineColorBlendStateCreateInfo m_pDepthWritesToColor_BS; - static const VkPipelineColorBlendStateCreateInfo m_pResolveColor_BS; - static const VkPipelineColorBlendStateCreateInfo m_pSum_BS; -}; - -VkImageMemoryBarrier -getImageMemoryBarrier(VkImage image, VkAccessFlags srcMask, VkAccessFlags dstMask, - VkImageLayout oldLayout, VkImageLayout newLayout, - VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT); + struct DebugMarkerPointer + { + DebugMarkerPointer() {} + + void init(VkDevice device) + { + dev = device; + pfnDebugMarkerSetObjectTag = (PFN_vkDebugMarkerSetObjectTagEXT)vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectTagEXT"); + pfnDebugMarkerSetObjectName = (PFN_vkDebugMarkerSetObjectNameEXT)vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectNameEXT"); + pfnCmdDebugMarkerBegin = (PFN_vkCmdDebugMarkerBeginEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerBeginEXT"); + pfnCmdDebugMarkerEnd = (PFN_vkCmdDebugMarkerEndEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerEndEXT"); + pfnCmdDebugMarkerInsert = (PFN_vkCmdDebugMarkerInsertEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerInsertEXT"); + } + + void nameObject(VkBuffer object, const char* name) const + { + nameObject_impl(VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, reinterpret_cast(object), name); + } + + void nameObject(VkBufferView object, const char* name) const + { + nameObject_impl(VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, reinterpret_cast(object), name); + } + + void nameObject(VkDeviceMemory object, const char* name) const + { + nameObject_impl(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, reinterpret_cast(object), name); + } + + void nameObject(VkPipeline object, const char* name) const + { + + nameObject_impl(VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, reinterpret_cast(object), name); + } + + void markBeginRegion(VkCommandBuffer cmdBuffer, const char* name) const + { + if (!pfnCmdDebugMarkerBegin) + return; + VkDebugMarkerMarkerInfoEXT info{ VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT }; + info.pMarkerName = name; + info.color[0] = 1.f; + pfnCmdDebugMarkerBegin(cmdBuffer, &info); + } + + void markEndRegion(VkCommandBuffer cmdBuffer) const + { + if (!pfnCmdDebugMarkerEnd) + return; + pfnCmdDebugMarkerEnd(cmdBuffer); + } + + private: + PFN_vkDebugMarkerSetObjectTagEXT pfnDebugMarkerSetObjectTag = NULL; + PFN_vkDebugMarkerSetObjectNameEXT pfnDebugMarkerSetObjectName = NULL; + PFN_vkCmdDebugMarkerBeginEXT pfnCmdDebugMarkerBegin = NULL; + PFN_vkCmdDebugMarkerEndEXT pfnCmdDebugMarkerEnd = NULL; + PFN_vkCmdDebugMarkerInsertEXT pfnCmdDebugMarkerInsert = NULL; + + VkDevice dev; + + void nameObject_impl(VkDebugReportObjectTypeEXT type, uint64_t object, const char* name) const + { + if (!pfnDebugMarkerSetObjectName) + return; + VkDebugMarkerObjectNameInfoEXT info{ VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT }; + info.objectType = type; + info.object = object; + info.pObjectName = name; + pfnDebugMarkerSetObjectName(dev, &info); + } + }; + + + struct ShaderModule + { + VkShaderModule m_shaderModule; + + ShaderModule(VkDevice dev, const std::vector &code); + ~ShaderModule(); + private: + VkDevice m_pvkDevice; + + ShaderModule(const ShaderModule&) {}; + ShaderModule& operator=(const ShaderModule&) {}; + }; + + uint32_t getMemoryTypeIndex(uint32_t typeBits, const VkPhysicalDeviceMemoryProperties &memprops, VkMemoryPropertyFlags properties); + VkDeviceSize align(VkDeviceSize offset, VkDeviceSize alignment); + VkDeviceMemory allocBufferMemory(VkDevice dev, VkBuffer buffer, + const VkPhysicalDeviceMemoryProperties &memprops, VkMemoryPropertyFlags properties); + VkDeviceMemory allocImageMemory(VkDevice dev, VkImage image, + const VkPhysicalDeviceMemoryProperties &memprops); + + VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkBufferView *texelBufferView); + + VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkDescriptorBufferInfo *Bufferdescriptor); + + VkWriteDescriptorSet getWriteDescriptor(VkDescriptorSet dstSet, uint32_t dstBinding, + VkDescriptorType descriptorType, + const VkDescriptorImageInfo *descriptor); + + void fillInitialData(VkCommandBuffer commandBuffer, VkBuffer scratchBuffer, + void *pScratchBuffer, void *pDataToUpload, VkBuffer destBuffer, + size_t &offsetInScratchBuffer, VkDeviceSize size); + + VkResult getDescriptorLayout(VkDevice pvkDevice, const VkDescriptorSetLayoutBinding *ptr, + size_t count, VkDescriptorSetLayout &result); + VkBufferMemoryBarrier getBufferBarrier(VkBuffer buffer, VkAccessFlags srcAccess, + VkAccessFlags dstAccess, size_t offset = 0u, + uint64_t size = VK_WHOLE_SIZE); + + VkPipelineShaderStageCreateInfo getShaderStageCreateInfo(VkShaderModule module, + VkShaderStageFlagBits stage, + const char *shaderName); + + VkImageCreateInfo getImageCreateInfo(VkFormat format, uint32_t width, uint32_t height, + VkImageUsageFlags usage, uint32_t layers = 1); + + struct CommonPipelineState + { + // No tesselation + static const VkPipelineTessellationStateCreateInfo tessellationState; + // One viewport and scissor + static const VkDynamicState dynamicStates[2]; + static const VkPipelineDynamicStateCreateInfo dynamicState; + // One sample + static const VkPipelineMultisampleStateCreateInfo multisampleState; + // One viewport + static const VkPipelineViewportStateCreateInfo viewportState; + static const VkPipelineRasterizationStateCreateInfo rasterizationCreateInfo; + + static const VkPipelineVertexInputStateCreateInfo m_pLayoutHair; + // Full screen quad layout structure + static const VkPipelineVertexInputStateCreateInfo m_pLayoutQuad; + + // Triangles list + static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyTriangle; + // Lines list + static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyLine; + + static VkGraphicsPipelineCreateInfo getBasePipelineCreateInfo( + const VkPipelineVertexInputStateCreateInfo *vertex_input_state, + const VkPipelineDepthStencilStateCreateInfo *depth_stencil_state, + const VkPipelineColorBlendStateCreateInfo *color_blend_state, + const VkPipelineInputAssemblyStateCreateInfo *input_assembly, + const VkPipelineShaderStageCreateInfo *stages, VkPipelineLayout layout, + VkRenderPass render_pass, uint32_t subpass); + + static const VkPipelineDepthStencilStateCreateInfo DepthTestEnabledDesc; + // Enable depth test to use early z, disable depth write to make sure required layers + // won't be clipped out in early z + static const VkPipelineDepthStencilStateCreateInfo + DepthTestEnabledNoDepthWritesStencilWriteIncrementDesc; + static const VkPipelineDepthStencilStateCreateInfo + DepthTestDisabledStencilTestLessDSS; + static const VkPipelineDepthStencilStateCreateInfo + m_pDepthWriteEnabledStencilTestLess_DSS; + + // disable color write if there is no need for fragments counting + static const VkPipelineColorBlendStateCreateInfo ColorWritesOff; + static const VkPipelineColorBlendStateCreateInfo BlendStateBlendToBg; + static const VkPipelineColorBlendStateCreateInfo m_pDepthWritesToColor_BS; + static const VkPipelineColorBlendStateCreateInfo m_pResolveColor_BS; + static const VkPipelineColorBlendStateCreateInfo m_pSum_BS; + }; + + VkImageMemoryBarrier + getImageMemoryBarrier(VkImage image, VkAccessFlags srcMask, VkAccessFlags dstMask, + VkImageLayout oldLayout, VkImageLayout newLayout, + uint32_t layerCount, + VkImageAspectFlags aspect); } \ No newline at end of file