From cdd751dc2f5bf0851c795587aab4fd547e95b6a8 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 20 May 2017 13:20:23 -0700 Subject: Added asteroids sample --- Projects/Asteroids/.gitignore | 2 + Projects/Asteroids/DiligentD3D11.dds | Bin 0 -> 37340 bytes Projects/Asteroids/DiligentD3D12.dds | Bin 0 -> 37340 bytes Projects/Asteroids/DiligentGL.dds | Bin 0 -> 37340 bytes Projects/Asteroids/README.md | 12 + Projects/Asteroids/SDK/Include/d3dx12.h | 1508 ++++++++++++++++++++ Projects/Asteroids/asteroids.vcxproj | 288 ++++ Projects/Asteroids/asteroids.vcxproj.filters | 124 ++ Projects/Asteroids/directx11.dds | Bin 0 -> 28128 bytes Projects/Asteroids/directx12.dds | Bin 0 -> 28128 bytes Projects/Asteroids/license.txt | 50 + Projects/Asteroids/src/DDSTextureLoader.cpp | 1103 ++++++++++++++ Projects/Asteroids/src/DDSTextureLoader.h | 18 + Projects/Asteroids/src/WinWrapper.cpp | 616 ++++++++ Projects/Asteroids/src/asteroid_ps.hlsl | 50 + Projects/Asteroids/src/asteroid_ps_d3d11.hlsl | 56 + Projects/Asteroids/src/asteroid_vs.hlsl | 36 + Projects/Asteroids/src/asteroids_DE.cpp | 870 +++++++++++ Projects/Asteroids/src/asteroids_DE.h | 123 ++ Projects/Asteroids/src/asteroids_d3d11.cpp | 594 ++++++++ Projects/Asteroids/src/asteroids_d3d11.h | 108 ++ Projects/Asteroids/src/asteroids_d3d12.cpp | 938 ++++++++++++ Projects/Asteroids/src/asteroids_d3d12.h | 182 +++ Projects/Asteroids/src/asteroids_d3d12.ico | Bin 0 -> 2998 bytes Projects/Asteroids/src/camera.cpp | 170 +++ Projects/Asteroids/src/camera.h | 62 + Projects/Asteroids/src/common.hlsl | 45 + Projects/Asteroids/src/common_defines.h | 6 + Projects/Asteroids/src/dds.h | 145 ++ Projects/Asteroids/src/descriptor.h | 165 +++ Projects/Asteroids/src/font.h | 98 ++ Projects/Asteroids/src/font_ps.hlsl | 12 + Projects/Asteroids/src/gui.h | 149 ++ .../Asteroids/src/intel_clear_bd_50_usascii.inl | 920 ++++++++++++ Projects/Asteroids/src/mesh.cpp | 352 +++++ Projects/Asteroids/src/mesh.h | 74 + Projects/Asteroids/src/noise.h | 57 + Projects/Asteroids/src/settings.h | 92 ++ Projects/Asteroids/src/simplexnoise1234.c | 499 +++++++ Projects/Asteroids/src/simplexnoise1234.h | 70 + Projects/Asteroids/src/simulation.cpp | 250 ++++ Projects/Asteroids/src/simulation.h | 90 ++ Projects/Asteroids/src/skybox_ps.hlsl | 16 + Projects/Asteroids/src/skybox_vs.hlsl | 20 + Projects/Asteroids/src/sprite.h | 36 + Projects/Asteroids/src/sprite_ps.hlsl | 11 + Projects/Asteroids/src/sprite_vs.hlsl | 14 + .../src/stb_font_consolas_bold_50_usascii.inl | 1195 ++++++++++++++++ Projects/Asteroids/src/subset_d3d12.h | 50 + Projects/Asteroids/src/texture.cpp | 285 ++++ Projects/Asteroids/src/texture.h | 46 + Projects/Asteroids/src/upload_heap.h | 60 + Projects/Asteroids/src/util.h | 79 + Projects/Asteroids/starbox_1024.dds | Bin 0 -> 25165952 bytes 54 files changed, 11746 insertions(+) create mode 100644 Projects/Asteroids/.gitignore create mode 100644 Projects/Asteroids/DiligentD3D11.dds create mode 100644 Projects/Asteroids/DiligentD3D12.dds create mode 100644 Projects/Asteroids/DiligentGL.dds create mode 100644 Projects/Asteroids/README.md create mode 100644 Projects/Asteroids/SDK/Include/d3dx12.h create mode 100644 Projects/Asteroids/asteroids.vcxproj create mode 100644 Projects/Asteroids/asteroids.vcxproj.filters create mode 100644 Projects/Asteroids/directx11.dds create mode 100644 Projects/Asteroids/directx12.dds create mode 100644 Projects/Asteroids/license.txt create mode 100644 Projects/Asteroids/src/DDSTextureLoader.cpp create mode 100644 Projects/Asteroids/src/DDSTextureLoader.h create mode 100644 Projects/Asteroids/src/WinWrapper.cpp create mode 100644 Projects/Asteroids/src/asteroid_ps.hlsl create mode 100644 Projects/Asteroids/src/asteroid_ps_d3d11.hlsl create mode 100644 Projects/Asteroids/src/asteroid_vs.hlsl create mode 100644 Projects/Asteroids/src/asteroids_DE.cpp create mode 100644 Projects/Asteroids/src/asteroids_DE.h create mode 100644 Projects/Asteroids/src/asteroids_d3d11.cpp create mode 100644 Projects/Asteroids/src/asteroids_d3d11.h create mode 100644 Projects/Asteroids/src/asteroids_d3d12.cpp create mode 100644 Projects/Asteroids/src/asteroids_d3d12.h create mode 100644 Projects/Asteroids/src/asteroids_d3d12.ico create mode 100644 Projects/Asteroids/src/camera.cpp create mode 100644 Projects/Asteroids/src/camera.h create mode 100644 Projects/Asteroids/src/common.hlsl create mode 100644 Projects/Asteroids/src/common_defines.h create mode 100644 Projects/Asteroids/src/dds.h create mode 100644 Projects/Asteroids/src/descriptor.h create mode 100644 Projects/Asteroids/src/font.h create mode 100644 Projects/Asteroids/src/font_ps.hlsl create mode 100644 Projects/Asteroids/src/gui.h create mode 100644 Projects/Asteroids/src/intel_clear_bd_50_usascii.inl create mode 100644 Projects/Asteroids/src/mesh.cpp create mode 100644 Projects/Asteroids/src/mesh.h create mode 100644 Projects/Asteroids/src/noise.h create mode 100644 Projects/Asteroids/src/settings.h create mode 100644 Projects/Asteroids/src/simplexnoise1234.c create mode 100644 Projects/Asteroids/src/simplexnoise1234.h create mode 100644 Projects/Asteroids/src/simulation.cpp create mode 100644 Projects/Asteroids/src/simulation.h create mode 100644 Projects/Asteroids/src/skybox_ps.hlsl create mode 100644 Projects/Asteroids/src/skybox_vs.hlsl create mode 100644 Projects/Asteroids/src/sprite.h create mode 100644 Projects/Asteroids/src/sprite_ps.hlsl create mode 100644 Projects/Asteroids/src/sprite_vs.hlsl create mode 100644 Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl create mode 100644 Projects/Asteroids/src/subset_d3d12.h create mode 100644 Projects/Asteroids/src/texture.cpp create mode 100644 Projects/Asteroids/src/texture.h create mode 100644 Projects/Asteroids/src/upload_heap.h create mode 100644 Projects/Asteroids/src/util.h create mode 100644 Projects/Asteroids/starbox_1024.dds (limited to 'Projects') diff --git a/Projects/Asteroids/.gitignore b/Projects/Asteroids/.gitignore new file mode 100644 index 0000000..2dc16a1 --- /dev/null +++ b/Projects/Asteroids/.gitignore @@ -0,0 +1,2 @@ +!libittnotify.lib + diff --git a/Projects/Asteroids/DiligentD3D11.dds b/Projects/Asteroids/DiligentD3D11.dds new file mode 100644 index 0000000..428f1d3 Binary files /dev/null and b/Projects/Asteroids/DiligentD3D11.dds differ diff --git a/Projects/Asteroids/DiligentD3D12.dds b/Projects/Asteroids/DiligentD3D12.dds new file mode 100644 index 0000000..4f04ac0 Binary files /dev/null and b/Projects/Asteroids/DiligentD3D12.dds differ diff --git a/Projects/Asteroids/DiligentGL.dds b/Projects/Asteroids/DiligentGL.dds new file mode 100644 index 0000000..1406643 Binary files /dev/null and b/Projects/Asteroids/DiligentGL.dds differ diff --git a/Projects/Asteroids/README.md b/Projects/Asteroids/README.md new file mode 100644 index 0000000..89b379d --- /dev/null +++ b/Projects/Asteroids/README.md @@ -0,0 +1,12 @@ +Asteroids D3D12 +=============== + +The Intel asteroids sample was developed as an example of how to use the DirectX 12 graphics API to get performance and power benefits over previous APIs. For more information on the sample, please see: https://software.intel.com/en-us/blogs/2014/08/11/siggraph-2014-directx-12-on-intel + +Requirements +============ +- Windows 10. The application will run on older operating systems but the DirectX 12 path will not be available. +- Visual Studio 2015 with the Windows 10 SDK. +- DirectX 12 capable hardware and drivers. For instance, Intel HD Graphics 4400 or newer. + +For more information on Intel graphics and game code, please visit https://software.intel.com/gamedev diff --git a/Projects/Asteroids/SDK/Include/d3dx12.h b/Projects/Asteroids/SDK/Include/d3dx12.h new file mode 100644 index 0000000..ba59dfc --- /dev/null +++ b/Projects/Asteroids/SDK/Include/d3dx12.h @@ -0,0 +1,1508 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx12.h +// Content: D3DX12 utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() + {} + explicit CD3DX12_RECT( const D3D12_RECT& o ) : + D3D12_RECT( o ) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } + ~CD3DX12_RECT() {} + operator const D3D12_RECT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() + {} + explicit CD3DX12_BOX( const D3D12_BOX& o ) : + D3D12_BOX( o ) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right ) + { + left = Left; + top = 0; + front = 0; + right = Right; + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + front = 0; + right = Right; + bottom = Bottom; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) + { + left = Left; + top = Top; + front = Front; + right = Right; + bottom = Bottom; + back = Back; + } + ~CD3DX12_BOX() {} + operator const D3D12_BOX&() const { return *this; } +}; +inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } + ~CD3DX12_DEPTH_STENCIL_DESC() {} + operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() + {} + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } + ~CD3DX12_BLEND_DESC() {} + operator const D3D12_BLEND_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() + {} + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } + ~CD3DX12_RASTERIZER_DESC() {} + operator const D3D12_RASTERIZER_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() + {} + explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) : + D3D12_RESOURCE_ALLOCATION_INFO( o ) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment ) + { + SizeInBytes = size; + Alignment = alignment; + } + operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() + {} + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + operator const D3D12_HEAP_PROPERTIES&() const { return *this; } + bool IsCPUAccessible() const + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() + {} + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + operator const D3D12_HEAP_DESC&() const { return *this; } + bool IsCPUAccessible() const + { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } +}; +inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() + {} + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4] ) + { + Format = format; + memcpy( Color, color, sizeof( Color ) ); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil ) + { + Format = format; + /* Use memcpy to preserve NAN values */ + memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); + DepthStencil.Stencil = stencil; + } + operator const D3D12_CLEAR_VALUE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() + {} + explicit CD3DX12_RANGE(const D3D12_RANGE &o) : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end ) + { + Begin = begin; + End = end; + } + operator const D3D12_RANGE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() + {} + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource ) + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } + operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() + {} + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth ) + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } + operator const D3D12_TILE_REGION_SIZE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() + {} + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource ) + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_SUBRESOURCE_TILING&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() + {} + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels ) + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } + operator const D3D12_TILE_SHAPE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() + {} + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } + operator const D3D12_RESOURCE_BARRIER&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() + {} + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource ) + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_PACKED_MIP_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() + {} + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch ) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch ) + { + Format = resDesc.Format; + Width = UINT( resDesc.Width ); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } + operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() + {} + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() { } + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() {} + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() {} + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() {} + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() {} + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() {} + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() {} + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) +{ + MipSlice = static_cast(Subresource % MipLevels); + ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {Format}; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() + {} + explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) : + D3D12_RESOURCE_DESC( o ) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags ) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags ); + } + inline UINT16 Depth() const + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } + operator const D3D12_RESOURCE_DESC&() const { return *this; } +}; +inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) +{ + for (UINT z = 0; z < NumSlices; ++z) + { + BYTE* pDestSlice = reinterpret_cast(pDest->pData) + pDest->SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(pSrc->pData) + pSrc->SlicePitch * z; + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * y, + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) +{ + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); + D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > (SIZE_T)-1 || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; + MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, NULL); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( pLayouts[0].Offset + pLayouts[0].Footprint.Width ) ); + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc)); + if (pMem == NULL) + { + return 0; + } + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources); + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) +{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } + +//------------------------------------------------------------------------------------------------ +inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp) +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast(pp); +} + + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ + + + diff --git a/Projects/Asteroids/asteroids.vcxproj b/Projects/Asteroids/asteroids.vcxproj new file mode 100644 index 0000000..4239f13 --- /dev/null +++ b/Projects/Asteroids/asteroids.vcxproj @@ -0,0 +1,288 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {176C9B9A-2E06-4AC5-B186-56C9280104E7} + Win32Proj + 10.0.10240.0 + Asteroids + + + + Application + true + v140 + + + Application + false + v140 + + + + + + + + + + + + + + + false + Build + FxCompile + + + false + Build + FxCompile + + + + WIN32;NOMINMAX;_CRT_SECURE_NO_WARNINGS;ENGINE_DLL;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + SDK\Include;$(IntDir);..\..\diligentcore\Graphics\GraphicsEngine\interface;..\..\diligentcore\Graphics\GraphicsEngineD3D11\interface;..\..\diligentcore\Graphics\GraphicsEngineD3D12\interface;..\..\diligentcore\Graphics\GraphicsEngineOpenGl\interface;..\..\diligentcore\Graphics\GraphicsTools\include;..\..\diligentcore\Platforms\interface;..\..\diligenttools\RenderScript\include;..\..\diligenttools\TextureLoader\interface;..\..\diligentcore\Common\interface;..\..\diligentcore\Common\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + Level3 + ProgramDatabase + Disabled + true + false + false + NotUsing + + + true + Console + d3d11.dll;d3d12.dll + d3dcompiler.lib;d3d12.lib;d3d11.lib;dxgi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib;winmm.lib;shcore.lib;ninput.lib;%(AdditionalDependencies) + SDK\Lib\x64;%(AdditionalLibraryDirectories) + + + + 5.0 + g_%(Filename) + $(IntDir)%(Filename).h + + %(Filename) + + + + + WIN32;NOMINMAX;_CRT_SECURE_NO_WARNINGS;ENGINE_DLL;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + SDK\Include;$(IntDir);..\..\diligentcore\Graphics\GraphicsEngine\interface;..\..\diligentcore\Graphics\GraphicsEngineD3D11\interface;..\..\diligentcore\Graphics\GraphicsEngineD3D12\interface;..\..\diligentcore\Graphics\GraphicsEngineOpenGl\interface;..\..\diligentcore\Graphics\GraphicsTools\include;..\..\diligentcore\Platforms\interface;..\..\diligenttools\RenderScript\include;..\..\diligenttools\TextureLoader\interface;..\..\diligentcore\Common\interface;..\..\diligentcore\Common\include;%(AdditionalIncludeDirectories) + MultiThreaded + Level3 + ProgramDatabase + true + false + NotUsing + + + true + Console + true + true + d3d11.dll;d3d12.dll + d3dcompiler.lib;d3d12.lib;d3d11.lib;dxgi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;delayimp.lib;winmm.lib;shcore.lib;ninput.lib;%(AdditionalDependencies) + SDK\Lib\x64;%(AdditionalLibraryDirectories) + + + + 5.0 + g_%(Filename) + $(IntDir)%(Filename).h + + %(Filename) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5.1 + 5.1 + + + + + Pixel + Pixel + + + Pixel + Pixel + + + Vertex + Vertex + + + Pixel + Pixel + + + Pixel + Pixel + + + Vertex + Vertex + + + Pixel + Pixel + + + Vertex + Vertex + + + + + Document + copy "%(RelativeDir)%(Filename).dll" "$(TargetDir)" +copy "%(RelativeDir)%(Filename).pdb" "$(TargetDir)" + Copying %(Filename).dll and %(Filename).pdb + $(TargetDir)%(Filename).dll + + + Document + copy "%(RelativeDir)%(Filename).dll" "$(TargetDir)" +copy "%(RelativeDir)%(Filename).pdb" "$(TargetDir)" + Copying %(Filename).dll and %(Filename).pdb + $(TargetDir)%(Filename).dll + + + Document + copy "%(RelativeDir)%(Filename).dll" "$(TargetDir)" +copy "%(RelativeDir)%(Filename).pdb" "$(TargetDir)" + Copying %(Filename).dll and %(Filename).pdb + $(TargetDir)%(Filename).dll + + + Document + copy "%(RelativeDir)%(Filename).dll" "$(TargetDir)" +copy "%(RelativeDir)%(Filename).pdb" "$(TargetDir)" + Copying %(Filename).dll and %(Filename).pdb + $(TargetDir)%(Filename).dll + + + Document + copy "%(RelativeDir)%(Filename).dll" "$(TargetDir)" +copy "%(RelativeDir)%(Filename).pdb" "$(TargetDir)" + Copying %(Filename).dll and %(Filename).pdb + $(TargetDir)%(Filename).dll + + + Document + copy "%(RelativeDir)%(Filename).dll" "$(TargetDir)" +copy "%(RelativeDir)%(Filename).pdb" "$(TargetDir)" + Copying %(Filename).dll and %(Filename).pdb + $(TargetDir)%(Filename).dll + + + + + + + + + + + + {7380f7e6-315f-4b4e-92eb-e6aeee865298} + + + {664e6f0d-6784-4760-9565-d54f8eb1edf4} + + + {fe289cc7-15d6-4a76-b9cb-f61cab3192c9} + + + {fff8071a-db82-485b-adc3-f0b675296869} + + + {15e346d3-fde6-4b29-88b7-fca14dada501} + + + {052dd700-477c-4512-a7f4-b05ebef5c80e} + + + {c6014499-0cf2-43ec-a773-a4e354fb2d74} + + + {8ada5f93-7a38-4ad8-b8f5-1ffd4d4f630c} + + + {58f32677-436b-412a-bbf8-2b1310d82cd8} + + + {019dbd2a-273d-4ba4-bf86-b5efe2ed76b1} + + + {97d592a8-5afe-4e72-8da9-3c3ef98948b1} + + + {822f4b60-069a-4f54-a219-dd4562a254a1} + + + {3f7fed43-207a-4c2c-80c4-5965448d0706} + + + {695c52b1-0267-4ded-bdf3-e7113756ff3f} + + + {c8add3b4-e83b-458e-96c8-b278f22c2f04} + + + {3de4fdb9-df4d-4b57-9ffe-616704d4fe2f} + + + + + + \ No newline at end of file diff --git a/Projects/Asteroids/asteroids.vcxproj.filters b/Projects/Asteroids/asteroids.vcxproj.filters new file mode 100644 index 0000000..70f8e77 --- /dev/null +++ b/Projects/Asteroids/asteroids.vcxproj.filters @@ -0,0 +1,124 @@ + + + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GUI + + + GUI + + + GUI + + + + + Shaders + + + + + + {8faf854c-ac25-4515-8f07-93a5c642b94b} + + + {bfe3f052-dc47-42b1-b2ed-8a41a5f87110} + + + {c8998999-1e17-41eb-be05-0a68278ef143} + + + {4d8d1863-88b5-4e85-a233-a65f32f19b4c} + + + + + GUI + + + GUI + + + + + Media + + + Media + + + Media + + + + + DLLs + + + DLLs + + + DLLs + + + DLLs + + + DLLs + + + DLLs + + + \ No newline at end of file diff --git a/Projects/Asteroids/directx11.dds b/Projects/Asteroids/directx11.dds new file mode 100644 index 0000000..5b91ecd Binary files /dev/null and b/Projects/Asteroids/directx11.dds differ diff --git a/Projects/Asteroids/directx12.dds b/Projects/Asteroids/directx12.dds new file mode 100644 index 0000000..ca157cd Binary files /dev/null and b/Projects/Asteroids/directx12.dds differ diff --git a/Projects/Asteroids/license.txt b/Projects/Asteroids/license.txt new file mode 100644 index 0000000..7e7eab0 --- /dev/null +++ b/Projects/Asteroids/license.txt @@ -0,0 +1,50 @@ +Code Samples License - Intel® Software Network +IMPORTANT - READ BEFORE COPYING, INSTALLING, OR USING. +Do not copy, install, or use the "Materials" provided under this license agreement ("Agreement"), until you have carefully read the following terms and conditions.By copying, installing, or otherwise using the Materials, you agree to be bound by the terms of this Agreement. If you do not agree to the terms of this Agreement, do not copy, install, or use the Materials. + + +INTEL® PRODUCT LICENSE AGREEMENT + +LICENSE GRANT: +Subject to the License Restrictions below, Intel Corporation ("Intel") grants to you the following non-exclusive, non-assignable royalty-free copyright licenses in the "Materials" below, which are identified specifically in License Definitions, and in any updates thereto that Intel may offer in the future. + +LICENSE DEFINITIONS: +Materials are defined as consisting of Sample Source, Redistributables, and End-User Documentation. + +Sample Source: may include example interface or application source code. You may copy, modify, and compile the Sample Source and distribute it in your own products in binary and source code form. + +Redistributables: include header, library, and dynamically linkable library files. You may copy and distribute Redistributables with your product. + +End-User Documentation: includes textual materials intended for end users. You may copy, modify, and distribute them. + +LICENSE RESTRICTIONS: +You may not reverse-assemble, reverse-compile, or otherwise reverse-engineer any software provided solely in binary form. + + Upon Intel's release of an update, upgrade, or new version of the Materials, you will make reasonable efforts to discontinue distribution of the enclosed Materials and you will make reasonable efforts to distribute such updates, upgrades, or new versions to your customers who have received the Materials herein. + +Distribution of the Materials is also subject to the following limitations: You i. shall be solely responsible to your customers for any update or support obligation or other liability which may arise from the distribution, +ii. do not make any statement that your product is "certified," or that its performance is guaranteed, by Intel, +iii. do not use Intel's name or trademarks to market your product without written permission, +iv. shall prohibit disassembly and reverse engineering, +v. shall not publish reviews of Materials designated herein as beta without written permission b y Intel, and +vi. shall indemnify, hold harmless, and defend Intel and its suppliers from and against any claims or lawsuits, including attorney's fees, that arise or result from your distribution of any product. +COPYRIGHT: +Title to the Materials and all copies thereof remain with Intel or its suppliers. The Materials are copyrighted and are protected by United States copyright laws and international treaty provisions. You will not remove any copyright notice from the Materials. You agree to prevent unauthorized copying of the Materials. Except as expressly provided herein, Intel does not grant any express or implied right to you under Intel patents, copyrights, trademarks, or trade secret information. + +REPLACEMENTS: +The Materials are provided "AS IS" without warranty of any kind. + +USER SUBMISSIONS: +You agree that any material, information, or other communication, including all data, images, sounds, text, and other things embodied therein, you transmit or post to an Intel website will be considered non-confidential ("Communications"). Intel will have no confidentiality obligations with respect to the Communications. You agree that Intel and its designees will be free to copy, modify, create derivative works, publicly display, disclose, distribute, license and sublicense through multiple tiers of distribution and licensees, incorporate, and otherwise use the Communications, including derivative works thereto, for any and all commercial or non-commercial purposes. + +LIMITATION OF LIABILITY: +THE ABOVE REPLACEMENT PROVISION IS THE ONLY WARRANTY OF ANY KIND. INTEL OFFERS NO OTHER WARRANTY EITHER EXPRESS OR IMPLIED INCLUDING THOSE OF MERCHANTABILITY, NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR A PARTICULAR PURPOSE. NEITHER INTEL NOR ITS SUPPLIERS SHALL BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +TERMINATION OF THIS LICENSE: +Intel may terminate this license at any time if you are in breach of any of its terms and conditions. Upon termination, you will immediately destroy the Materials or return all copies of the Materials to Intel along with any copies you have made. + +U.S. GOVERNMENT RESTRICTED RIGHTS: +The Materials are provided with "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is subject to restrictions set forth in FAR52.227-14 and DFAR252.227-7013 et. seq. or its successor. Use of the Materials by the Government constitutes acknowledgement of Intel's rights in them. + +APPLICABLE LAWS: +An y claim arising under or relating to this Agreement shall be governed by the internal substantive laws of the State of Delaware or federal courts located in Delaware, without regard to principles of conflict of laws. You may not export the Materials in violation of applicable export laws. \ No newline at end of file diff --git a/Projects/Asteroids/src/DDSTextureLoader.cpp b/Projects/Asteroids/src/DDSTextureLoader.cpp new file mode 100644 index 0000000..97e1064 --- /dev/null +++ b/Projects/Asteroids/src/DDSTextureLoader.cpp @@ -0,0 +1,1103 @@ +//-------------------------------------------------------------------------------------- +// File: DDSTextureLoader.cpp +// +// Functions for loading a DDS texture without using D3DX +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +//#include "DXUT.h" +#include "DDSTextureLoader.h" +#include // For D3DFMT stuff + +#include +#include +using std::max; +using std::min; + +#define SAFE_DELETE_ARRAY(a) if(a) { delete[] a; a=nullptr; } +#define SAFE_RELEASE(a) if(a) { a->Release(); a=nullptr; } + + +// From DXUT +//-------------------------------------------------------------------------------------- +// Helper functions to create SRGB formats from typeless formats and vice versa +//-------------------------------------------------------------------------------------- +DXGI_FORMAT MAKE_SRGB( _In_ DXGI_FORMAT format ) +{ + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_UNORM_SRGB; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_UNORM_SRGB; + + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + return DXGI_FORMAT_BC7_UNORM_SRGB; + }; + + return format; +} + + +//-------------------------------------------------------------------------------------- +HRESULT LoadTextureDataFromFile( __in_z const WCHAR* szFileName, BYTE** ppHeapData, + DDS_HEADER** ppHeader, + BYTE** ppBitData, UINT* pBitSize ) +{ + // open the file + HANDLE hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, NULL ); + if( INVALID_HANDLE_VALUE == hFile ) + return HRESULT_FROM_WIN32( GetLastError() ); + + // Get the file size + LARGE_INTEGER FileSize = {0}; + GetFileSizeEx( hFile, &FileSize ); + + // File is too big for 32-bit allocation, so reject read + if( FileSize.HighPart > 0 ) + { + CloseHandle( hFile ); + return E_FAIL; + } + + // Need at least enough data to fill the header and magic number to be a valid DDS + if( FileSize.LowPart < (sizeof(DDS_HEADER)+sizeof(DWORD)) ) + { + CloseHandle( hFile ); + return E_FAIL; + } + + // create enough space for the file data + *ppHeapData = new BYTE[ FileSize.LowPart ]; + if( !( *ppHeapData ) ) + { + CloseHandle( hFile ); + return E_OUTOFMEMORY; + } + + // read the data in + DWORD BytesRead = 0; + if( !ReadFile( hFile, *ppHeapData, FileSize.LowPart, &BytesRead, NULL ) ) + { + CloseHandle( hFile ); + SAFE_DELETE_ARRAY( *ppHeapData ); + return HRESULT_FROM_WIN32( GetLastError() ); + } + + if( BytesRead < FileSize.LowPart ) + { + CloseHandle( hFile ); + SAFE_DELETE_ARRAY( *ppHeapData ); + return E_FAIL; + } + + // DDS files always start with the same magic number ("DDS ") + DWORD dwMagicNumber = *( DWORD* )( *ppHeapData ); + if( dwMagicNumber != DDS_MAGIC ) + { + CloseHandle( hFile ); + SAFE_DELETE_ARRAY( *ppHeapData ); + return E_FAIL; + } + + DDS_HEADER* pHeader = reinterpret_cast( *ppHeapData + sizeof( DWORD ) ); + + // Verify header to validate DDS file + if( pHeader->dwSize != sizeof(DDS_HEADER) + || pHeader->ddspf.dwSize != sizeof(DDS_PIXELFORMAT) ) + { + CloseHandle( hFile ); + SAFE_DELETE_ARRAY( *ppHeapData ); + return E_FAIL; + } + + // Check for DX10 extension + bool bDXT10Header = false; + if ( (pHeader->ddspf.dwFlags & DDS_FOURCC) + && (MAKEFOURCC( 'D', 'X', '1', '0' ) == pHeader->ddspf.dwFourCC) ) + { + // Must be long enough for both headers and magic value + if( FileSize.LowPart < (sizeof(DDS_HEADER)+sizeof(DWORD)+sizeof(DDS_HEADER_DXT10)) ) + { + CloseHandle( hFile ); + SAFE_DELETE_ARRAY( *ppHeapData ); + return E_FAIL; + } + + bDXT10Header = true; + } + + // setup the pointers in the process request + *ppHeader = pHeader; + INT offset = sizeof( DWORD ) + sizeof( DDS_HEADER ) + + (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0); + *ppBitData = *ppHeapData + offset; + *pBitSize = FileSize.LowPart - offset; + + CloseHandle( hFile ); + + return S_OK; +} + + +static UINT BitsPerPixel( DXGI_FORMAT fmt ) +{ + switch( fmt ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 128; + + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 96; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return 64; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return 32; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + return 16; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return 8; + + case DXGI_FORMAT_R1_UNORM: + return 1; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 4; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 8; + + default: + return 0; + } +} + + +static void GetSurfaceInfo( UINT width, UINT height, DXGI_FORMAT fmt, UINT* pNumBytes, UINT* pRowBytes, UINT* pNumRows ) +{ + UINT numBytes = 0; + UINT rowBytes = 0; + UINT numRows = 0; + + bool bc = false; + bool packed = false; + UINT bcnumBytesPerBlock = 0; + switch (fmt) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + bc=true; + bcnumBytesPerBlock = 8; + break; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + bc = true; + bcnumBytesPerBlock = 16; + break; + + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + packed = true; + break; + } + + if( bc ) + { + int numBlocksWide = 0; + if( width > 0 ) + numBlocksWide = max( 1U, (width + 3) / 4 ); + int numBlocksHigh = 0; + if( height > 0 ) + numBlocksHigh = max( 1U, (height + 3) / 4 ); + rowBytes = numBlocksWide * bcnumBytesPerBlock; + numRows = numBlocksHigh; + } + else if ( packed ) + { + rowBytes = ( ( width + 1 ) >> 1 ) * 4; + numRows = height; + } + else + { + UINT bpp = BitsPerPixel( fmt ); + rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte + numRows = height; + } + + numBytes = rowBytes * numRows; + if( pNumBytes != NULL ) + *pNumBytes = numBytes; + if( pRowBytes != NULL ) + *pRowBytes = rowBytes; + if( pNumRows != NULL ) + *pNumRows = numRows; +} + + +//-------------------------------------------------------------------------------------- +#define ISBITMASK( r,g,b,a ) ( ddpf.dwRBitMask == r && ddpf.dwGBitMask == g && ddpf.dwBBitMask == b && ddpf.dwABitMask == a ) + +//-------------------------------------------------------------------------------------- +static D3DFORMAT GetD3D9Format( const DDS_PIXELFORMAT& ddpf ) +{ + if( ddpf.dwFlags & DDS_RGB ) + { + switch (ddpf.dwRGBBitCount) + { + case 32: + if( ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0xff000000) ) + return D3DFMT_A8R8G8B8; + if( ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0x00000000) ) + return D3DFMT_X8R8G8B8; + if( ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0xff000000) ) + return D3DFMT_A8B8G8R8; + if( ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0x00000000) ) + return D3DFMT_X8B8G8R8; + + // Note that many common DDS reader/writers (including D3DX) swap the + // the RED/BLUE masks for 10:10:10:2 formats. We assumme + // below that the 'incorrect' header mask is being used + + // For 'correct' writers this should be 0x3ff00000,0x000ffc00,0x000003ff for BGR data + if( ISBITMASK(0x000003ff,0x000ffc00,0x3ff00000,0xc0000000) ) + return D3DFMT_A2R10G10B10; + + // For 'correct' writers this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data + if( ISBITMASK(0x3ff00000,0x000ffc00,0x000003ff,0xc0000000) ) + return D3DFMT_A2B10G10R10; + + if( ISBITMASK(0x0000ffff,0xffff0000,0x00000000,0x00000000) ) + return D3DFMT_G16R16; + if( ISBITMASK(0xffffffff,0x00000000,0x00000000,0x00000000) ) + return D3DFMT_R32F; // D3DX writes this out as a FourCC of 114 + break; + + case 24: + if( ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0x00000000) ) + return D3DFMT_R8G8B8; + break; + + case 16: + if( ISBITMASK(0x0000f800,0x000007e0,0x0000001f,0x00000000) ) + return D3DFMT_R5G6B5; + if( ISBITMASK(0x00007c00,0x000003e0,0x0000001f,0x00008000) ) + return D3DFMT_A1R5G5B5; + if( ISBITMASK(0x00007c00,0x000003e0,0x0000001f,0x00000000) ) + return D3DFMT_X1R5G5B5; + if( ISBITMASK(0x00000f00,0x000000f0,0x0000000f,0x0000f000) ) + return D3DFMT_A4R4G4B4; + if( ISBITMASK(0x00000f00,0x000000f0,0x0000000f,0x00000000) ) + return D3DFMT_X4R4G4B4; + + // 3:3:2, 3:3:2:8, and paletted texture formats are typically not supported on modern video cards + break; + } + } + else if( ddpf.dwFlags & DDS_LUMINANCE ) + { + if( 8 == ddpf.dwRGBBitCount ) + { + if( ISBITMASK(0x0000000f,0x00000000,0x00000000,0x000000f0) ) + return D3DFMT_A4L4; + if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x00000000) ) + return D3DFMT_L8; + } + + if( 16 == ddpf.dwRGBBitCount ) + { + if( ISBITMASK(0x0000ffff,0x00000000,0x00000000,0x00000000) ) + return D3DFMT_L16; + if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x0000ff00) ) + return D3DFMT_A8L8; + } + } + else if( ddpf.dwFlags & DDS_ALPHA ) + { + if( 8 == ddpf.dwRGBBitCount ) + { + return D3DFMT_A8; + } + } + else if( ddpf.dwFlags & DDS_FOURCC ) + { + if( MAKEFOURCC( 'D', 'X', 'T', '1' ) == ddpf.dwFourCC ) + return D3DFMT_DXT1; + if( MAKEFOURCC( 'D', 'X', 'T', '2' ) == ddpf.dwFourCC ) + return D3DFMT_DXT2; + if( MAKEFOURCC( 'D', 'X', 'T', '3' ) == ddpf.dwFourCC ) + return D3DFMT_DXT3; + if( MAKEFOURCC( 'D', 'X', 'T', '4' ) == ddpf.dwFourCC ) + return D3DFMT_DXT4; + if( MAKEFOURCC( 'D', 'X', 'T', '5' ) == ddpf.dwFourCC ) + return D3DFMT_DXT5; + + if( MAKEFOURCC( 'R', 'G', 'B', 'G' ) == ddpf.dwFourCC ) + return D3DFMT_R8G8_B8G8; + if( MAKEFOURCC( 'G', 'R', 'G', 'B' ) == ddpf.dwFourCC ) + return D3DFMT_G8R8_G8B8; + + if( MAKEFOURCC( 'U', 'Y', 'V', 'Y' ) == ddpf.dwFourCC ) + return D3DFMT_UYVY; + if( MAKEFOURCC( 'Y', 'U', 'Y', '2' ) == ddpf.dwFourCC ) + return D3DFMT_YUY2; + + // Check for D3DFORMAT enums being set here + switch( ddpf.dwFourCC ) + { + case D3DFMT_A16B16G16R16: + case D3DFMT_Q16W16V16U16: + case D3DFMT_R16F: + case D3DFMT_G16R16F: + case D3DFMT_A16B16G16R16F: + case D3DFMT_R32F: + case D3DFMT_G32R32F: + case D3DFMT_A32B32G32R32F: + case D3DFMT_CxV8U8: + return (D3DFORMAT)ddpf.dwFourCC; + } + } + + return D3DFMT_UNKNOWN; +} + +//-------------------------------------------------------------------------------------- +DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf ) +{ + if( ddpf.dwFlags & DDS_RGB ) + { + switch (ddpf.dwRGBBitCount) + { + case 32: + // DXGI_FORMAT_B8G8R8A8_UNORM_SRGB & DXGI_FORMAT_B8G8R8X8_UNORM_SRGB should be + // written using the DX10 extended header instead since these formats require + // DXGI 1.1 + // + // This code will use the fallback to swizzle BGR to RGB in memory for standard + // DDS files which works on 10 and 10.1 devices with WDDM 1.0 drivers + // + // NOTE: We don't use DXGI_FORMAT_B8G8R8X8_UNORM or DXGI_FORMAT_B8G8R8X8_UNORM + // here because they were defined for DXGI 1.0 but were not required for D3D10/10.1 + + if( ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0xff000000) ) + return DXGI_FORMAT_R8G8B8A8_UNORM; + + // No D3DFMT_X8B8G8R8 in DXGI. We'll deal with it in a swizzle case to ensure + // alpha channel is 255 (don't care formats could contain garbage) + + // Note that many common DDS reader/writers (including D3DX) swap the + // the RED/BLUE masks for 10:10:10:2 formats. We assumme + // below that the 'backwards' header mask is being used since it is most + // likely written by D3DX. The more robust solution is to use the 'DX10' + // header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly + + // For 'correct' writers, this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data + if( ISBITMASK(0x3ff00000,0x000ffc00,0x000003ff,0xc0000000) ) + return DXGI_FORMAT_R10G10B10A2_UNORM; + + if( ISBITMASK(0x0000ffff,0xffff0000,0x00000000,0x00000000) ) + return DXGI_FORMAT_R16G16_UNORM; + + if( ISBITMASK(0xffffffff,0x00000000,0x00000000,0x00000000) ) + // Only 32-bit color channel format in D3D9 was R32F + return DXGI_FORMAT_R32_FLOAT; // D3DX writes this out as a FourCC of 114 + break; + + case 24: + // No 24bpp DXGI formats + break; + + case 16: + // 5:5:5 & 5:6:5 formats are defined for DXGI, but are deprecated for D3D10, 10.0, and 11 + + // No 4bpp, 3:3:2, 3:3:2:8, or paletted DXGI formats + break; + } + } + else if( ddpf.dwFlags & DDS_LUMINANCE ) + { + if( 8 == ddpf.dwRGBBitCount ) + { + if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x00000000) ) + return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension + + // No 4bpp DXGI formats + } + + if( 16 == ddpf.dwRGBBitCount ) + { + if( ISBITMASK(0x0000ffff,0x00000000,0x00000000,0x00000000) ) + return DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension + if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x0000ff00) ) + return DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension + } + } + else if( ddpf.dwFlags & DDS_ALPHA ) + { + if( 8 == ddpf.dwRGBBitCount ) + { + return DXGI_FORMAT_A8_UNORM; + } + } + else if( ddpf.dwFlags & DDS_FOURCC ) + { + if( MAKEFOURCC( 'D', 'X', 'T', '1' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC1_UNORM; + if( MAKEFOURCC( 'D', 'X', 'T', '3' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC2_UNORM; + if( MAKEFOURCC( 'D', 'X', 'T', '5' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC3_UNORM; + + // While pre-mulitplied alpha isn't directly supported by the DXGI formats, + // they are basically the same as these BC formats so they can be mapped + if( MAKEFOURCC( 'D', 'X', 'T', '2' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC2_UNORM; + if( MAKEFOURCC( 'D', 'X', 'T', '4' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC3_UNORM; + + if( MAKEFOURCC( 'A', 'T', 'I', '1' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC4_UNORM; + if( MAKEFOURCC( 'B', 'C', '4', 'U' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC4_UNORM; + if( MAKEFOURCC( 'B', 'C', '4', 'S' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC4_SNORM; + + if( MAKEFOURCC( 'A', 'T', 'I', '2' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC5_UNORM; + if( MAKEFOURCC( 'B', 'C', '5', 'U' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC5_UNORM; + if( MAKEFOURCC( 'B', 'C', '5', 'S' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_BC5_SNORM; + + if( MAKEFOURCC( 'R', 'G', 'B', 'G' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_R8G8_B8G8_UNORM; + if( MAKEFOURCC( 'G', 'R', 'G', 'B' ) == ddpf.dwFourCC ) + return DXGI_FORMAT_G8R8_G8B8_UNORM; + + // Check for D3DFORMAT enums being set here + switch( ddpf.dwFourCC ) + { + case D3DFMT_A16B16G16R16: // 36 + return DXGI_FORMAT_R16G16B16A16_UNORM; + + case D3DFMT_Q16W16V16U16: // 110 + return DXGI_FORMAT_R16G16B16A16_SNORM; + + case D3DFMT_R16F: // 111 + return DXGI_FORMAT_R16_FLOAT; + + case D3DFMT_G16R16F: // 112 + return DXGI_FORMAT_R16G16_FLOAT; + + case D3DFMT_A16B16G16R16F: // 113 + return DXGI_FORMAT_R16G16B16A16_FLOAT; + + case D3DFMT_R32F: // 114 + return DXGI_FORMAT_R32_FLOAT; + + case D3DFMT_G32R32F: // 115 + return DXGI_FORMAT_R32G32_FLOAT; + + case D3DFMT_A32B32G32R32F: // 116 + return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + } + + return DXGI_FORMAT_UNKNOWN; +} + + +//-------------------------------------------------------------------------------------- +static HRESULT CreateTextureFromDDS( ID3D11Device* pDev, DDS_HEADER* pHeader, __inout_bcount(BitSize) BYTE* pBitData, + UINT BitSize, __out ID3D11ShaderResourceView** ppSRV, bool bSRGB ) +{ + HRESULT hr = S_OK; + + UINT iWidth = pHeader->dwWidth; + UINT iHeight = pHeader->dwHeight; + UINT iDepth = pHeader->dwDepth; + + UINT resDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + UINT arraySize = 1; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + bool isCubeMap = false; + + UINT iMipCount = pHeader->dwMipMapCount; + if( 0 == iMipCount ) + iMipCount = 1; + + bool swaprgb = false; + bool seta = false; + + if ((pHeader->ddspf.dwFlags & DDS_FOURCC) + && (MAKEFOURCC( 'D', 'X', '1', '0' ) == pHeader->ddspf.dwFourCC ) ) + { + DDS_HEADER_DXT10* d3d10ext = (DDS_HEADER_DXT10*)( (char*)pHeader + sizeof(DDS_HEADER) ); + + arraySize = d3d10ext->arraySize; + if ( arraySize == 0 ) + return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + + if ( BitsPerPixel( d3d10ext->dxgiFormat ) == 0 ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + + format = d3d10ext->dxgiFormat; + + switch ( d3d10ext->resourceDimension ) + { + case DDS_DIMENSION_TEXTURE1D: + // D3DX writes 1D textures with a fixed Height of 1 + if ( (pHeader->dwFlags & DDS_HEIGHT) && iHeight != 1 ) + return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + iHeight = iDepth = 1; + break; + + case DDS_DIMENSION_TEXTURE2D: + if ( d3d10ext->miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE ) + { + arraySize *= 6; + isCubeMap = true; + } + iDepth = 1; + break; + + case DDS_DIMENSION_TEXTURE3D: + if ( !(pHeader->dwFlags & DDS_HEADER_FLAGS_VOLUME) ) + return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + + if ( arraySize > 1 ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + break; + + default: + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + + resDim = d3d10ext->resourceDimension; + } + else + { + format = GetDXGIFormat( pHeader->ddspf ); + + if ( pHeader->dwFlags & DDS_HEADER_FLAGS_VOLUME ) + { + resDim = DDS_DIMENSION_TEXTURE3D; + } + else + { + if ( pHeader->dwCaps2 & DDS_CUBEMAP ) + { + // We require all six faces to be defined + if ( (pHeader->dwCaps2 & DDS_CUBEMAP_ALLFACES ) != DDS_CUBEMAP_ALLFACES ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + + arraySize = 6; + isCubeMap = true; + } + + iDepth = 1; + resDim = DDS_DIMENSION_TEXTURE2D; + + // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture + } + + if ( format == DXGI_FORMAT_UNKNOWN ) + { + D3DFORMAT fmt = GetD3D9Format( pHeader->ddspf ); + + switch( fmt ) + { + case D3DFMT_X8R8G8B8: + format = DXGI_FORMAT_B8G8R8A8_UNORM; // NOTE: DXGI1.1 requirement is fine here + seta = true; + break; + + case D3DFMT_A8R8G8B8: + format = DXGI_FORMAT_B8G8R8A8_UNORM; // NOTE: DXGI1.1 requirement is fine here + break; + + case D3DFMT_X8B8G8R8: + format = DXGI_FORMAT_R8G8B8A8_UNORM; + seta = true; + break; + + case D3DFMT_A2R10G10B10: + format = DXGI_FORMAT_R10G10B10A2_UNORM; + swaprgb = TRUE; + break; + + // Would need temp memory to expand other formats (24bpp, 4bpp, 16-bit (5:6:5, 5:5:5, 5:5:5:1), 3:3:2, 3:3:2:8) + + default: + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + } + + assert( BitsPerPixel( format ) != 0 ); + } + + // Bound sizes + if ( iMipCount > D3D11_REQ_MIP_LEVELS ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + + switch ( resDim ) + { + case DDS_DIMENSION_TEXTURE1D: + if ( (arraySize > D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) + || (iWidth > D3D11_REQ_TEXTURE1D_U_DIMENSION) ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + break; + + case DDS_DIMENSION_TEXTURE2D: + if ( isCubeMap ) + { + // This is the right bound because we set arraySize to (NumCubes*6) above + if ( (arraySize > D3D11_REQ_TEXTURECUBE_DIMENSION) + || (iWidth > D3D11_REQ_TEXTURECUBE_DIMENSION) + || (iHeight > D3D11_REQ_TEXTURECUBE_DIMENSION)) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + else if ( (arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) + || (iWidth > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) + || (iHeight > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION)) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + break; + + case DDS_DIMENSION_TEXTURE3D: + if ( (arraySize > 1) + || (iWidth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) + || (iHeight > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) + || (iDepth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + break; + } + + + if ( bSRGB ) + format = MAKE_SRGB( format ); + + // Create the texture + D3D11_SUBRESOURCE_DATA* pInitData = new D3D11_SUBRESOURCE_DATA[ iMipCount * arraySize ]; + if( !pInitData ) + return E_OUTOFMEMORY; + + UINT NumBytes = 0; + UINT RowBytes = 0; + UINT NumRows = 0; + BYTE* pSrcBits = pBitData; + const BYTE *pEndBits = pBitData + BitSize; + + UINT index = 0; + for( UINT j = 0; j < arraySize; j++ ) + { + UINT w = iWidth; + UINT h = iHeight; + UINT d = iDepth; + for( UINT i = 0; i < iMipCount; i++ ) + { + GetSurfaceInfo( w, h, format, &NumBytes, &RowBytes, &NumRows ); + + pInitData[index].pSysMem = ( void* )pSrcBits; + pInitData[index].SysMemPitch = RowBytes; + pInitData[index].SysMemSlicePitch = NumBytes; + ++index; + + if ( pSrcBits + (NumBytes*d) > pEndBits ) + { + SAFE_DELETE_ARRAY( pInitData ); + return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); + } + + if ( swaprgb || seta ) + { + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + BYTE *sptr = pSrcBits; + for ( UINT slice = 0; slice < d; ++slice ) + { + BYTE *rptr = sptr; + for ( UINT row = 0; row < NumRows; ++row ) + { + BYTE *ptr = rptr; + for( UINT x = 0; x < w; ++x, ptr += 4 ) + { + if ( ptr + 4 <= pEndBits ) + { + if ( swaprgb ) + { + BYTE a = ptr[0]; + ptr[0] = ptr[2]; + ptr[2] = a; + } + if ( seta ) + ptr[3] = 255; + } + } + rptr += RowBytes; + } + sptr += NumBytes; + } + } + break; + + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + BYTE *sptr = pSrcBits; + for ( UINT slice = 0; slice < d; ++slice ) + { + const BYTE *rptr = sptr; + for ( UINT row = 0; row < NumRows; ++row ) + { + DWORD *ptr = (DWORD*)rptr; + for( UINT x = 0; x < w; ++x, ++ptr ) + { + if ( ptr + 1 <= (DWORD*)pEndBits ) + { + DWORD t = *ptr; + DWORD u = (t & 0x3ff00000) >> 20; + DWORD v = (t & 0x000003ff) << 20; + *ptr = ( t & ~0x3ff003ff ) | u | v; + } + } + rptr += RowBytes; + } + sptr += NumBytes; + } + } + break; + } + } + + pSrcBits += NumBytes * d; + + w = w >> 1; + h = h >> 1; + d = d >> 1; + if( w == 0 ) + w = 1; + if( h == 0 ) + h = 1; + if( d == 0 ) + d = 1; + } + } + + switch ( resDim ) + { + case DDS_DIMENSION_TEXTURE1D: + { + D3D11_TEXTURE1D_DESC desc; + desc.Width = iWidth; + desc.MipLevels = iMipCount; + desc.ArraySize = arraySize; + desc.Format = format; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ID3D11Texture1D* pTex = NULL; + hr = pDev->CreateTexture1D( &desc, pInitData, &pTex ); + if( SUCCEEDED( hr ) && pTex ) + { +#if defined(DEBUG) || defined(PROFILE) + pTex->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof("DDSTextureLoader")-1, "DDSTextureLoader" ); +#endif + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = format; + + if ( arraySize > 1 ) + { + SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1DARRAY; + SRVDesc.Texture1DArray.MipLevels = desc.MipLevels; + SRVDesc.Texture1DArray.ArraySize = arraySize; + } + else + { + SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D; + SRVDesc.Texture1D.MipLevels = desc.MipLevels; + } + + hr = pDev->CreateShaderResourceView( pTex, &SRVDesc, ppSRV ); + SAFE_RELEASE( pTex ); + } + } + break; + + case DDS_DIMENSION_TEXTURE2D: + { + D3D11_TEXTURE2D_DESC desc; + desc.Width = iWidth; + desc.Height = iHeight; + desc.MipLevels = iMipCount; + desc.ArraySize = arraySize; + desc.Format = format; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = (isCubeMap) ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0; + + ID3D11Texture2D* pTex = NULL; + hr = pDev->CreateTexture2D( &desc, pInitData, &pTex ); + if( SUCCEEDED( hr ) && pTex ) + { +#if defined(DEBUG) || defined(PROFILE) + pTex->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof("DDSTextureLoader")-1, "DDSTextureLoader" ); +#endif + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = format; + + if ( isCubeMap ) + { + if ( arraySize > 6 ) + { + SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBEARRAY; + SRVDesc.TextureCubeArray.MipLevels = desc.MipLevels; + + // Earlier we set arraySize to (NumCubes * 6) + SRVDesc.TextureCubeArray.NumCubes = arraySize / 6; + } + else + { + SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBE; + SRVDesc.TextureCube.MipLevels = desc.MipLevels; + } + } + else if ( arraySize > 1 ) + { + SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY; + SRVDesc.Texture2DArray.MipLevels = desc.MipLevels; + SRVDesc.Texture2DArray.ArraySize = arraySize; + } + else + { + SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Texture2D.MipLevels = desc.MipLevels; + } + + hr = pDev->CreateShaderResourceView( pTex, &SRVDesc, ppSRV ); + SAFE_RELEASE( pTex ); + } + } + break; + + case DDS_DIMENSION_TEXTURE3D: + { + D3D11_TEXTURE3D_DESC desc; + desc.Width = iWidth; + desc.Height = iHeight; + desc.Depth = iDepth; + desc.MipLevels = iMipCount; + desc.Format = format; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + ID3D11Texture3D* pTex = NULL; + hr = pDev->CreateTexture3D( &desc, pInitData, &pTex ); + if( SUCCEEDED( hr ) && pTex ) + { +#if defined(DEBUG) || defined(PROFILE) + pTex->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof("DDSTextureLoader")-1, "DDSTextureLoader" ); +#endif + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = format; + SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE3D; + SRVDesc.Texture3D.MipLevels = desc.MipLevels; + + hr = pDev->CreateShaderResourceView( pTex, &SRVDesc, ppSRV ); + SAFE_RELEASE( pTex ); + } + } + break; + } + + SAFE_DELETE_ARRAY( pInitData ); + + return hr; +} + + +//-------------------------------------------------------------------------------------- +HRESULT CreateDDSTextureFromFile( __in ID3D11Device* pDev, __in_z const WCHAR* szFileName, __out_opt ID3D11ShaderResourceView** ppSRV, bool sRGB ) +{ + if ( !pDev || !szFileName || !ppSRV ) + return E_INVALIDARG; + + BYTE* pHeapData = NULL; + DDS_HEADER* pHeader = NULL; + BYTE* pBitData = NULL; + UINT BitSize = 0; + + HRESULT hr = LoadTextureDataFromFile( szFileName, &pHeapData, &pHeader, &pBitData, &BitSize ); + if(FAILED(hr)) + { + SAFE_DELETE_ARRAY( pHeapData ); + return hr; + } + + hr = CreateTextureFromDDS( pDev, pHeader, pBitData, BitSize, ppSRV, sRGB ); + SAFE_DELETE_ARRAY( pHeapData ); + +#if defined(DEBUG) || defined(PROFILE) + if ( *ppSRV ) + { + CHAR strFileA[MAX_PATH]; + WideCharToMultiByte( CP_ACP, 0, szFileName, -1, strFileA, MAX_PATH, NULL, FALSE ); + CHAR* pstrName = strrchr( strFileA, '\\' ); + if( pstrName == NULL ) + pstrName = strFileA; + else + pstrName++; + + (*ppSRV)->SetPrivateData( WKPDID_D3DDebugObjectName, lstrlenA(pstrName), pstrName ); + } +#endif + + return hr; +} diff --git a/Projects/Asteroids/src/DDSTextureLoader.h b/Projects/Asteroids/src/DDSTextureLoader.h new file mode 100644 index 0000000..5bca4c6 --- /dev/null +++ b/Projects/Asteroids/src/DDSTextureLoader.h @@ -0,0 +1,18 @@ +//-------------------------------------------------------------------------------------- +// File: DDSTextureLoader.h +// +// Functions for loading a DDS texture without using D3DX +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "DDS.h" +#include + +HRESULT CreateDDSTextureFromFile( __in ID3D11Device* pDev, __in_z const WCHAR* szFileName, __out_opt ID3D11ShaderResourceView** ppSRV, bool sRGB = false ); + +// INTEL: Exposed this from the internals so we can load the data into D3D12, etc. +DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf ); +HRESULT LoadTextureDataFromFile(__in_z const WCHAR* szFileName, BYTE** ppHeapData, + DDS_HEADER** ppHeader, + BYTE** ppBitData, UINT* pBitSize); diff --git a/Projects/Asteroids/src/WinWrapper.cpp b/Projects/Asteroids/src/WinWrapper.cpp new file mode 100644 index 0000000..ffb0f6d --- /dev/null +++ b/Projects/Asteroids/src/WinWrapper.cpp @@ -0,0 +1,616 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include // must be after windows.h +#include +#include +#include +#include +#include +#include + +#include "asteroids_d3d11.h" +#include "asteroids_d3d12.h" +#include "asteroids_DE.h" +#include "camera.h" +#include "gui.h" + +using namespace DirectX; + +namespace { + +// Global demo state +Settings gSettings; +OrbitCamera gCamera; + +IDXGIFactory2* gDXGIFactory = nullptr; + +AsteroidsD3D11::Asteroids* gWorkloadD3D11 = nullptr; +AsteroidsD3D12::Asteroids* gWorkloadD3D12 = nullptr; +AsteroidsDE::Asteroids* gWorkloadDE = nullptr; +bool gd3d11Available = false; +bool gd3d12Available = false; +Settings::RenderMode gLastFrameRenderMode = static_cast(-1); + +GUI gGUI; +GUIText* gFPSControl; + +enum +{ + basicStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE, + windowedStyle = basicStyle | WS_OVERLAPPEDWINDOW, + fullscreenStyle = basicStyle +}; + +bool CheckDll(char const* dllName) +{ + auto hModule = LoadLibrary(dllName); + if (hModule == NULL) { + return false; + } + FreeLibrary(hModule); + return true; +} + + +UINT SetupDPI() +{ + // Just do system DPI awareness for now for simplicity... scale the 3D content + SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE); + + UINT dpiX = 0, dpiY; + POINT pt = {1, 1}; + auto hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) { + return dpiX; + } else { + return 96; // default + } +} + + +void ResetCameraView() +{ + auto center = XMVectorSet(0.0f, -0.4f*SIM_DISC_RADIUS, 0.0f, 0.0f); + auto radius = SIM_ORBIT_RADIUS + SIM_DISC_RADIUS + 10.f; + auto minRadius = SIM_ORBIT_RADIUS - 3.0f * SIM_DISC_RADIUS; + auto maxRadius = SIM_ORBIT_RADIUS + 3.0f * SIM_DISC_RADIUS; + auto longAngle = 4.50f; + auto latAngle = 1.45f; + gCamera.View(center, radius, minRadius, maxRadius, longAngle, latAngle); +} + +void ToggleFullscreen(HWND hWnd) +{ + static WINDOWPLACEMENT prevPlacement = { sizeof(prevPlacement) }; + DWORD dwStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_STYLE); + if ((dwStyle & windowedStyle) == windowedStyle) + { + MONITORINFO mi = { sizeof(mi) }; + if (GetWindowPlacement(hWnd, &prevPlacement) && + GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), &mi)) + { + SetWindowLong(hWnd, GWL_STYLE, fullscreenStyle); + SetWindowPos(hWnd, HWND_TOP, + mi.rcMonitor.left, mi.rcMonitor.top, + mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top, + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } + } else { + SetWindowLong(hWnd, GWL_STYLE, windowedStyle); + SetWindowPlacement(hWnd, &prevPlacement); + SetWindowPos(hWnd, NULL, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } +} + + +} // namespace + + + +LRESULT CALLBACK WindowProc( + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + switch (message) { + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + case WM_SIZE: { + UINT ww = LOWORD(lParam); + UINT wh = HIWORD(lParam); + + // Ignore resizing to minimized + if (ww == 0 || wh == 0) return 0; + + gSettings.windowWidth = (int)ww; + gSettings.windowHeight = (int)wh; + gSettings.renderWidth = (UINT)(double(gSettings.windowWidth) * gSettings.renderScale); + gSettings.renderHeight = (UINT)(double(gSettings.windowHeight) * gSettings.renderScale); + + // Update camera projection + float aspect = (float)gSettings.renderWidth / (float)gSettings.renderHeight; + gCamera.Projection(XM_PIDIV2 * 0.8f * 3 / 2, aspect); + + // Resize currently active swap chain + switch (gSettings.mode) + { + case Settings::RenderMode::NativeD3D11: + if(gWorkloadD3D11) + gWorkloadD3D11->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight); + break; + + case Settings::RenderMode::NativeD3D12: + if(gWorkloadD3D12) + gWorkloadD3D12->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight); + break; + + case Settings::RenderMode::DiligentD3D11: + case Settings::RenderMode::DiligentD3D12: + case Settings::RenderMode::DiligentGL: + if(gWorkloadDE) + gWorkloadDE->ResizeSwapChain(hWnd, gSettings.renderWidth, gSettings.renderHeight); + break; + } + + return 0; + } + + case WM_KEYDOWN: + if (lParam & (1 << 30)) { + // Ignore repeats + return 0; + } + switch (wParam) { + case VK_SPACE: + gSettings.animate = !gSettings.animate; + std::cout << "Animate: " << gSettings.animate << std::endl; + return 0; + + /* Disabled for demo setup */ + case 'V': + gSettings.vsync = !gSettings.vsync; + std::cout << "Vsync: " << gSettings.vsync << std::endl; + return 0; + case 'M': + gSettings.multithreadedRendering = !gSettings.multithreadedRendering; + std::cout << "Multithreaded Rendering: " << gSettings.multithreadedRendering << std::endl; + return 0; + case 'I': + gSettings.executeIndirect = !gSettings.executeIndirect; + std::cout << "ExecuteIndirect Rendering: " << gSettings.executeIndirect << std::endl; + return 0; + case 'S': + gSettings.submitRendering = !gSettings.submitRendering; + std::cout << "Submit Rendering: " << gSettings.submitRendering << std::endl; + return 0; + + case VK_ADD: + case VK_OEM_PLUS: + gSettings.numThreads = std::min(gSettings.numThreads+1, 16); + gLastFrameRenderMode = static_cast(-1); + return 0; + case VK_SUBTRACT: + case VK_OEM_MINUS: + gSettings.numThreads = std::max(gSettings.numThreads-1, 2); + gLastFrameRenderMode = static_cast(-1); + return 0; + + case '1': gSettings.mode = gd3d11Available ? Settings::RenderMode::NativeD3D11 : gSettings.mode; return 0; + case '2': gSettings.mode = gd3d12Available ? Settings::RenderMode::NativeD3D12 : gSettings.mode; return 0; + case '3': gSettings.mode = gd3d11Available ? Settings::RenderMode::DiligentD3D11 : gSettings.mode; return 0; + case '4': gSettings.mode = gd3d12Available ? Settings::RenderMode::DiligentD3D12 : gSettings.mode; return 0; + case '5': gSettings.mode = Settings::RenderMode::DiligentGL; return 0; + + case VK_ESCAPE: + SendMessage(hWnd, WM_CLOSE, 0, 0); + return 0; + } // Switch on key code + return 0; + + case WM_SYSKEYDOWN: + if (lParam & (1 << 30)) { + // Ignore repeats + return 0; + } + switch (wParam) { + case VK_RETURN: + ToggleFullscreen(hWnd); + break; + } + return 0; + + case WM_MOUSEWHEEL: { + auto delta = GET_WHEEL_DELTA_WPARAM(wParam); + gCamera.ZoomRadius(-0.07f * delta); + return 0; + } + + case WM_POINTERDOWN: + case WM_POINTERUPDATE: + case WM_POINTERUP: { + auto pointerId = GET_POINTERID_WPARAM(wParam); + POINTER_INFO pointerInfo; + if (GetPointerInfo(pointerId, &pointerInfo)) { + if (message == WM_POINTERDOWN) { + // Compute pointer position in render units + POINT p = pointerInfo.ptPixelLocation; + ScreenToClient(hWnd, &p); + RECT clientRect; + GetClientRect(hWnd, &clientRect); + p.x = p.x * gSettings.renderWidth / (clientRect.right - clientRect.left); + p.y = p.y * gSettings.renderHeight / (clientRect.bottom - clientRect.top); + + auto guiControl = gGUI.HitTest(p.x, p.y); + if (guiControl == gFPSControl) { + gSettings.lockFrameRate = !gSettings.lockFrameRate; + } else { // Camera manipulation + gCamera.AddPointer(pointerId); + } + } + + // Otherwise send it to the camera controls + gCamera.ProcessPointerFrames(pointerId, &pointerInfo); + if (message == WM_POINTERUP) gCamera.RemovePointer(pointerId); + } + return 0; + } + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } +} + +int InitWorkload(HWND hWnd, AsteroidsSimulation &asteroids) +{ + delete gWorkloadD3D11; + gWorkloadD3D11 = nullptr; + delete gWorkloadD3D12; + gWorkloadD3D12 = nullptr; + delete gWorkloadDE; + gWorkloadDE = nullptr; + switch (gSettings.mode) + { + case Settings::RenderMode::NativeD3D11: + if (gd3d11Available) { + gWorkloadD3D11 = new AsteroidsD3D11::Asteroids(&asteroids, &gGUI, gSettings.warp); + } + + gWorkloadD3D11->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight); + break; + + case Settings::RenderMode::NativeD3D12: + if (gd3d12Available) { + // If requested, enumerate the warp adapter + // TODO: Allow picking from multiple hardware adapters + IDXGIAdapter1* adapter = nullptr; + + if (gSettings.warp) { + IDXGIFactory4* DXGIFactory4 = nullptr; + if (FAILED(gDXGIFactory->QueryInterface(&DXGIFactory4))) { + fprintf(stderr, "error: WARP requires IDXGIFactory4 interface which is not present on this system!\n"); + return -1; + } + + auto hr = DXGIFactory4->EnumWarpAdapter(IID_PPV_ARGS(&adapter)); + DXGIFactory4->Release(); + + if (FAILED(hr)) { + fprintf(stderr, "error: WARP adapter not present on this system!\n"); + return -1; + } + } + + gWorkloadD3D12 = new AsteroidsD3D12::Asteroids(&asteroids, &gGUI, gSettings.numThreads, adapter); + } + + gWorkloadD3D12->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight); + break; + + case Settings::RenderMode::DiligentD3D11: + gWorkloadDE = new AsteroidsDE::Asteroids(gSettings.numThreads, &asteroids, &gGUI, hWnd, Diligent::DeviceType::D3D11); + break; + + case Settings::RenderMode::DiligentD3D12: + gWorkloadDE = new AsteroidsDE::Asteroids(gSettings.numThreads, &asteroids, &gGUI, hWnd, Diligent::DeviceType::D3D12); + break; + + case Settings::RenderMode::DiligentGL: + gWorkloadDE = new AsteroidsDE::Asteroids(gSettings.numThreads, &asteroids, &gGUI, hWnd, Diligent::DeviceType::OpenGL); + break; + } + + return 0; +} + +int main(int argc, char** argv) +{ +#if defined(_DEBUG) || defined(DEBUG) + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); +#endif + + gd3d11Available = CheckDll("d3d11.dll"); + gd3d12Available = CheckDll("d3d12.dll"); + + // Must be done before any windowing-system-like things or else virtualization will kick in + auto dpi = SetupDPI(); + // By default render at the lower resolution and scale up based on system settings + gSettings.renderScale = 96.0 / double(dpi); + + // Scale default window size based on dpi + gSettings.windowWidth *= dpi / 96; + gSettings.windowHeight *= dpi / 96; + + for (int a = 1; a < argc; ++a) { + if (_stricmp(argv[a], "-close_after") == 0 && a + 1 < argc) { + gSettings.closeAfterSeconds = atof(argv[++a]); + } else if (_stricmp(argv[a], "-nod3d11") == 0) { + gd3d11Available = false; + } else if (_stricmp(argv[a], "-warp") == 0) { + gSettings.warp = true; + } else if (_stricmp(argv[a], "-nod3d12") == 0) { + gd3d12Available = false; + } else if (_stricmp(argv[a], "-indirect") == 0) { + gSettings.executeIndirect = true; + } else if (_stricmp(argv[a], "-fullscreen") == 0) { + gSettings.windowed = false; + } else if (_stricmp(argv[a], "-window") == 0 && a + 2 < argc) { + gSettings.windowWidth = atoi(argv[++a]); + gSettings.windowHeight = atoi(argv[++a]); + } else if (_stricmp(argv[a], "-render_scale") == 0 && a + 1 < argc) { + gSettings.renderScale = atof(argv[++a]); + } else if (_stricmp(argv[a], "-locked_fps") == 0 && a + 1 < argc) { + gSettings.lockedFrameRate = atoi(argv[++a]); + } else if (_stricmp(argv[a], "-threads") == 0 && a + 1 < argc) { + gSettings.numThreads = atoi(argv[++a]); + } else { + fprintf(stderr, "error: unrecognized argument '%s'\n", argv[a]); + fprintf(stderr, "usage: asteroids_d3d12 [options]\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -close_after [seconds]\n"); + fprintf(stderr, " -nod3d11\n"); + fprintf(stderr, " -nod3d12\n"); + fprintf(stderr, " -fullscreen\n"); + fprintf(stderr, " -window [width] [height]\n"); + fprintf(stderr, " -render_scale [scale]\n"); + fprintf(stderr, " -locked_fps [fps]\n"); + fprintf(stderr, " -warp\n"); + return -1; + } + } + + if (gSettings.numThreads == 0) + { + gSettings.numThreads = std::max(std::thread::hardware_concurrency()-1, 2u); + } + + //if (!d3d11Available && !d3d12Available) { + // fprintf(stderr, "error: neither D3D11 nor D3D12 available.\n"); + // return -1; + //} + + // DXGI Factory + ThrowIfFailed(CreateDXGIFactory2(0, IID_PPV_ARGS(&gDXGIFactory))); + + // Setup GUI + gFPSControl = gGUI.AddText(150, 10); + + ResetCameraView(); + // Camera projection set up in WM_SIZE + + AsteroidsSimulation asteroids(1337, NUM_ASTEROIDS, NUM_UNIQUE_MESHES, MESH_MAX_SUBDIV_LEVELS, NUM_UNIQUE_TEXTURES); + + + gSettings.mode = Settings::RenderMode::DiligentD3D12; + + + // init window class + WNDCLASSEX windowClass; + ZeroMemory(&windowClass, sizeof(WNDCLASSEX)); + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = GetModuleHandle(NULL); + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.lpszClassName = "AsteroidsD3D12WindowClass"; + RegisterClassEx(&windowClass); + + RECT windowRect = { 0, 0, gSettings.windowWidth, gSettings.windowHeight }; + AdjustWindowRect(&windowRect, windowedStyle, FALSE); + + // create the window and store a handle to it + auto hWnd = CreateWindowEx( + WS_EX_APPWINDOW, + "AsteroidsD3D12WindowClass", + "Asteroids", + windowedStyle, + 0, // CW_USE_DEFAULT + 0, // CW_USE_DEFAULT + windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, + NULL, + NULL, + windowClass.hInstance, + NULL); + + if (!gSettings.windowed) { + ToggleFullscreen(hWnd); + } + + SetForegroundWindow(hWnd); + + // Initialize performance counters + UINT64 perfCounterFreq = 0; + UINT64 lastPerfCount = 0; + QueryPerformanceFrequency((LARGE_INTEGER*)&perfCounterFreq); + QueryPerformanceCounter((LARGE_INTEGER*)&lastPerfCount); + + // main loop + double elapsedTime = 0.0; + double frameTime = 0.0; + int lastMouseX = 0; + int lastMouseY = 0; + POINTER_INFO pointerInfo = {}; + + timeBeginPeriod(1); + EnableMouseInPointer(TRUE); + + float filteredUpdateTime = 0.0f; + float filteredRenderTime = 0.0f; + float filteredFrameTime = 0.0f; + for (;;) + { + MSG msg = {}; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) { + // Cleanup + delete gWorkloadD3D11; + delete gWorkloadD3D12; + delete gWorkloadDE; + SafeRelease(&gDXGIFactory); + timeEndPeriod(1); + EnableMouseInPointer(FALSE); + return (int)msg.wParam; + }; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + // If we swap to a new API we need to recreate swap chains + if (gLastFrameRenderMode != gSettings.mode) { + InitWorkload(hWnd, asteroids); + gLastFrameRenderMode = gSettings.mode; + } + + // Still need to process inertia even when no interaction is happening + gCamera.ProcessInertia(); + + // In D3D12 we'll wait on the GPU before taking the timestamp (more consistent) + if (gSettings.mode == Settings::RenderMode::NativeD3D12) { + gWorkloadD3D12->WaitForReadyToRender(); + } + + // Get time delta + UINT64 count; + QueryPerformanceCounter((LARGE_INTEGER*)&count); + auto rawFrameTime = (double)(count - lastPerfCount) / perfCounterFreq; + elapsedTime += rawFrameTime; + lastPerfCount = count; + + // Maintaining absolute time sync is not important in this demo so we can err on the "smoother" side + double alpha = 0.2f; + frameTime = alpha * rawFrameTime + (1.0f - alpha) * frameTime; + + // Update GUI + { + const char *ModeStr = nullptr; + float updateTime = 0; + float renderTime = 0; + switch (gSettings.mode) + { + case Settings::RenderMode::NativeD3D11: + ModeStr = "Native D3D11"; + gWorkloadD3D11->GetPerfCounters(updateTime, renderTime); + break; + + case Settings::RenderMode::NativeD3D12: + ModeStr = "Native D3D12"; + gWorkloadD3D12->GetPerfCounters(updateTime, renderTime); + break; + + case Settings::RenderMode::DiligentD3D11: + ModeStr = "Diligent D3D11"; + gWorkloadDE->GetPerfCounters(updateTime, renderTime); + break; + + case Settings::RenderMode::DiligentD3D12: + ModeStr = "Diligent D3D12"; + gWorkloadDE->GetPerfCounters(updateTime, renderTime); + break; + + case Settings::RenderMode::DiligentGL: + ModeStr = "Diligent GL"; + gWorkloadDE->GetPerfCounters(updateTime, renderTime); + break; + } + float filterScale = 0.05f; + filteredUpdateTime = filteredUpdateTime * (1.f - filterScale) + filterScale * updateTime; + filteredRenderTime = filteredRenderTime * (1.f - filterScale) + filterScale * renderTime; + filteredFrameTime = filteredFrameTime * (1.f - filterScale) + filterScale * (float)frameTime; + + char buffer[256]; + sprintf(buffer, "Asteroids %s (%dt) - %4.2f ms (%4.2f ms / %4.2f ms)", ModeStr, gSettings.multithreadedRendering ? gSettings.numThreads : 1, + 1000.f * filteredFrameTime, 1000.f * filteredUpdateTime, 1000.f * filteredRenderTime); + + SetWindowText(hWnd, buffer); + + if (gSettings.lockFrameRate) { + sprintf(buffer, "(Locked)"); + } else { + sprintf(buffer, "%.0f fps", 1.0f / filteredFrameTime); + } + gFPSControl->Text(buffer); + } + + switch (gSettings.mode) + { + case Settings::RenderMode::NativeD3D11: + if(gWorkloadD3D11) + gWorkloadD3D11->Render((float)frameTime, gCamera, gSettings); + break; + + case Settings::RenderMode::NativeD3D12: + if(gWorkloadD3D12) + gWorkloadD3D12->Render((float)frameTime, gCamera, gSettings); + break; + + case Settings::RenderMode::DiligentD3D11: + case Settings::RenderMode::DiligentD3D12: + case Settings::RenderMode::DiligentGL: + if(gWorkloadDE) + gWorkloadDE->Render((float)frameTime, gCamera, gSettings); + break; + } + + if (gSettings.lockFrameRate) { + + UINT64 afterRenderCount; + QueryPerformanceCounter((LARGE_INTEGER*)&afterRenderCount); + double renderTime = (double)(afterRenderCount - count) / perfCounterFreq; + + double targetRenderTime = 1.0 / double(gSettings.lockedFrameRate); + double deltaMs = (targetRenderTime - renderTime) * 1000.0; + if (deltaMs > 1.0) { + Sleep((DWORD)deltaMs); + } + + } + + // All done? + if (gSettings.closeAfterSeconds > 0.0 && elapsedTime > gSettings.closeAfterSeconds) { + SendMessage(hWnd, WM_CLOSE, 0, 0); + break; + } + } + + // Shouldn't get here + return 1; +} diff --git a/Projects/Asteroids/src/asteroid_ps.hlsl b/Projects/Asteroids/src/asteroid_ps.hlsl new file mode 100644 index 0000000..c645486 --- /dev/null +++ b/Projects/Asteroids/src/asteroid_ps.hlsl @@ -0,0 +1,50 @@ +#include "asteroid_vs.hlsl" +#include "common_defines.h" + +// Apparently tools don't like unbounded/bindless texture arrays, so use the real constant for now +Texture2DArray Tex[NUM_UNIQUE_TEXTURES] : register(t0); +sampler Sampler : register(s0); + +float4 asteroid_ps(in float4 position : SV_Position, + in VSOut vs_output) : SV_Target +{ + // Tweaking + float3 lightPos = float3(0.5, -0.25, -1); + bool applyNoise = true; + bool applyLight = true; + bool applyCoverage = true; + + float3 normal = normalize(vs_output.normalWorld); + + // Triplanar projection + float3 blendWeights = abs(normalize(vs_output.positionModel)); + float3 uvw = vs_output.positionModel * 0.5f + 0.5f; + // Tighten up the blending zone + blendWeights = saturate((blendWeights - 0.2f) * 7.0f); + blendWeights /= (blendWeights.x + blendWeights.y + blendWeights.z).xxx; + + float3 coords1 = float3(uvw.yz, 0); + float3 coords2 = float3(uvw.zx, 1); + float3 coords3 = float3(uvw.xy, 2); + + // TODO: Should really branch out zero'd weight ones, but FXC is being a pain + // and forward substituting the above and then refusing to compile "divergent" + // coordinates... + float3 detailTex = 0.0f; + detailTex += blendWeights.x * Tex[mTextureIndex].Sample(Sampler, coords1).xyz; + detailTex += blendWeights.y * Tex[mTextureIndex].Sample(Sampler, coords2).xyz; + detailTex += blendWeights.z * Tex[mTextureIndex].Sample(Sampler, coords3).xyz; + + float wrap = 0.0f; + float wrap_diffuse = saturate((dot(normal, normalize(lightPos)) + wrap) / (1.0f + wrap)); + float light = 3.0f * wrap_diffuse + 0.06f; + + // Approximate partial coverage on distant asteroids (by fading them out) + float coverage = saturate(position.z * 4000.0f); + + float3 color = vs_output.albedo; + [flatten] if (applyNoise) color = color * (2.0f * detailTex); + [flatten] if (applyLight) color = color * light; + [flatten] if (applyCoverage) color = color * coverage; + return float4(color, 1.0f); +} diff --git a/Projects/Asteroids/src/asteroid_ps_d3d11.hlsl b/Projects/Asteroids/src/asteroid_ps_d3d11.hlsl new file mode 100644 index 0000000..69ebc33 --- /dev/null +++ b/Projects/Asteroids/src/asteroid_ps_d3d11.hlsl @@ -0,0 +1,56 @@ +#include "common_defines.h" + +struct VSOut +{ + float3 positionModel : POSITIONMODEL; + float3 normalWorld : NORMAL; + float3 albedo : ALBEDO; // Alternatively, can pass just "ao" to PS and read cbuffer in PS +}; + +Texture2DArray Tex;// : register(t0); +SamplerState Tex_sampler;// : register(s0); + +void asteroid_ps_d3d11(in float4 position : SV_Position, + in VSOut vs_output, + out float4 color : SV_Target) +{ + // Tweaking + float3 lightPos = float3(0.5, -0.25, -1); + bool applyNoise = true; + bool applyLight = true; + bool applyCoverage = true; + + float3 normal = normalize(vs_output.normalWorld); + + // Triplanar projection + float3 blendWeights = abs(normalize(vs_output.positionModel)); + float3 uvw = vs_output.positionModel * 0.5f + 0.5f; + // Tighten up the blending zone + blendWeights = saturate((blendWeights - 0.2f) * 7.0f); + blendWeights /= (blendWeights.x + blendWeights.y + blendWeights.z).xxx; + + float3 coords1 = float3(uvw.yz, 0); + float3 coords2 = float3(uvw.zx, 1); + float3 coords3 = float3(uvw.xy, 2); + + // TODO: Should really branch out zero'd weight ones, but FXC is being a pain + // and forward substituting the above and then refusing to compile "divergent" + // coordinates... + float3 detailTex = float3(0.0, 0.0, 0.0); + detailTex += blendWeights.x * Tex.Sample(Tex_sampler, coords1).xyz; + detailTex += blendWeights.y * Tex.Sample(Tex_sampler, coords2).xyz; + detailTex += blendWeights.z * Tex.Sample(Tex_sampler, coords3).xyz; + + float wrap = 0.0f; + float wrap_diffuse = saturate((dot(normal, normalize(lightPos)) + wrap) / (1.0f + wrap)); + float light = 3.0f * wrap_diffuse + 0.06f; + + // Approximate partial coverage on distant asteroids (by fading them out) + float coverage = saturate(position.z * 4000.0f); + + color.rgb = vs_output.albedo.rgb; + [flatten] if (applyNoise) color.rgb = color.rgb * (2.0f * detailTex); + [flatten] if (applyLight) color.rgb = color.rgb * light; + [flatten] if (applyCoverage) color.rgb = color.rgb * coverage; + color.a = 1.0; +} diff --git a/Projects/Asteroids/src/asteroid_vs.hlsl b/Projects/Asteroids/src/asteroid_vs.hlsl new file mode 100644 index 0000000..772137c --- /dev/null +++ b/Projects/Asteroids/src/asteroid_vs.hlsl @@ -0,0 +1,36 @@ +cbuffer DrawConstantBuffer// : register(b0) +{ + float4x4 mWorld; + float4x4 mViewProjection; + float4 mSurfaceColor; + float4 mDeepColor; + uint mTextureIndex; +}; + +struct VSOut +{ + float3 positionModel : POSITIONMODEL; + float3 normalWorld : NORMAL; + float3 albedo : ALBEDO; // Alternatively, can pass just "ao" to PS and read cbuffer in PS +}; + +float linstep(float min, float max, float s) +{ + return saturate((s - min) / (max - min)); +} + + +void asteroid_vs(in float3 in_pos : ATTRIB0, + in float3 in_normal : ATTRIB1, + out float4 position : SV_Position, + out VSOut vs_output) +{ + float3 positionWorld = mul(mWorld, float4(in_pos, 1.0f)).xyz; + position = mul(mViewProjection, float4(positionWorld, 1.0f)); + + vs_output.positionModel = in_pos; + vs_output.normalWorld = mul(mWorld, float4(in_normal, 0.0f)).xyz; // No non-uniform scaling + + float depth = linstep(0.5f, 0.7f, length(in_pos.xyz)); + vs_output.albedo = lerp(mDeepColor.xyz, mSurfaceColor.xyz, depth); +} diff --git a/Projects/Asteroids/src/asteroids_DE.cpp b/Projects/Asteroids/src/asteroids_DE.cpp new file mode 100644 index 0000000..0cb3ddf --- /dev/null +++ b/Projects/Asteroids/src/asteroids_DE.cpp @@ -0,0 +1,870 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "asteroids_DE.h" +#include "RenderDeviceFactoryD3D11.h" +#include "RenderDeviceFactoryD3D12.h" +#include "RenderDeviceFactoryOpenGL.h" +#include "BasicShaderSourceStreamFactory.h" +#include "MapHelper.h" + +#include "util.h" +#include "mesh.h" +#include "noise.h" +#include "texture.h" +#include "StringTools.h" +#include "TextureUtilities.h" + +using namespace Diligent; + +namespace Diligent +{ +#ifdef ENGINE_DLL + CreateDeviceAndContextsD3D11Type CreateDeviceAndContextsD3D11 = nullptr; + CreateSwapChainD3D11Type CreateSwapChainD3D11 = nullptr; + + CreateDeviceAndContextsD3D12Type CreateDeviceAndContextsD3D12 = nullptr; + CreateSwapChainD3D12Type CreateSwapChainD3D12 = nullptr; + + CreateDeviceAndSwapChainGLType CreateDeviceAndSwapChainGL = nullptr; +#endif +} + +namespace AsteroidsDE { + + +// Create Direct3D device and swap chain +void Asteroids::InitDevice(HWND hWnd, DeviceType DevType) +{ + EngineCreationAttribs EngineCreationAttribs; + EngineCreationAttribs.strShaderCachePath = "bin\\tmp\\ShaderCache"; + SwapChainDesc SwapChainDesc; + SwapChainDesc.SamplesCount = 1; + SwapChainDesc.BufferCount = NUM_SWAP_CHAIN_BUFFERS; + SwapChainDesc.ColorBufferFormat = TEX_FORMAT_RGBA8_UNORM_SRGB; + SwapChainDesc.DepthBufferFormat = TEX_FORMAT_D32_FLOAT; + SwapChainDesc.DefaultDepthValue = 0.f; + switch (DevType) + { + case DeviceType::D3D12: + case DeviceType::D3D11: + { + std::vector ppContexts(mNumSubsets); + if(DevType == DeviceType::D3D11) + { + EngineD3D11Attribs DeviceAttribs; + DeviceAttribs.DebugFlags = (Uint32)EngineD3D11DebugFlags::VerifyCommittedShaderResources | + (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance; + +#ifdef ENGINE_DLL + if(!CreateDeviceAndContextsD3D11 || !CreateSwapChainD3D11) + LoadGraphicsEngineD3D11(CreateDeviceAndContextsD3D11, CreateSwapChainD3D11); +#endif + CreateDeviceAndContextsD3D11( DeviceAttribs, &mDevice, ppContexts.data(), mNumSubsets-1 ); + CreateSwapChainD3D11( mDevice, ppContexts[0], SwapChainDesc, hWnd, &mSwapChain ); + } + else + { + EngineD3D12Attribs Attribs; + Attribs.GPUDescriptorHeapDynamicSize[0] = 65536*4; + Attribs.GPUDescriptorHeapSize[0] = 65536*4; +#ifndef _DEBUG + Attribs.DynamicDescriptorAllocationChunkSize[0] = 4*2048; +#endif +#ifdef ENGINE_DLL + if(!CreateDeviceAndContextsD3D12 || !CreateSwapChainD3D12) + LoadGraphicsEngineD3D12(CreateDeviceAndContextsD3D12, CreateSwapChainD3D12); +#endif + CreateDeviceAndContextsD3D12( Attribs, &mDevice, ppContexts.data(), mNumSubsets-1 ); + CreateSwapChainD3D12( mDevice, ppContexts[0], SwapChainDesc, hWnd, &mSwapChain ); + } + + mDeviceCtxt.Attach(ppContexts[0]); + mDeferredCtxt.resize(mNumSubsets-1); + for(size_t ctx=0; ctx < mNumSubsets-1; ++ctx) + mDeferredCtxt[ctx].Attach(ppContexts[1+ctx]); + } + break; + + case DeviceType::OpenGL: +#ifdef ENGINE_DLL + if(!CreateDeviceAndSwapChainGL) + LoadGraphicsEngineOpenGL(CreateDeviceAndSwapChainGL); +#endif + CreateDeviceAndSwapChainGL( + EngineCreationAttribs, &mDevice, &mDeviceCtxt, SwapChainDesc, hWnd, &mSwapChain ); + break; + + default: + LOG_ERROR_AND_THROW("Unknown device type"); + break; + } +} + +Asteroids::Asteroids(UINT NumThreads, AsteroidsSimulation* asteroids, GUI* gui, HWND hWnd, Diligent::DeviceType DevType) + : mAsteroids(asteroids) + , mGUI(gui) +{ + QueryPerformanceFrequency((LARGE_INTEGER*)&mPerfCounterFreq); + + mNumSubsets = std::max(NumThreads,1u); + mNumSubsets = std::min(NumThreads,32u); + + InitDevice(hWnd, DevType); + + mCmdLists.resize(mDeferredCtxt.size()); + mWorkerThreads.resize(mNumSubsets-1); + for(auto &thread : mWorkerThreads) + { + thread = std::thread(WorkerThreadFunc, this, (Uint32)(&thread-mWorkerThreads.data()) ); + } + + const char *spriteFile = nullptr; + switch(DevType) + { + case DeviceType::D3D11: spriteFile = "DiligentD3D11.dds"; break; + case DeviceType::D3D12: spriteFile = "DiligentD3D12.dds"; break; + case DeviceType::OpenGL: spriteFile = "DiligentGL.dds"; break; + } + mSprite.reset( new GUISprite(5, 10, 140, 50, spriteFile) ); + + BasicShaderSourceStreamFactory BasicSSSFactory({"src"}); + + mBackBufferWidth = mSwapChain->GetDesc().Width; + mBackBufferHeight = mSwapChain->GetDesc().Height; + // Create draw constant buffer + { + BufferDesc desc; + desc.Name = "draw constant buffer (dynamic)"; + desc.Usage = USAGE_DYNAMIC; + desc.uiSizeInBytes = (Uint32) sizeof(DrawConstantBuffer); + desc.BindFlags = BIND_UNIFORM_BUFFER; + desc.CPUAccessFlags = CPU_ACCESS_WRITE; + mDevice->CreateBuffer(desc, BufferData(), &mDrawConstantBuffer); + } + + // create pipeline state + { + PipelineStateDesc PSODesc; + LayoutElement inputDesc[] = { + LayoutElement( 0, 0, 3, VT_FLOAT32), + LayoutElement( 1, 0, 3, VT_FLOAT32) + }; + + PSODesc.GraphicsPipeline.InputLayout.LayoutElements = inputDesc; + PSODesc.GraphicsPipeline.InputLayout.NumElements = _countof(inputDesc); + + PSODesc.GraphicsPipeline.DepthStencilDesc.DepthFunc = COMPARISON_FUNC_GREATER_EQUAL; + + RefCntAutoPtr vs, ps; + { + ShaderCreationAttribs attribs; + attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC; + attribs.Desc.ShaderType = SHADER_TYPE_VERTEX; + attribs.Desc.Name = "Asteroids VS"; + attribs.EntryPoint = "asteroid_vs"; + attribs.FilePath = "asteroid_vs.hlsl"; + attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + attribs.pShaderSourceStreamFactory = &BasicSSSFactory; + mDevice->CreateShader(attribs, &vs); + vs->GetShaderVariable("DrawConstantBuffer")->Set(mDrawConstantBuffer); + } + + { + ShaderCreationAttribs attribs; + attribs.Desc.DefaultVariableType = m_BindingMode == BindingMode::Dynamic ? SHADER_VARIABLE_TYPE_DYNAMIC : SHADER_VARIABLE_TYPE_MUTABLE; + attribs.Desc.ShaderType = SHADER_TYPE_PIXEL; + attribs.Desc.Name = "Asteroids PS"; + attribs.EntryPoint = "asteroid_ps_d3d11"; + attribs.FilePath = "asteroid_ps_d3d11.hlsl"; + attribs.pShaderSourceStreamFactory = &BasicSSSFactory; + attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + + StaticSamplerDesc samDesc; + samDesc.Desc.MagFilter = FILTER_TYPE_ANISOTROPIC; + samDesc.Desc.MinFilter = FILTER_TYPE_ANISOTROPIC; + samDesc.Desc.MipFilter = FILTER_TYPE_ANISOTROPIC; + samDesc.Desc.AddressU = TEXTURE_ADDRESS_WRAP; + samDesc.Desc.AddressV = TEXTURE_ADDRESS_WRAP; + samDesc.Desc.AddressW = TEXTURE_ADDRESS_WRAP; + samDesc.Desc.MinLOD = -D3D11_FLOAT32_MAX; + samDesc.Desc.MaxLOD = D3D11_FLOAT32_MAX; + samDesc.Desc.MipLODBias = 0.0f; + samDesc.Desc.MaxAnisotropy = TEXTURE_ANISO; + samDesc.Desc.ComparisonFunc = COMPARISON_FUNC_NEVER; + samDesc.TextureName = "Tex"; + attribs.Desc.StaticSamplers = &samDesc; + attribs.Desc.NumStaticSamplers = 1; + + mDevice->CreateShader(attribs, &ps); + } + PSODesc.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB; + PSODesc.GraphicsPipeline.NumRenderTargets = 1; + PSODesc.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT; + PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + PSODesc.Name = "Asteroids PSO"; + + PSODesc.GraphicsPipeline.pVS = vs; + PSODesc.GraphicsPipeline.pPS = ps; + Uint32 NumSRBs = 0; + if(m_BindingMode == BindingMode::Dynamic) + { + NumSRBs = mNumSubsets; + } + else if(m_BindingMode == BindingMode::Mutable) + { + PSODesc.SRBAllocationGranularity = 1024; + NumSRBs = NUM_ASTEROIDS; + } + else if(m_BindingMode == BindingMode::TextureMutable) + { + PSODesc.SRBAllocationGranularity = NUM_UNIQUE_TEXTURES; + NumSRBs = NUM_UNIQUE_TEXTURES; + } + mDevice->CreatePipelineState(PSODesc, &mAsteroidsPSO); + mAsteroidsSRBs.resize(NumSRBs); + for(size_t srb = 0; srb < mAsteroidsSRBs.size(); ++srb) + { + mAsteroidsPSO->CreateShaderResourceBinding(&mAsteroidsSRBs[srb]); + } + } + + + // Load textures + { + TextureLoadInfo loadInfo; + loadInfo.IsSRGB = true; + RefCntAutoPtr skybox; + CreateTextureFromFile("starbox_1024.dds", loadInfo, mDevice, &skybox); + mSkyboxSRV = skybox->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); + } + + // Create skybox constant buffer + { + BufferDesc desc; + desc.Name = "skybox constant buffer (dynamic)"; + desc.Usage = USAGE_DYNAMIC; + desc.uiSizeInBytes = sizeof(SkyboxConstantBuffer); + desc.BindFlags = BIND_UNIFORM_BUFFER; + desc.CPUAccessFlags = CPU_ACCESS_WRITE; + mDevice->CreateBuffer(desc, BufferData(), &mSkyboxConstantBuffer); + } + + // create skybox pipeline state + { + LayoutElement inputDesc[] = { + LayoutElement( 0, 0, 3, VT_FLOAT32), + LayoutElement( 1, 0, 3, VT_FLOAT32) + }; + + RefCntAutoPtr vs, ps; + ShaderCreationAttribs attribs; + attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC; + attribs.Desc.ShaderType = SHADER_TYPE_VERTEX; + attribs.Desc.Name = "Skybox VS"; + attribs.EntryPoint = "skybox_vs"; + attribs.FilePath = "skybox_vs.hlsl"; + attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + attribs.pShaderSourceStreamFactory = &BasicSSSFactory; + mDevice->CreateShader(attribs, &vs); + vs->GetShaderVariable("SkyboxConstantBuffer")->Set(mSkyboxConstantBuffer); + + attribs.Desc.Name = "Skybox PS"; + attribs.EntryPoint = "skybox_ps"; + attribs.FilePath = "skybox_ps.hlsl"; + attribs.Desc.ShaderType = SHADER_TYPE_PIXEL; + + StaticSamplerDesc ssdesc; + ssdesc.TextureName = "Skybox"; + ssdesc.Desc.MagFilter = FILTER_TYPE_ANISOTROPIC; + ssdesc.Desc.MinFilter = FILTER_TYPE_ANISOTROPIC; + ssdesc.Desc.MipFilter = FILTER_TYPE_ANISOTROPIC; + ssdesc.Desc.AddressU = TEXTURE_ADDRESS_WRAP; + ssdesc.Desc.AddressV = TEXTURE_ADDRESS_WRAP; + ssdesc.Desc.AddressW = TEXTURE_ADDRESS_WRAP; + ssdesc.Desc.MaxAnisotropy = TEXTURE_ANISO; + attribs.Desc.StaticSamplers = &ssdesc; + attribs.Desc.NumStaticSamplers = 1; + mDevice->CreateShader(attribs, &ps); + ps->GetShaderVariable("Skybox")->Set(mSkyboxSRV); + + PipelineStateDesc PSODesc; + PSODesc.Name = "Skybox PSO"; + PSODesc.GraphicsPipeline.InputLayout.LayoutElements = inputDesc; + PSODesc.GraphicsPipeline.InputLayout.NumElements = _countof(inputDesc); + + PSODesc.GraphicsPipeline.DepthStencilDesc.DepthFunc = COMPARISON_FUNC_GREATER_EQUAL; + PSODesc.GraphicsPipeline.pVS = vs; + PSODesc.GraphicsPipeline.pPS = ps; + + PSODesc.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB; + PSODesc.GraphicsPipeline.NumRenderTargets = 1; + PSODesc.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT; + PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + + mDevice->CreatePipelineState(PSODesc, &mSkyboxPSO); + } + + // Create sampler + { + SamplerDesc desc; + desc.MagFilter = FILTER_TYPE_ANISOTROPIC; + desc.MinFilter = FILTER_TYPE_ANISOTROPIC; + desc.MipFilter = FILTER_TYPE_ANISOTROPIC; + desc.AddressU = TEXTURE_ADDRESS_WRAP; + desc.AddressV = TEXTURE_ADDRESS_WRAP; + desc.AddressW = TEXTURE_ADDRESS_WRAP; + desc.MinLOD = -D3D11_FLOAT32_MAX; + desc.MaxLOD = D3D11_FLOAT32_MAX; + desc.MipLODBias = 0.0f; + desc.MaxAnisotropy = TEXTURE_ANISO; + desc.ComparisonFunc = COMPARISON_FUNC_NEVER; + mDevice->CreateSampler(desc, &mSamplerState); + } + + CreateGUIResources(); + + // Sprites and fonts + { + PipelineStateDesc PSODesc; + LayoutElement inputDesc[] = { + LayoutElement( 0, 0, 2, VT_FLOAT32), + LayoutElement( 1, 0, 2, VT_FLOAT32) + }; + PSODesc.GraphicsPipeline.InputLayout.LayoutElements = inputDesc; + PSODesc.GraphicsPipeline.InputLayout.NumElements = _countof(inputDesc); + + auto &BlendState = PSODesc.GraphicsPipeline.BlendDesc; + { + // Premultiplied over blend + BlendState.RenderTargets[0].BlendEnable = TRUE; + BlendState.RenderTargets[0].SrcBlend = BLEND_FACTOR_ONE; + BlendState.RenderTargets[0].BlendOp = BLEND_OPERATION_ADD; + BlendState.RenderTargets[0].DestBlend = BLEND_FACTOR_INV_SRC_ALPHA; + } + + PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = false; + + PSODesc.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB; + PSODesc.GraphicsPipeline.NumRenderTargets = 1; + PSODesc.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT; + PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + + RefCntAutoPtr sprite_vs, sprite_ps, font_ps; + { + ShaderCreationAttribs attribs; + attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC; + attribs.Desc.ShaderType = SHADER_TYPE_VERTEX; + attribs.Desc.Name = "Sprite VS"; + attribs.EntryPoint = "sprite_vs"; + attribs.FilePath = "sprite_vs.hlsl"; + attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + attribs.pShaderSourceStreamFactory = &BasicSSSFactory; + mDevice->CreateShader(attribs, &sprite_vs); + } + + { + ShaderCreationAttribs attribs; + attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_DYNAMIC; + attribs.Desc.ShaderType = SHADER_TYPE_PIXEL; + attribs.Desc.Name = "Sprite PS"; + attribs.EntryPoint = "sprite_ps"; + attribs.FilePath = "sprite_ps.hlsl"; + attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + attribs.pShaderSourceStreamFactory = &BasicSSSFactory; + mDevice->CreateShader(attribs, &sprite_ps); + } + + { + ShaderCreationAttribs attribs; + attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC; + attribs.Desc.ShaderType = SHADER_TYPE_PIXEL; + attribs.Desc.Name = "Font PS"; + attribs.EntryPoint = "font_ps"; + attribs.FilePath = "font_ps.hlsl"; + attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + attribs.pShaderSourceStreamFactory = &BasicSSSFactory; + mDevice->CreateShader(attribs, &font_ps); + font_ps->GetShaderVariable("Tex")->Set(mFontTextureSRV); + } + + PSODesc.Name = "Sprite PSO"; + PSODesc.GraphicsPipeline.pVS = sprite_vs; + PSODesc.GraphicsPipeline.pPS = sprite_ps; + mDevice->CreatePipelineState(PSODesc, &mSpritePSO); + mSpritePSO->CreateShaderResourceBinding(&mSpriteSRB); + + PSODesc.Name = "Font PSO"; + PSODesc.GraphicsPipeline.pPS = font_ps; + mDevice->CreatePipelineState(PSODesc, &mFontPSO); + } + + + CreateMeshes(); + InitializeTextureData(); + if( m_BindingMode == BindingMode::Mutable ) + { + for(size_t srb = 0; srb < NUM_ASTEROIDS; ++srb) + { + auto staticData = &mAsteroids->StaticData()[srb]; + mAsteroidsSRBs[srb]->GetVariable(SHADER_TYPE_PIXEL, "Tex")->Set(mTextureSRVs[staticData->textureIndex]); + } + } + else if( m_BindingMode == BindingMode::TextureMutable ) + { + for(size_t srb = 0; srb < NUM_UNIQUE_TEXTURES; ++srb) + { + mAsteroidsSRBs[srb]->GetVariable(SHADER_TYPE_PIXEL, "Tex")->Set(mTextureSRVs[srb]); + } + } + +} + +Asteroids::~Asteroids() +{ + { + std::unique_lock lk(mMutex); + mExitThreads = true; + } + mCondVar.notify_all(); + + for(auto &thread : mWorkerThreads) + { + thread.join(); + } +} + + + +void Asteroids::ResizeSwapChain(HWND outputWindow, unsigned int width, unsigned int height) +{ + mSwapChain->Resize(width, height); + mBackBufferWidth = width; + mBackBufferHeight = height; +} + + +void Asteroids::CreateMeshes() +{ + auto asteroidMeshes = mAsteroids->Meshes(); + + // create vertex buffer + { + BufferDesc desc; + desc.Name = "Asteroid Meshes Vertex Buffer"; + desc.uiSizeInBytes = (Uint32)asteroidMeshes->vertices.size() * sizeof(asteroidMeshes->vertices[0]); + desc.BindFlags = BIND_VERTEX_BUFFER; + desc.Usage = USAGE_DEFAULT; + + BufferData data; + data.pData = asteroidMeshes->vertices.data(); + data.DataSize = desc.uiSizeInBytes; + + mDevice->CreateBuffer(desc, data, &mVertexBuffer); + } + + // create index buffer + { + BufferDesc desc; + desc.Name = "Asteroid Meshes Index Buffer"; + desc.uiSizeInBytes = (Uint32)asteroidMeshes->indices.size() * sizeof(asteroidMeshes->indices[0]); + desc.BindFlags = BIND_INDEX_BUFFER; + desc.Usage = USAGE_DEFAULT; + + BufferData data; + data.pData = asteroidMeshes->indices.data(); + data.DataSize = desc.uiSizeInBytes; + + mDevice->CreateBuffer(desc, data, &mIndexBuffer); + } + + std::vector skyboxVertices; + CreateSkyboxMesh(&skyboxVertices); + + + // create skybox vertex buffer + { + BufferDesc desc; + desc.Name = "Skybox Vertex Buffer"; + desc.uiSizeInBytes = (Uint32)skyboxVertices.size() * sizeof(skyboxVertices[0]); + desc.BindFlags = BIND_VERTEX_BUFFER; + desc.Usage = USAGE_DEFAULT; + + BufferData data; + data.pData = skyboxVertices.data(); + data.DataSize = desc.uiSizeInBytes; + + mDevice->CreateBuffer(desc, data, &mSkyboxVertexBuffer); + } + + // create sprite vertex buffer (dynamic) + { + BufferDesc desc; + desc.Name = "sprite vertex buffer (dynamic)"; + desc.uiSizeInBytes = (Uint32)MAX_SPRITE_VERTICES_PER_FRAME * sizeof(SpriteVertex); + desc.BindFlags = BIND_VERTEX_BUFFER; + desc.Usage = USAGE_DYNAMIC; + desc.CPUAccessFlags = CPU_ACCESS_WRITE; + + mDevice->CreateBuffer(desc, BufferData(), &mSpriteVertexBuffer); + } +} + +void Asteroids::InitializeTextureData() +{ + TextureDesc textureDesc; + textureDesc.Type = RESOURCE_DIM_TEX_2D_ARRAY; + textureDesc.Width = TEXTURE_DIM; + textureDesc.Height = TEXTURE_DIM; + textureDesc.ArraySize = 3; + textureDesc.MipLevels = 0; // Full chain + textureDesc.Format = TEX_FORMAT_RGBA8_UNORM_SRGB; + textureDesc.SampleCount = 1; + textureDesc.Usage = USAGE_DEFAULT; + textureDesc.BindFlags = BIND_SHADER_RESOURCE; + + for (UINT t = 0; t < NUM_UNIQUE_TEXTURES; ++t) { + std::vector subResData(textureDesc.ArraySize*mAsteroids->GetTextureMipLevels()); + auto *texData = mAsteroids->TextureData(t); + for(size_t subRes=0; subRes < subResData.size(); ++subRes) + { + subResData[subRes].pData = texData[subRes].pSysMem; + subResData[subRes].Stride = texData[subRes].SysMemPitch; + subResData[subRes].DepthStride = texData[subRes].SysMemSlicePitch; + } + TextureData initData; + initData.NumSubresources = (Uint32)subResData.size(); + initData.pSubResources = subResData.data(); + mDevice->CreateTexture(textureDesc, initData, &mTextures[t]); + mTextureSRVs[t] = mTextures[t]->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); + mTextureSRVs[t]->SetSampler(mSamplerState); + } +} + +void Asteroids::CreateGUIResources() +{ + auto font = mGUI->Font(); + TextureDesc textureDesc; + textureDesc.Type = RESOURCE_DIM_TEX_2D; + textureDesc.Format = TEX_FORMAT_R8_UNORM; + textureDesc.Width = font->BitmapWidth(); + textureDesc.Height = font->BitmapHeight(); + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.BindFlags = BIND_SHADER_RESOURCE; + textureDesc.Usage = USAGE_DEFAULT; + + TextureData initialData; + TextureSubResData subresources[] = { + TextureSubResData((void*)font->Pixels(), font->BitmapWidth()) + }; + initialData.pSubResources = subresources; + initialData.NumSubresources = _countof(subresources); + + RefCntAutoPtr texture; + mDevice->CreateTexture(textureDesc, initialData, &texture); + mFontTextureSRV = texture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); + mFontTextureSRV->SetSampler(mSamplerState); + + // Load any GUI sprite textures + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i >= 0 ? (*mGUI)[i] : mSprite.get(); + if (control->TextureFile().length() > 0 && mSpriteTextures.find(control->TextureFile()) == mSpriteTextures.end()) { + std::wstring_convert> converter; + ID3D11ShaderResourceView* textureSRV = nullptr; + auto path = NarrowString(converter.from_bytes(control->TextureFile()).c_str()); + TextureLoadInfo loadInfo; + loadInfo.IsSRGB = true; + RefCntAutoPtr spriteTexture; + CreateTextureFromFile(path.c_str(), loadInfo, mDevice, &spriteTexture); + auto *pSRV = spriteTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); + pSRV->SetSampler(mSamplerState); + mSpriteTextures[control->TextureFile()] = pSRV; + } + } +} + +static_assert(sizeof(IndexType) == 2, "Expecting 16-bit index buffer"); + +void Asteroids::WorkerThreadFunc(Asteroids *pThis, Diligent::Uint32 ThreadNum) +{ + for (;;) + { + // Wait for mUpdateSubsets or mExitThreads flag on conditional variable + { + std::unique_lock lk(pThis->mMutex); + pThis->mCondVar.wait(lk, [&]{return pThis->mUpdateSubsets || pThis->mExitThreads;}); + } + + if(pThis->mExitThreads) + return; + + auto SubsetSize = NUM_ASTEROIDS / pThis->mNumSubsets; + auto SubsetStart = SubsetSize * (ThreadNum+1); + auto &FrameAttribs = pThis->mFrameAttribs; + + pThis->mAsteroids->Update(FrameAttribs.frameTime, FrameAttribs.camera->Eye(), *FrameAttribs.settings, SubsetStart, SubsetSize); + + // Increment number of completed threads + ++pThis->m_NumThreadsCompleted; + + // Wait for mRenderSubsets flag on conditional variable + { + std::unique_lock lk(pThis->mMutex); + pThis->mCondVar.wait(lk, [&]{return pThis->mRenderSubsets || pThis->mExitThreads;}); + } + + pThis->RenderSubset(1+ThreadNum, pThis->mDeferredCtxt[ThreadNum], *FrameAttribs.camera, SubsetStart, SubsetSize); + + RefCntAutoPtr pCmdList; + pThis->mCmdLists[ThreadNum].Release(); + pThis->mDeferredCtxt[ThreadNum]->FinishCommandList(&pThis->mCmdLists[ThreadNum]); + + // Increment number of completed threads + ++pThis->m_NumThreadsCompleted; + } + +} + +void Asteroids::RenderSubset(Diligent::Uint32 SubsetNum, + IDeviceContext *pCtx, + const OrbitCamera& camera, + Uint32 startIdx, + Uint32 numAsteroids) +{ + pCtx->SetRenderTargets(0, nullptr, nullptr); + + // Frame data + auto staticAsteroidData = mAsteroids->StaticData(); + auto dynamicAsteroidData = mAsteroids->DynamicData(); + + pCtx->SetPipelineState(mAsteroidsPSO); + + { + IBuffer* ia_buffers[] = { mVertexBuffer }; + Uint32 ia_strides[] = { sizeof(Vertex) }; + Uint32 ia_offsets[] = { 0 }; + pCtx->SetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets, 0); + pCtx->SetIndexBuffer(mIndexBuffer, 0); + } + + auto pVar = m_BindingMode == BindingMode::Dynamic ? mAsteroidsSRBs[SubsetNum]->GetVariable(SHADER_TYPE_PIXEL, "Tex") : nullptr; + auto viewProjection = camera.ViewProjection(); + for (UINT drawIdx = startIdx; drawIdx < startIdx+numAsteroids; ++drawIdx) + { + auto staticData = &staticAsteroidData[drawIdx]; + auto dynamicData = &dynamicAsteroidData[drawIdx]; + + { + MapHelper drawConstants(pCtx, mDrawConstantBuffer, MAP_WRITE_DISCARD, 0); + XMStoreFloat4x4(&drawConstants->mWorld, dynamicData->world); + XMStoreFloat4x4(&drawConstants->mViewProjection, viewProjection); + drawConstants->mSurfaceColor = staticData->surfaceColor; + drawConstants->mDeepColor = staticData->deepColor; + } + if( m_BindingMode == BindingMode::Dynamic ) + { + pVar->Set(mTextureSRVs[staticData->textureIndex]); + pCtx->CommitShaderResources(mAsteroidsSRBs[SubsetNum], COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); + } + else if( m_BindingMode == BindingMode::Mutable ) + { + pCtx->CommitShaderResources(mAsteroidsSRBs[drawIdx], COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); + } + else if( m_BindingMode == BindingMode::TextureMutable ) + { + pCtx->CommitShaderResources(mAsteroidsSRBs[staticData->textureIndex], 0); + } + + DrawAttribs attribs; + attribs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + attribs.IsIndexed = true; + attribs.NumIndices = dynamicData->indexCount; + attribs.IndexType = VT_UINT16; + attribs.FirstIndexLocation = dynamicData->indexStart; + attribs.BaseVertex = staticData->vertexStart; + pCtx->Draw(attribs); + } +} + +void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Settings& settings) +{ + mFrameAttribs.frameTime = frameTime; + mFrameAttribs.camera = &camera; + mFrameAttribs.settings = &settings; + + // Clear the render target + float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + mDeviceCtxt->SetRenderTargets(0, nullptr, nullptr); + mDeviceCtxt->ClearRenderTarget(nullptr, clearcol); + mDeviceCtxt->ClearDepthStencil(nullptr, CLEAR_DEPTH_FLAG, 0.0f, 0); + + if( m_BindingMode == BindingMode::TextureMutable ) + { + for(auto &srb=mAsteroidsSRBs.begin(); srb!=mAsteroidsSRBs.end(); ++srb) + { + mDeviceCtxt->TransitionShaderResources(mAsteroidsPSO, *srb); + } + } + + LONG64 currCounter; + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mUpdateTicks = currCounter; + + auto SubsetSize = NUM_ASTEROIDS / (settings.multithreadedRendering ? mNumSubsets : 1); + + if (settings.multithreadedRendering) + { + // Set mUpdateSubsets flag + { + std::unique_lock lk(mMutex); + mUpdateSubsets = true; + m_NumThreadsCompleted = 0; + } + mCondVar.notify_all(); + } + + mAsteroids->Update(frameTime, camera.Eye(), settings, 0, SubsetSize); + + if (settings.multithreadedRendering) + { + // Wait for worker threads to finish + while(m_NumThreadsCompleted < (int)mNumSubsets-1) + std::this_thread::yield(); + // Clear mUpdateSubsets flag while all threads are waiting for mRenderSubsets flag + mUpdateSubsets = false; + } + + + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mUpdateTicks = currCounter-mUpdateTicks; + + mRenderTicks = currCounter; + + if (settings.multithreadedRendering) + { + // Set mRenderSubsets flag + { + std::unique_lock lk(mMutex); + mRenderSubsets = true; + m_NumThreadsCompleted = 0; + } + mCondVar.notify_all(); + } + + RenderSubset(0, mDeviceCtxt, camera, 0, SubsetSize); + + if (settings.multithreadedRendering) + { + // Wait for worker threads to finish + while(m_NumThreadsCompleted < (int)mNumSubsets-1) + std::this_thread::yield(); + // Clear mRenderSubsets flag while all threads are waiting for mUpdateSubsets flag + mRenderSubsets = false; + + for(auto &cmdList : mCmdLists) + { + mDeviceCtxt->ExecuteCommandList(cmdList); + } + } + + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mRenderTicks = currCounter-mRenderTicks; + + mDeviceCtxt->SetRenderTargets(0, nullptr, nullptr); + // Draw skybox + { + { + MapHelper skyboxConstants(mDeviceCtxt, mSkyboxConstantBuffer, MAP_WRITE_DISCARD, 0); + XMStoreFloat4x4(&skyboxConstants->mViewProjection, camera.ViewProjection()); + } + + IBuffer* ia_buffers[] = { mSkyboxVertexBuffer }; + UINT ia_strides[] = { sizeof(SkyboxVertex) }; + UINT ia_offsets[] = { 0 }; + mDeviceCtxt->SetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets, 0); + + mDeviceCtxt->SetPipelineState(mSkyboxPSO); + mDeviceCtxt->CommitShaderResources(nullptr, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); + + DrawAttribs DrawAttrs; + DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + DrawAttrs.NumVertices = 6*6; + mDeviceCtxt->Draw(DrawAttrs); + } + + // Draw sprites and fonts + { + // Fill in vertices (TODO: could move this vector to be a member - not a big deal) + std::vector controlVertices; + controlVertices.reserve(mGUI->size()); + + { + MapHelper vertexBase(mDeviceCtxt, mSpriteVertexBuffer, MAP_WRITE_DISCARD, 0); + auto vertexEnd = (SpriteVertex*)vertexBase; + + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i >= 0 ? (*mGUI)[i] : mSprite.get(); + controlVertices.push_back((UINT)(control->Draw((float)mBackBufferWidth, (float)mBackBufferHeight, vertexEnd) - vertexEnd)); + vertexEnd += controlVertices.back(); + } + } + + IBuffer* ia_buffers[] = { mSpriteVertexBuffer }; + Uint32 ia_strides[] = { sizeof(SpriteVertex) }; + Uint32 ia_offsets[] = { 0 }; + mDeviceCtxt->SetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets, 0); + + // Draw + UINT vertexStart = 0; + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i >= 0 ? (*mGUI)[i] : mSprite.get(); + if (control->Visible()) { + if (control->TextureFile().length() == 0) { // Font + mDeviceCtxt->SetPipelineState(mFontPSO); + mDeviceCtxt->CommitShaderResources(nullptr, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); + } else { // Sprite + auto textureSRV = mSpriteTextures[control->TextureFile()]; + mDeviceCtxt->SetPipelineState(mSpritePSO); + mSpriteSRB->GetVariable(SHADER_TYPE_PIXEL, "Tex")->Set(textureSRV); + mDeviceCtxt->CommitShaderResources(mSpriteSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); + } + DrawAttribs DrawAttrs; + DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + DrawAttrs.NumVertices = controlVertices[1+i]; + DrawAttrs.StartVertexLocation = vertexStart; + mDeviceCtxt->Draw(DrawAttrs); + } + vertexStart += controlVertices[1+i]; + } + } + + mSwapChain->Present();//settings.vsync ? 1 : 0, 0); +} + +void Asteroids::GetPerfCounters(float &UpdateTime, float &RenderTime) +{ + UpdateTime = (float)mUpdateTicks/(float)mPerfCounterFreq; + RenderTime = (float)mRenderTicks/(float)mPerfCounterFreq; +} + +} // namespace AsteroidsDE diff --git a/Projects/Asteroids/src/asteroids_DE.h b/Projects/Asteroids/src/asteroids_DE.h new file mode 100644 index 0000000..271d511 --- /dev/null +++ b/Projects/Asteroids/src/asteroids_DE.h @@ -0,0 +1,123 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "RenderDevice.h" +#include "SwapChain.h" +#include "DeviceContext.h" +#include +#include +#include + +#include "camera.h" +#include "settings.h" +#include "simulation.h" +#include "util.h" +#include "gui.h" +#include "RefCntAutoPtr.h" + +namespace AsteroidsDE { + +struct DrawConstantBuffer { + DirectX::XMFLOAT4X4 mWorld; + DirectX::XMFLOAT4X4 mViewProjection; + DirectX::XMFLOAT3 mSurfaceColor; + float unused0; + DirectX::XMFLOAT3 mDeepColor; + float unused1; +}; + +struct SkyboxConstantBuffer { + DirectX::XMFLOAT4X4 mViewProjection; +}; + +class Asteroids { +public: + Asteroids(UINT NumThreads, AsteroidsSimulation* asteroids, GUI* gui, HWND hWnd, Diligent::DeviceType DevType); + ~Asteroids(); + + void Render(float frameTime, const OrbitCamera& camera, const Settings& settings); + + void ResizeSwapChain(HWND outputWindow, unsigned int width, unsigned int height); + + void GetPerfCounters(float &UpdateTime, float &RenderTime); + +private: + void CreateMeshes(); + void InitializeTextureData(); + void CreateGUIResources(); + void RenderSubset(Diligent::Uint32 SubsetNum, Diligent::IDeviceContext *pCtx, const OrbitCamera& camera, Diligent::Uint32 startIdx, Diligent::Uint32 numAsteroids); + void InitDevice(HWND hWnd, Diligent::DeviceType DevType); + + enum class BindingMode + { + Dynamic = 1, + Mutable = 2, + TextureMutable = 3 + }m_BindingMode = BindingMode::TextureMutable; + + AsteroidsSimulation* mAsteroids = nullptr; + GUI* mGUI = nullptr; + + Diligent::RefCntAutoPtr mSwapChain; + Diligent::RefCntAutoPtr mDevice; + Diligent::RefCntAutoPtr mDeviceCtxt; + std::vector< Diligent::RefCntAutoPtr > mDeferredCtxt; + std::vector< Diligent::RefCntAutoPtr > mCmdLists; + + Diligent::Uint32 mBackBufferWidth, mBackBufferHeight; + Diligent::Uint32 mNumSubsets = 0; + std::vector mWorkerThreads; + + std::mutex mMutex; + std::condition_variable mCondVar; + bool mUpdateSubsets = false; + bool mRenderSubsets = false; + bool mExitThreads = false; + std::atomic_int m_NumThreadsCompleted; + static void WorkerThreadFunc(Asteroids *pThis, Diligent::Uint32 ThreadNum); + + struct FrameAttribs + { + float frameTime; + const OrbitCamera* camera; + const Settings* settings; + }mFrameAttribs; + + Diligent::RefCntAutoPtr mIndexBuffer; + Diligent::RefCntAutoPtr mVertexBuffer; + Diligent::RefCntAutoPtr mDrawConstantBuffer; + Diligent::RefCntAutoPtr mSpriteVertexBuffer; + Diligent::RefCntAutoPtr mSkyboxConstantBuffer; + Diligent::RefCntAutoPtr mSkyboxVertexBuffer; + + Diligent::RefCntAutoPtr mAsteroidsPSO; + std::vector< Diligent::RefCntAutoPtr > mAsteroidsSRBs; + + Diligent::RefCntAutoPtr mFontPSO; + Diligent::RefCntAutoPtr mSpritePSO; + Diligent::RefCntAutoPtr mSpriteSRB; + + Diligent::RefCntAutoPtr mSkyboxPSO; + + std::map> mSpriteTextures; + Diligent::RefCntAutoPtr mSkyboxSRV; + Diligent::RefCntAutoPtr mFontTextureSRV; + Diligent::RefCntAutoPtr mTextures[NUM_UNIQUE_TEXTURES]; + Diligent::RefCntAutoPtr mTextureSRVs[NUM_UNIQUE_TEXTURES]; + Diligent::RefCntAutoPtr mSamplerState; + + std::unique_ptr mSprite; + UINT64 mPerfCounterFreq = 0; + volatile LONG64 mUpdateTicks = 0, mRenderTicks = 0; +}; + +} // namespace AsteroidsD3D11 diff --git a/Projects/Asteroids/src/asteroids_d3d11.cpp b/Projects/Asteroids/src/asteroids_d3d11.cpp new file mode 100644 index 0000000..85602e5 --- /dev/null +++ b/Projects/Asteroids/src/asteroids_d3d11.cpp @@ -0,0 +1,594 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "asteroids_d3d11.h" +#include "util.h" +#include "mesh.h" +#include "noise.h" +#include "texture.h" +#include "DDSTextureLoader.h" + +#include "asteroid_vs.h" +#include "asteroid_ps_d3d11.h" +#include "skybox_vs.h" +#include "skybox_ps.h" +#include "sprite_vs.h" +#include "sprite_ps.h" +#include "font_ps.h" + +using namespace DirectX; + +namespace AsteroidsD3D11 { + +Asteroids::Asteroids(AsteroidsSimulation* asteroids, GUI* gui, bool warp) + : mAsteroids(asteroids) + , mGUI(gui) + , mSwapChain(nullptr) + , mDevice(nullptr) + , mDeviceCtxt(nullptr) + , mRenderTarget(nullptr) + , mRenderTargetView(nullptr) + , mDepthStencilView(nullptr) + , mDepthStencilState(nullptr) + , mInputLayout(nullptr) + , mIndexBuffer(nullptr) + , mVertexBuffer(nullptr) + , mVertexShader(nullptr) + , mPixelShader(nullptr) + , mDrawConstantBuffer(nullptr) + , mSkyboxVertexShader(nullptr) + , mSkyboxPixelShader(nullptr) + , mSkyboxConstantBuffer(nullptr) + , mSamplerState(nullptr) + , mD3D11Sprite( new GUISprite(5, 10, 140, 50, "directx11.dds") ) +{ + QueryPerformanceFrequency((LARGE_INTEGER*)&mPerfCounterFreq); + + memset(&mViewPort, 0, sizeof(mViewPort)); + memset(&mScissorRect, 0, sizeof(mScissorRect)); + memset(mTextures, 0, sizeof(mTextures)); + memset(mTextureSRVs, 0, sizeof(mTextureSRVs)); + + // Create device and swap chain + { + IDXGIAdapter* adapter = nullptr; + D3D_DRIVER_TYPE driverType = ( warp ) ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_HARDWARE; + HMODULE swModule = NULL; + UINT flags = 0; + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 }; + UINT numFeatureLevels = ARRAYSIZE(featureLevels); + UINT sdkVersion = D3D11_SDK_VERSION; + +#ifdef _DEBUG + flags = flags | D3D11_CREATE_DEVICE_DEBUG; +#endif + + auto hr = D3D11CreateDevice(adapter, driverType, swModule, + flags, featureLevels, numFeatureLevels, sdkVersion, &mDevice, nullptr, &mDeviceCtxt); + if (FAILED(hr)) { + // Try again without the debug flag... + flags = flags & ~D3D11_CREATE_DEVICE_DEBUG; + ThrowIfFailed(D3D11CreateDevice(adapter, driverType, swModule, + flags, featureLevels, numFeatureLevels, sdkVersion, &mDevice, nullptr, &mDeviceCtxt)); + } + } + + // create pipeline state + { + D3D11_INPUT_ELEMENT_DESC inputDesc[] = { + { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc), + g_asteroid_vs, sizeof(g_asteroid_vs), &mInputLayout)); + + { + D3D11_DEPTH_STENCIL_DESC desc = CD3D11_DEPTH_STENCIL_DESC(D3D11_DEFAULT); + desc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL; + ThrowIfFailed(mDevice->CreateDepthStencilState(&desc, &mDepthStencilState)); + } + { + CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); + ThrowIfFailed(mDevice->CreateBlendState(&desc, &mBlendState)); + + // Premultiplied over blend + desc.RenderTarget[0].BlendEnable = TRUE; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + ThrowIfFailed(mDevice->CreateBlendState(&desc, &mSpriteBlendState)); + } + + ThrowIfFailed(mDevice->CreateVertexShader(g_asteroid_vs, sizeof(g_asteroid_vs), NULL, &mVertexShader)); + ThrowIfFailed(mDevice->CreatePixelShader(g_asteroid_ps_d3d11, sizeof(g_asteroid_ps_d3d11), NULL, &mPixelShader)); + } + // create skybox pipeline state + { + D3D11_INPUT_ELEMENT_DESC inputDesc[] = { + { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc), + g_skybox_vs, sizeof(g_skybox_vs), &mSkyboxInputLayout)); + + ThrowIfFailed(mDevice->CreateVertexShader(g_skybox_vs, sizeof(g_skybox_vs), NULL, &mSkyboxVertexShader)); + ThrowIfFailed(mDevice->CreatePixelShader(g_skybox_ps, sizeof(g_skybox_ps), NULL, &mSkyboxPixelShader)); + } + + // Sprites and fonts + { + D3D11_INPUT_ELEMENT_DESC inputDesc[] = { + { "ATTRIB", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "ATTRIB", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc), + g_sprite_vs, sizeof(g_sprite_vs), &mSpriteInputLayout)); + + ThrowIfFailed(mDevice->CreateVertexShader(g_sprite_vs, sizeof(g_sprite_vs), NULL, &mSpriteVertexShader)); + ThrowIfFailed(mDevice->CreatePixelShader(g_sprite_ps, sizeof(g_sprite_ps), NULL, &mSpritePixelShader)); + ThrowIfFailed(mDevice->CreatePixelShader(g_font_ps, sizeof(g_font_ps), NULL, &mFontPixelShader)); + } + + // Create draw constant buffer + { + D3D11_BUFFER_DESC desc = {}; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.ByteWidth = sizeof(DrawConstantBuffer); + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mDrawConstantBuffer)); + } + // Create skybox constant buffer + { + D3D11_BUFFER_DESC desc = {}; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.ByteWidth = sizeof(SkyboxConstantBuffer); + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mSkyboxConstantBuffer)); + } + + // Create sampler + { + D3D11_SAMPLER_DESC desc = {}; + desc.Filter = D3D11_FILTER_ANISOTROPIC; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + desc.MinLOD = -D3D11_FLOAT32_MAX; + desc.MaxLOD = D3D11_FLOAT32_MAX; + desc.MipLODBias = 0.0f; + desc.MaxAnisotropy = TEXTURE_ANISO; + desc.ComparisonFunc = D3D11_COMPARISON_NEVER; + ThrowIfFailed(mDevice->CreateSamplerState(&desc, &mSamplerState)); + } + + CreateMeshes(); + InitializeTextureData(); + CreateGUIResources(); + + // Load textures + ThrowIfFailed(CreateDDSTextureFromFile(mDevice, L"starbox_1024.dds", &mSkyboxSRV, true)); +} + +Asteroids::~Asteroids() +{ + ReleaseSwapChain(); + + SafeRelease(&mDepthStencilState); + SafeRelease(&mInputLayout); + SafeRelease(&mIndexBuffer); + SafeRelease(&mVertexBuffer); + SafeRelease(&mVertexShader); + SafeRelease(&mPixelShader); + SafeRelease(&mDrawConstantBuffer); + SafeRelease(&mSamplerState); + + SafeRelease(&mBlendState); + SafeRelease(&mSpriteBlendState); + + for (auto i : mSpriteTextures) { + i.second->Release(); + } + SafeRelease(&mSpriteInputLayout); + SafeRelease(&mSpriteVertexShader); + SafeRelease(&mSpritePixelShader); + SafeRelease(&mSpriteVertexBuffer); + + SafeRelease(&mFontPixelShader); + SafeRelease(&mFontTextureSRV); + + SafeRelease(&mSkyboxVertexShader); + SafeRelease(&mSkyboxPixelShader); + SafeRelease(&mSkyboxConstantBuffer); + SafeRelease(&mSkyboxVertexBuffer); + SafeRelease(&mSkyboxInputLayout); + SafeRelease(&mSkyboxSRV); + + for (auto& texture : mTextures) SafeRelease(&texture); + for (auto& srv : mTextureSRVs) SafeRelease(&srv); + + if (mSwapChain != nullptr) { + mSwapChain->Release(); + mSwapChain = nullptr; + } + SafeRelease(&mDeviceCtxt); + SafeRelease(&mDevice); + + delete mD3D11Sprite; +} + + +void Asteroids::ReleaseSwapChain() +{ + // Cleanup any references... + SafeRelease(&mRenderTarget); + SafeRelease(&mRenderTargetView); + SafeRelease(&mDepthStencilView); + SafeRelease(&mSwapChain); + mDeviceCtxt->ClearState(); + mDeviceCtxt->Flush(); +} + +inline void DisableDXGIWindowChanges(IUnknown* device, HWND window) +{ + IDXGIDevice * pDXGIDevice; + ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice))); + IDXGIAdapter * pDXGIAdapter; + ThrowIfFailed(pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter))); + IDXGIFactory * pIDXGIFactory; + ThrowIfFailed(pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory))); + + ThrowIfFailed(pIDXGIFactory->MakeWindowAssociation(window, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER)); + + pIDXGIFactory->Release(); + pDXGIAdapter->Release(); + pDXGIDevice->Release(); +} + +void Asteroids::ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height) +{ + ReleaseSwapChain(); + + // Create swap chain + { + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // Can create an SRGB render target view on the swap chain buffer + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = NUM_SWAP_CHAIN_BUFFERS; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used + swapChainDesc.Flags = 0; + + ThrowIfFailed(dxgiFactory->CreateSwapChainForHwnd( + mDevice, outputWindow, &swapChainDesc, nullptr, nullptr, &mSwapChain)); + // MakeWindowAssociation must be called after CreateSwapChain + DisableDXGIWindowChanges(mDevice, outputWindow); + } + + // create render target view + { + ThrowIfFailed(mSwapChain->GetBuffer(0, IID_PPV_ARGS(&mRenderTarget))); + + D3D11_RENDER_TARGET_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + desc.Texture2D.MipSlice = 0; + ThrowIfFailed(mDevice->CreateRenderTargetView(mRenderTarget, &desc, &mRenderTargetView)); + } + + // create depth stencil view + { + CD3D11_TEXTURE2D_DESC desc = CD3D11_TEXTURE2D_DESC( + DXGI_FORMAT_D32_FLOAT, width, height, 1, 1, D3D11_BIND_DEPTH_STENCIL); + + ID3D11Texture2D* depthStencil = nullptr; + ThrowIfFailed(mDevice->CreateTexture2D(&desc, nullptr, &depthStencil)); + ThrowIfFailed(mDevice->CreateDepthStencilView(depthStencil, nullptr, &mDepthStencilView)); + depthStencil->Release(); + } + + // update the viewport and scissor + ZeroMemory(&mViewPort, sizeof(D3D11_VIEWPORT)); + mViewPort.TopLeftX = 0; + mViewPort.TopLeftY = 0; + mViewPort.Width = (float)width; + mViewPort.Height = (float)height; + mViewPort.MinDepth = 0.0f; + mViewPort.MaxDepth = 1.0f; + + mScissorRect.left = 0; + mScissorRect.top = 0; + mScissorRect.right = width; + mScissorRect.bottom = height; +} + + +void Asteroids::CreateMeshes() +{ + auto asteroidMeshes = mAsteroids->Meshes(); + + // create vertex buffer + { + CD3D11_BUFFER_DESC desc( + (UINT)asteroidMeshes->vertices.size() * sizeof(asteroidMeshes->vertices[0]), + D3D11_BIND_VERTEX_BUFFER, + D3D11_USAGE_DEFAULT); + + D3D11_SUBRESOURCE_DATA data = {}; + data.pSysMem = asteroidMeshes->vertices.data(); + + ThrowIfFailed(mDevice->CreateBuffer(&desc, &data, &mVertexBuffer)); + } + + // create index buffer + { + CD3D11_BUFFER_DESC desc( + (UINT)asteroidMeshes->indices.size() * sizeof(asteroidMeshes->indices[0]), + D3D11_BIND_INDEX_BUFFER, + D3D11_USAGE_DEFAULT); + + D3D11_SUBRESOURCE_DATA data = {}; + data.pSysMem = asteroidMeshes->indices.data(); + + ThrowIfFailed(mDevice->CreateBuffer(&desc, &data, &mIndexBuffer)); + } + + std::vector skyboxVertices; + CreateSkyboxMesh(&skyboxVertices); + + // create skybox vertex buffer + { + CD3D11_BUFFER_DESC desc( + (UINT)skyboxVertices.size() * sizeof(skyboxVertices[0]), + D3D11_BIND_VERTEX_BUFFER, + D3D11_USAGE_DEFAULT); + + D3D11_SUBRESOURCE_DATA data = {}; + data.pSysMem = skyboxVertices.data(); + + ThrowIfFailed(mDevice->CreateBuffer(&desc, &data, &mSkyboxVertexBuffer)); + } + + // create sprite vertex buffer (dynamic) + { + CD3D11_BUFFER_DESC desc( + MAX_SPRITE_VERTICES_PER_FRAME * sizeof(SpriteVertex), + D3D11_BIND_VERTEX_BUFFER, + D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); + + ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mSpriteVertexBuffer)); + } +} + +void Asteroids::InitializeTextureData() +{ + D3D11_TEXTURE2D_DESC textureDesc = {}; + textureDesc.Width = TEXTURE_DIM; + textureDesc.Height = TEXTURE_DIM; + textureDesc.ArraySize = 3; + textureDesc.MipLevels = 0; // Full chain + textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + textureDesc.SampleDesc.Count = 1; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + for (UINT t = 0; t < NUM_UNIQUE_TEXTURES; ++t) { + ThrowIfFailed(mDevice->CreateTexture2D(&textureDesc, mAsteroids->TextureData(t), &mTextures[t])); + ThrowIfFailed(mDevice->CreateShaderResourceView(mTextures[t], nullptr, &mTextureSRVs[t])); + } +} + +void Asteroids::CreateGUIResources() +{ + auto font = mGUI->Font(); + D3D11_TEXTURE2D_DESC textureDesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8_UNORM, font->BitmapWidth(), font->BitmapHeight(), 1, 1); + + D3D11_SUBRESOURCE_DATA initialData = {}; + initialData.pSysMem = font->Pixels(); + initialData.SysMemPitch = font->BitmapWidth(); + + ID3D11Texture2D* texture = nullptr; + ThrowIfFailed(mDevice->CreateTexture2D(&textureDesc, &initialData, &texture)); + ThrowIfFailed(mDevice->CreateShaderResourceView(texture, nullptr, &mFontTextureSRV)); + SafeRelease(&texture); + + // Load any GUI sprite textures + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i >= 0 ? (*mGUI)[i] : mD3D11Sprite; + if (control->TextureFile().length() > 0 && mSpriteTextures.find(control->TextureFile()) == mSpriteTextures.end()) { + std::wstring_convert> converter; + ID3D11ShaderResourceView* textureSRV = nullptr; + ThrowIfFailed(CreateDDSTextureFromFile(mDevice, converter.from_bytes(control->TextureFile()).c_str(), &textureSRV, true)); + mSpriteTextures[control->TextureFile()] = textureSRV; + } + } +} + +static_assert(sizeof(IndexType) == 2, "Expecting 16-bit index buffer"); + +void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Settings& settings) +{ + LONG64 currCounter = 0; + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + + // Frame data + mAsteroids->Update(frameTime, camera.Eye(), settings); + + mTotalUpdateTicks = currCounter; + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mTotalUpdateTicks = currCounter - mTotalUpdateTicks; + + auto staticAsteroidData = mAsteroids->StaticData(); + auto dynamicAsteroidData = mAsteroids->DynamicData(); + + // Clear the render target + float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + mDeviceCtxt->ClearRenderTargetView(mRenderTargetView, clearcol); + mDeviceCtxt->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH, 0.0f, 0); + + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + { + ID3D11Buffer* ia_buffers[] = { mVertexBuffer }; + UINT ia_strides[] = { sizeof(Vertex) }; + UINT ia_offsets[] = { 0 }; + mDeviceCtxt->IASetInputLayout(mInputLayout); + mDeviceCtxt->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + mDeviceCtxt->IASetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets); + mDeviceCtxt->IASetIndexBuffer(mIndexBuffer, DXGI_FORMAT_R16_UINT, 0); + } + + mDeviceCtxt->VSSetShader(mVertexShader, nullptr, 0); + mDeviceCtxt->VSSetConstantBuffers(0, 1, &mDrawConstantBuffer); + + mDeviceCtxt->RSSetViewports(1, &mViewPort); + mDeviceCtxt->RSSetScissorRects(1, &mScissorRect); + + mDeviceCtxt->PSSetShader(mPixelShader, nullptr, 0); + mDeviceCtxt->PSSetSamplers(0, 1, &mSamplerState); + + mDeviceCtxt->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView); + mDeviceCtxt->OMSetDepthStencilState(mDepthStencilState, 0); + mDeviceCtxt->OMSetBlendState(mBlendState, nullptr, 0xFFFFFFFF); + + auto viewProjection = camera.ViewProjection(); + for (UINT drawIdx = 0; drawIdx < NUM_ASTEROIDS; ++drawIdx) + { + auto staticData = &staticAsteroidData[drawIdx]; + auto dynamicData = &dynamicAsteroidData[drawIdx]; + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + ThrowIfFailed(mDeviceCtxt->Map(mDrawConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); + + auto drawConstants = (DrawConstantBuffer*) mapped.pData; + XMStoreFloat4x4(&drawConstants->mWorld, dynamicData->world); + XMStoreFloat4x4(&drawConstants->mViewProjection, viewProjection); + drawConstants->mSurfaceColor = staticData->surfaceColor; + drawConstants->mDeepColor = staticData->deepColor; + + mDeviceCtxt->Unmap(mDrawConstantBuffer, 0); + + mDeviceCtxt->PSSetShaderResources(0, 1, &mTextureSRVs[staticData->textureIndex]); + + mDeviceCtxt->DrawIndexedInstanced(dynamicData->indexCount, 1, dynamicData->indexStart, staticData->vertexStart, 0); + } + + mTotalRenderTicks = currCounter; + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mTotalRenderTicks = currCounter - mTotalRenderTicks; + + // Draw skybox + { + D3D11_MAPPED_SUBRESOURCE mapped = {}; + ThrowIfFailed(mDeviceCtxt->Map(mSkyboxConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); + auto skyboxConstants = (SkyboxConstantBuffer*) mapped.pData; + XMStoreFloat4x4(&skyboxConstants->mViewProjection, camera.ViewProjection()); + mDeviceCtxt->Unmap(mSkyboxConstantBuffer, 0); + + ID3D11Buffer* ia_buffers[] = { mSkyboxVertexBuffer }; + UINT ia_strides[] = { sizeof(SkyboxVertex) }; + UINT ia_offsets[] = { 0 }; + mDeviceCtxt->IASetInputLayout(mSkyboxInputLayout); + mDeviceCtxt->IASetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets); + + mDeviceCtxt->VSSetShader(mSkyboxVertexShader, nullptr, 0); + mDeviceCtxt->VSSetConstantBuffers(0, 1, &mSkyboxConstantBuffer); + + mDeviceCtxt->PSSetShader(mSkyboxPixelShader, nullptr, 0); + mDeviceCtxt->PSSetSamplers(0, 1, &mSamplerState); + mDeviceCtxt->PSSetShaderResources(0, 1, &mSkyboxSRV); + + mDeviceCtxt->Draw(6*6, 0); + } + + mDeviceCtxt->OMSetRenderTargets(1, &mRenderTargetView, 0); // No more depth buffer + + // Draw sprites and fonts + { + // Fill in vertices (TODO: could move this vector to be a member - not a big deal) + std::vector controlVertices; + controlVertices.reserve(mGUI->size()); + + { + D3D11_MAPPED_SUBRESOURCE mapped = {}; + ThrowIfFailed(mDeviceCtxt->Map(mSpriteVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); + auto vertexBase = (SpriteVertex*)mapped.pData; + auto vertexEnd = vertexBase; + + + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i >= 0 ? (*mGUI)[i] : mD3D11Sprite; + controlVertices.push_back((UINT)(control->Draw(mViewPort.Width, mViewPort.Height, vertexEnd) - vertexEnd)); + vertexEnd += controlVertices.back(); + } + + mDeviceCtxt->Unmap(mSpriteVertexBuffer, 0); + } + + ID3D11Buffer* ia_buffers[] = { mSpriteVertexBuffer }; + UINT ia_strides[] = { sizeof(SpriteVertex) }; + UINT ia_offsets[] = { 0 }; + mDeviceCtxt->IASetInputLayout(mSpriteInputLayout); + mDeviceCtxt->IASetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets); + mDeviceCtxt->VSSetShader(mSpriteVertexShader, 0, 0); + mDeviceCtxt->OMSetBlendState(mSpriteBlendState, nullptr, 0xFFFFFFFF); + + // Draw + UINT vertexStart = 0; + + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i >= 0 ? (*mGUI)[i] : mD3D11Sprite; + if (control->Visible()) { + if (control->TextureFile().length() == 0) { // Font + mDeviceCtxt->PSSetShader(mFontPixelShader, 0, 0); + mDeviceCtxt->PSSetShaderResources(0, 1, &mFontTextureSRV); + } else { // Sprite + auto textureSRV = mSpriteTextures[control->TextureFile()]; + mDeviceCtxt->PSSetShader(mSpritePixelShader, 0, 0); + mDeviceCtxt->PSSetShaderResources(0, 1, &textureSRV); + } + mDeviceCtxt->Draw(controlVertices[1+i], vertexStart); + } + vertexStart += controlVertices[1+i]; + } + } + + mSwapChain->Present(settings.vsync ? 1 : 0, 0); +} + +void Asteroids::GetPerfCounters(float &UpdateTime, float &RenderTime) +{ + UpdateTime = (float)mTotalUpdateTicks/(float)mPerfCounterFreq; + RenderTime = (float)mTotalRenderTicks/(float)mPerfCounterFreq; +} + +} // namespace AsteroidsD3D11 diff --git a/Projects/Asteroids/src/asteroids_d3d11.h b/Projects/Asteroids/src/asteroids_d3d11.h new file mode 100644 index 0000000..da9548e --- /dev/null +++ b/Projects/Asteroids/src/asteroids_d3d11.h @@ -0,0 +1,108 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include +#include +#include +#include +#include + +#include "camera.h" +#include "settings.h" +#include "simulation.h" +#include "util.h" +#include "gui.h" + +namespace AsteroidsD3D11 { + +struct DrawConstantBuffer { + DirectX::XMFLOAT4X4 mWorld; + DirectX::XMFLOAT4X4 mViewProjection; + DirectX::XMFLOAT3 mSurfaceColor; + float unused0; + DirectX::XMFLOAT3 mDeepColor; + float unused1; +}; + +struct SkyboxConstantBuffer { + DirectX::XMFLOAT4X4 mViewProjection; +}; + +class Asteroids { +public: + Asteroids(AsteroidsSimulation* asteroids, GUI* gui, bool warp); + ~Asteroids(); + + void Render(float frameTime, const OrbitCamera& camera, const Settings& settings); + + void ReleaseSwapChain(); + void ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height); + + void GetPerfCounters(float &UpdateTime, float &RenderTime); + +private: + void CreateMeshes(); + void InitializeTextureData(); + void CreateGUIResources(); + + AsteroidsSimulation* mAsteroids = nullptr; + GUI* mGUI = nullptr; + + IDXGISwapChain1* mSwapChain = nullptr; + ID3D11Device* mDevice = nullptr; + ID3D11DeviceContext* mDeviceCtxt = nullptr; + + // These depend on the swap chain buffer size + ID3D11Texture2D* mRenderTarget = nullptr; + ID3D11RenderTargetView* mRenderTargetView = nullptr; + ID3D11DepthStencilView* mDepthStencilView = nullptr; + D3D11_VIEWPORT mViewPort; + D3D11_RECT mScissorRect; + + ID3D11DepthStencilState* mDepthStencilState = nullptr; + ID3D11BlendState* mBlendState = nullptr; + ID3D11BlendState* mSpriteBlendState = nullptr; + + ID3D11InputLayout* mInputLayout = nullptr; + ID3D11Buffer* mIndexBuffer = nullptr; + ID3D11Buffer* mVertexBuffer = nullptr; + ID3D11VertexShader* mVertexShader = nullptr; + ID3D11PixelShader* mPixelShader = nullptr; + ID3D11Buffer* mDrawConstantBuffer = nullptr; + + ID3D11VertexShader* mSpriteVertexShader = nullptr; + ID3D11PixelShader* mSpritePixelShader = nullptr; + ID3D11InputLayout* mSpriteInputLayout = nullptr; + ID3D11Buffer* mSpriteVertexBuffer = nullptr; + std::map mSpriteTextures; + + ID3D11PixelShader* mFontPixelShader = nullptr; + ID3D11ShaderResourceView* mFontTextureSRV = nullptr; + + ID3D11VertexShader* mSkyboxVertexShader = nullptr; + ID3D11PixelShader* mSkyboxPixelShader = nullptr; + ID3D11Buffer* mSkyboxConstantBuffer = nullptr; + ID3D11Buffer* mSkyboxVertexBuffer = nullptr; + ID3D11InputLayout* mSkyboxInputLayout = nullptr; + ID3D11ShaderResourceView* mSkyboxSRV = nullptr; + + ID3D11Texture2D* mTextures[NUM_UNIQUE_TEXTURES]; + ID3D11ShaderResourceView* mTextureSRVs[NUM_UNIQUE_TEXTURES]; + ID3D11SamplerState* mSamplerState = nullptr; + + GUISprite* mD3D11Sprite = nullptr; + + UINT64 mPerfCounterFreq = 0; + volatile LONG64 mTotalUpdateTicks = 0, mTotalRenderTicks = 0; +}; + +} // namespace AsteroidsD3D11 diff --git a/Projects/Asteroids/src/asteroids_d3d12.cpp b/Projects/Asteroids/src/asteroids_d3d12.cpp new file mode 100644 index 0000000..1d6fcdd --- /dev/null +++ b/Projects/Asteroids/src/asteroids_d3d12.cpp @@ -0,0 +1,938 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "asteroids_d3d12.h" +#include "util.h" +#include "mesh.h" +#include "noise.h" +#include "texture.h" + +#include "asteroid_vs.h" +#include "asteroid_ps.h" + +#include "skybox_vs.h" +#include "skybox_ps.h" + +#include "sprite_vs.h" +#include "sprite_ps.h" +#include "font_ps.h" + +using namespace DirectX; + +namespace AsteroidsD3D12 { + +enum RootParameters +{ + RP_DRAW_CBV, + RP_TEX_SRV, + RP_SMP, +}; + +Asteroids::Asteroids(AsteroidsSimulation* asteroids, GUI *gui, UINT minCmdLsts, IDXGIAdapter* adapter) + : mAsteroids(asteroids) + , mGUI(gui) + , mFenceEventHandle(CreateEvent(NULL, FALSE, FALSE, NULL)) + , mD3D12Sprite( new GUISprite(5, 10, 140, 50, "directx12.dds") ) +{ + QueryPerformanceFrequency((LARGE_INTEGER*)&mPerfCounterFreq); + + memset(&mViewPort, 0, sizeof(mViewPort)); + memset(&mScissorRect, 0, sizeof(mScissorRect)); + memset(mAsteroidTextures, 0, sizeof(mAsteroidTextures)); + memset(mIndexOffsets, 0xff, sizeof(mIndexOffsets)); + +#if defined(_DEBUG) + // Enable the D3D12 debug layer. + { + ID3D12Debug* debugController = nullptr; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) + { + debugController->EnableDebugLayer(); + debugController->Release(); + } + } +#endif + + // Create device + { + ThrowIfFailed(D3D12CreateDevice( + adapter, + D3D_FEATURE_LEVEL_11_0, + IID_PPV_ARGS(&mDevice))); + + D3D12_COMMAND_QUEUE_DESC QDesc; + QDesc.NodeMask = 1; + QDesc.Priority = 0; + QDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + QDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + ThrowIfFailed(mDevice->CreateCommandQueue(&QDesc, IID_PPV_ARGS(&mCommandQueue))); + + ThrowIfFailed(mDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence))); + } + + // General use descriptor heaps + mRTVDescs = new RTVDescriptorList(mDevice, NUM_SWAP_CHAIN_BUFFERS); + mDSVDescs = new DSVDescriptorList(mDevice, 1); + mSMPDescs = new SMPDescriptorList(mDevice, 1); + mSRVDescs = new SRVDescriptorList(mDevice, NUM_UNIQUE_TEXTURES); + + // Filled in in Resize - just take slots for them here + mDepthStencilView = mDSVDescs->Append(); + mRTVFormat = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + mDSVFormat = DXGI_FORMAT_D32_FLOAT; + + CreatePSOs(); + CreateMeshes(); + + // Create textures + { + // TODO: Query simulation for this data? Defines good enough for now... + D3D12_RESOURCE_DESC textureDesc = + CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, TEXTURE_DIM, TEXTURE_DIM, 3, 0); + + for (UINT i = 0; i < NUM_UNIQUE_TEXTURES; ++i) { + ThrowIfFailed(mDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &textureDesc, + D3D12_RESOURCE_STATE_COMMON, + nullptr, // Clear value + IID_PPV_ARGS(&mAsteroidTextures[i]) + )); + textureDesc = mAsteroidTextures[i]->GetDesc(); + + InitializeTexture2D(mDevice, mCommandQueue, mAsteroidTextures[i], &textureDesc, 4, mAsteroids->TextureData(i)); + + // Append a descriptor to the heap + mSRVDescs->AppendSRV(mAsteroidTextures[i]); + } + + ThrowIfFailed(CreateTexture2DFromDDS_XXXX8( + mDevice, mCommandQueue, &mSkybox, "starbox_1024.dds", DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)); + } + + CreateGUIResources(); + + // Fill in general heaps + { // Samplers + D3D12_SAMPLER_DESC sampler = {}; + sampler.Filter = D3D12_FILTER_ANISOTROPIC; + sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler.MaxAnisotropy = TEXTURE_ANISO; + sampler.MinLOD = -std::numeric_limits::max(); + sampler.MaxLOD = std::numeric_limits::max(); + mSampler = mSMPDescs->Append(&sampler); + } + + // Swap chain resources + for (UINT s = 0; s < NUM_SWAP_CHAIN_BUFFERS; s++) { + // Filled in in resize, just make a slot here + mSwapChainBuffer[s].mRenderTargetView = mRTVDescs->Append(); + } + + // Per-frame resources + for (UINT f = 0; f < NUM_FRAMES_TO_BUFFER; f++) { + auto frame = &mFrame[f]; + ThrowIfFailed(mDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frame->mCmdAlloc))); + + frame->mDynamicUpload = new UploadHeapT(mDevice); + auto dynamicUploadWO = frame->mDynamicUpload->DataWO(); + auto dynamicUploadGPUVA = frame->mDynamicUpload->Heap()->GetGPUVirtualAddress(); + + frame->mDrawConstantBuffersGPUVA = dynamicUploadGPUVA + offsetof(DynamicUploadHeap, mDrawConstantBuffers); + + // Set any static asteroid data now + auto staticData = mAsteroids->StaticData(); + for (int j = 0; j < NUM_ASTEROIDS; ++j) { + auto constants = &dynamicUploadWO->mDrawConstantBuffers[j]; + constants->mSurfaceColor = staticData[j].surfaceColor; + constants->mDeepColor = staticData[j].deepColor; + constants->mTextureIndex = staticData[j].textureIndex; + + auto indirectDraw = &dynamicUploadWO->mIndirectArgs[j]; + indirectDraw->mConstantBuffer = frame->mDrawConstantBuffersGPUVA + sizeof(DrawConstantBuffer) * j; + indirectDraw->mDrawIndexed.InstanceCount = 1; + indirectDraw->mDrawIndexed.StartInstanceLocation = 0; + indirectDraw->mDrawIndexed.BaseVertexLocation = staticData[j].vertexStart; + } + + // Dynamic sprite vertices + { + frame->mSpriteVertexBufferView.BufferLocation = dynamicUploadGPUVA + offsetof(DynamicUploadHeap, mSpriteVertices); + frame->mSpriteVertexBufferView.StrideInBytes = sizeof(SpriteVertex); + frame->mSpriteVertexBufferView.SizeInBytes = sizeof(SpriteVertex) * MAX_SPRITE_VERTICES_PER_FRAME; + } + + // General frame SRV descriptor heap + { + // We allocate a pile of extra space for dynamic descriptors (GUI, etc) + frame->mSRVDescs = new SRVDescriptorList(mDevice, 100); + + // Skybox constants + frame->mSkyboxConstants = dynamicUploadGPUVA + offsetof(DynamicUploadHeap, mSkyboxConstants); + + // Skybox texture + { + auto textureDesc = mSkybox->GetDesc(); + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Format = textureDesc.Format; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MipLevels = 1; + srvDesc.TextureCube.MostDetailedMip = 0; + srvDesc.TextureCube.ResourceMinLODClamp = 0.0f; + + frame->mSkyboxTexture = frame->mSRVDescs->AppendSRV(mSkybox, &srvDesc); + } + + // The rest of the heap we'll use for dynamically copy descriptors into, etc. + frame->mSRVDescsDynamicStart = frame->mSRVDescs->Size(); + } + } + + // Command Lists + ThrowIfFailed(mDevice->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, mFrame[0].mCmdAlloc, mAsteroidPSO, IID_PPV_ARGS(&mPostCmdLst))); + ThrowIfFailed(mPostCmdLst->Close()); // Avoid allocator issues... command lists really should be created in a "closed" state... + ThrowIfFailed(mDevice->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, mFrame[0].mCmdAlloc, mAsteroidPSO, IID_PPV_ARGS(&mPreCmdLst))); + ThrowIfFailed(mPreCmdLst->Close()); + + // Each command list for asteroid drawing maps 1:1 with a descriptor heap + // Change heaps is "free" at cmdlst boundaries and this greatly simplifies the code + // Thus the expectation is that we have ~ #threads heaps for multithreaded rendering on most GPUs + // Need at least one draw in each heap/cmd list... + minCmdLsts = std::min(minCmdLsts, (UINT)NUM_ASTEROIDS); + CreateSubsets(minCmdLsts); + std::cout << "Using " << mSubsetCount << " subsets per frame." << std::endl; + + // Just in case + WaitForAll(); +} + +Asteroids::~Asteroids() +{ + WaitForAll(); + ReleaseSwapChain(); + + SafeRelease(&mPreCmdLst); + SafeRelease(&mPostCmdLst); + + for (UINT i = 0; i < NUM_UNIQUE_TEXTURES; ++i) { + SafeRelease(&mAsteroidTextures[i]); + } + for (auto i : mSpriteTextures) { + i.second->Release(); + } + + SafeRelease(&mAsteroidPSO); + SafeRelease(&mFontTexture); + SafeRelease(&mFontPSO); + SafeRelease(&mSpritePSO); + SafeRelease(&mSkybox); + SafeRelease(&mSkyboxPSO); + + for (UINT f = 0; f < NUM_FRAMES_TO_BUFFER; ++f) { + auto frame = &mFrame[f]; + SafeRelease(&frame->mCmdAlloc); + delete frame->mDynamicUpload; + delete frame->mSRVDescs; + } + + ReleaseSubsets(); + + delete mMeshUpload; + + delete mRTVDescs; + delete mDSVDescs; + delete mSMPDescs; + delete mSRVDescs; + + SafeRelease(&mGenericRootSignature); + SafeRelease(&mAsteroidsRootSignature); + SafeRelease(&mCommandSignature); + SafeRelease(&mFence); + + SafeRelease(&mCommandQueue); + SafeRelease(&mDevice); + + if (mFenceEventHandle != NULL) { + CloseHandle(mFenceEventHandle); + mFenceEventHandle = NULL; + } + + delete mD3D12Sprite; +} + + +void Asteroids::ReleaseSwapChain() +{ + WaitForAll(); + + for (UINT s = 0; s < NUM_SWAP_CHAIN_BUFFERS; s++) { + SafeRelease(&mSwapChainBuffer[s].mRenderTarget); + } + SafeRelease(&mDepthStencil); + SafeRelease(&mSwapChain); +} + +inline void DisableDXGIWindowChanges(IUnknown* device, HWND window) +{ + IDXGIDevice * pDXGIDevice; + ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice))); + IDXGIAdapter * pDXGIAdapter; + ThrowIfFailed(pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter))); + IDXGIFactory * pIDXGIFactory; + ThrowIfFailed(pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory))); + + ThrowIfFailed(pIDXGIFactory->MakeWindowAssociation(window, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER)); + + pIDXGIFactory->Release(); + pDXGIAdapter->Release(); + pDXGIDevice->Release(); +} + +void Asteroids::ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height) +{ + ReleaseSwapChain(); + + // Create swap chain + { + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // Can create an SRGB render target view on the swap chain buffer + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = NUM_SWAP_CHAIN_BUFFERS; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used + swapChainDesc.Flags = 0; + + IDXGISwapChain1 *swapChain1 = nullptr; + ThrowIfFailed(dxgiFactory->CreateSwapChainForHwnd( + mCommandQueue, outputWindow, &swapChainDesc, nullptr, nullptr, &swapChain1)); + // MakeWindowAssociation must be called after CreateSwapChain + ThrowIfFailed(dxgiFactory->MakeWindowAssociation(outputWindow, + DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_PRINT_SCREEN)); + ThrowIfFailed(swapChain1->QueryInterface(&mSwapChain)); + swapChain1->Release(); + } + + { + // Create an SRGB view of the swap chain buffer + D3D12_RENDER_TARGET_VIEW_DESC desc = {}; + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + desc.Texture2D.MipSlice = 0; + desc.Texture2D.PlaneSlice = 0; + + // Create render target view for each swap chain buffer + for (UINT s = 0; s < NUM_SWAP_CHAIN_BUFFERS; s++) { + auto buffer = &mSwapChainBuffer[s]; + ThrowIfFailed(mSwapChain->GetBuffer(s, IID_PPV_ARGS(&buffer->mRenderTarget))); + mDevice->CreateRenderTargetView(buffer->mRenderTarget, &desc, buffer->mRenderTargetView); + } + } + + // create depth stencil view + { + D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex2D( + DXGI_FORMAT_D32_FLOAT, width, height, 1, 1, 1, 0, + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL ); + + // We use (1-z) so typically clear depth to 0 + D3D12_CLEAR_VALUE clearValue = {}; + clearValue.Format = desc.Format; + clearValue.DepthStencil.Depth = 0.0f; + clearValue.DepthStencil.Stencil = 0; + + ThrowIfFailed(mDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &desc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, + &clearValue, + IID_PPV_ARGS(&mDepthStencil) + )); + + mDevice->CreateDepthStencilView(mDepthStencil, nullptr, mDepthStencilView); + } + + // create the viewport and scissor + ZeroMemory(&mViewPort, sizeof(D3D11_VIEWPORT)); + mViewPort.TopLeftX = 0; + mViewPort.TopLeftY = 0; + mViewPort.Width = (float)width; + mViewPort.Height = (float)height; + mViewPort.MinDepth = 0.0f; + mViewPort.MaxDepth = 1.0f; + + mScissorRect.left = 0; + mScissorRect.top = 0; + mScissorRect.right = width; + mScissorRect.bottom = height; +} + +void Asteroids::CreatePSOs() +{ + // Generic root signature (t0, s0, b0) + { + CD3DX12_DESCRIPTOR_RANGE descRanges[2]; + descRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0); // t0 + descRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); // s0 + + CD3DX12_ROOT_PARAMETER rootParams[3]; + rootParams[RP_DRAW_CBV].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL); // b0 + rootParams[RP_TEX_SRV].InitAsDescriptorTable(1, &descRanges[0], D3D12_SHADER_VISIBILITY_PIXEL); // t0 + rootParams[RP_SMP].InitAsDescriptorTable(1, &descRanges[1], D3D12_SHADER_VISIBILITY_PIXEL); // s0 + + CD3DX12_ROOT_SIGNATURE_DESC RSLayout(ARRAYSIZE(rootParams), rootParams, 0, 0, + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS); + + ID3DBlob* serializedLayout = nullptr; + D3D12SerializeRootSignature(&RSLayout, D3D_ROOT_SIGNATURE_VERSION_1, &serializedLayout, 0); + + ThrowIfFailed(mDevice->CreateRootSignature( + 1, + serializedLayout->GetBufferPointer(), + serializedLayout->GetBufferSize(), + IID_PPV_ARGS(&mGenericRootSignature))); + + serializedLayout->Release(); + } + + // Asteroids root signature (tN, s0, b0) + { + CD3DX12_DESCRIPTOR_RANGE descRanges[2]; + descRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, NUM_UNIQUE_TEXTURES, 0, 0); // t0...tN + descRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); // s0 + + CD3DX12_ROOT_PARAMETER rootParams[3]; + rootParams[RP_DRAW_CBV].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL); // b0 + rootParams[RP_TEX_SRV].InitAsDescriptorTable(1, &descRanges[0], D3D12_SHADER_VISIBILITY_PIXEL); // t0 + rootParams[RP_SMP].InitAsDescriptorTable(1, &descRanges[1], D3D12_SHADER_VISIBILITY_PIXEL); // s0 + + CD3DX12_ROOT_SIGNATURE_DESC RSLayout(ARRAYSIZE(rootParams), rootParams, 0, 0, + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS); + + ID3DBlob* serializedLayout = nullptr; + D3D12SerializeRootSignature(&RSLayout, D3D_ROOT_SIGNATURE_VERSION_1, &serializedLayout, 0); + + ThrowIfFailed(mDevice->CreateRootSignature( + 1, + serializedLayout->GetBufferPointer(), + serializedLayout->GetBufferSize(), + IID_PPV_ARGS(&mAsteroidsRootSignature))); + + serializedLayout->Release(); + } + + // Command signature + { + D3D12_INDIRECT_ARGUMENT_DESC args[2] = {}; + args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW; + args[0].ConstantBufferView.RootParameterIndex = RP_DRAW_CBV; + args[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED; + + D3D12_COMMAND_SIGNATURE_DESC desc; + desc.ByteStride = sizeof(ExecuteIndirectArgs); + desc.NodeMask = 1; + desc.pArgumentDescs = args; + desc.NumArgumentDescs = ARRAYSIZE(args); + + ThrowIfFailed(mDevice->CreateCommandSignature(&desc, mGenericRootSignature, IID_PPV_ARGS(&mCommandSignature))); + } + + // Common state for this app + D3D12_GRAPHICS_PIPELINE_STATE_DESC defaultDesc = {}; + defaultDesc.BlendState = CD3DX12_BLEND_DESC(CD3DX12_DEFAULT()); + defaultDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(CD3DX12_DEFAULT()); + defaultDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT()); + defaultDesc.pRootSignature = mGenericRootSignature; + defaultDesc.SampleMask = UINT_MAX; + defaultDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + defaultDesc.NumRenderTargets = 1; + defaultDesc.RTVFormats[0] = mRTVFormat; + defaultDesc.DSVFormat = mDSVFormat; + defaultDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL; + defaultDesc.SampleDesc.Count = 1; + + // asteroid pipeline state + D3D12_INPUT_ELEMENT_DESC asteroidInputDesc[] = { + { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + D3D12_GRAPHICS_PIPELINE_STATE_DESC asteroidDesc = defaultDesc; + asteroidDesc.pRootSignature = mAsteroidsRootSignature; + asteroidDesc.VS = { g_asteroid_vs, sizeof(g_asteroid_vs) }; + asteroidDesc.PS = { g_asteroid_ps, sizeof(g_asteroid_ps) }; + asteroidDesc.InputLayout = { asteroidInputDesc, ARRAYSIZE(asteroidInputDesc) }; + + // skybox pipeline state + D3D12_INPUT_ELEMENT_DESC skyboxInputDesc[] = { + { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + D3D12_GRAPHICS_PIPELINE_STATE_DESC skyboxDesc = defaultDesc; + skyboxDesc.VS = { g_skybox_vs, sizeof(g_skybox_vs) }; + skyboxDesc.PS = { g_skybox_ps, sizeof(g_skybox_ps) }; + skyboxDesc.InputLayout = { skyboxInputDesc, ARRAYSIZE(skyboxInputDesc) }; + + // sprite pipeline state + D3D12_INPUT_ELEMENT_DESC spriteInputDesc[] = { + { "ATTRIB", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "ATTRIB", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + D3D12_GRAPHICS_PIPELINE_STATE_DESC spriteDesc = defaultDesc; + spriteDesc.VS = { g_sprite_vs, sizeof(g_sprite_vs) }; + spriteDesc.PS = { g_sprite_ps, sizeof(g_sprite_ps) }; + spriteDesc.InputLayout = { spriteInputDesc, ARRAYSIZE(spriteInputDesc) }; + spriteDesc.DepthStencilState.DepthEnable = FALSE; + // Premultiplied over blend + spriteDesc.BlendState.RenderTarget[0].BlendEnable = TRUE; + spriteDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; + spriteDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; + spriteDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + + // font pipeline state + D3D12_GRAPHICS_PIPELINE_STATE_DESC fontDesc = spriteDesc; + fontDesc.PS = { g_font_ps, sizeof(g_font_ps) }; + + concurrency::parallel_invoke( + [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&asteroidDesc, IID_PPV_ARGS(&mAsteroidPSO))); }, + [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&skyboxDesc, IID_PPV_ARGS(&mSkyboxPSO))); }, + [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&spriteDesc, IID_PPV_ARGS(&mSpritePSO))); }, + [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&fontDesc, IID_PPV_ARGS(&mFontPSO))); } + ); +} + + +void Asteroids::CreateSubsets(UINT numHeapsPerFrame) +{ + ReleaseSubsets(); + + mDrawsPerSubset = (NUM_ASTEROIDS + numHeapsPerFrame - 1) / numHeapsPerFrame; + mSubsetCount = numHeapsPerFrame; + + for (UINT f = 0; f < NUM_FRAMES_TO_BUFFER; f++) { + // Per-frame data + auto frame = &mFrame[f]; + auto dynamicUploadGPUVA = frame->mDynamicUpload->Heap()->GetGPUVirtualAddress(); + + for (UINT subsetIdx = 0; subsetIdx < mSubsetCount; ++subsetIdx) { + void* memory = _aligned_malloc(sizeof(SubsetD3D12), 64); + auto subset = new(memory) SubsetD3D12(mDevice, NUM_UNIQUE_TEXTURES, mAsteroidPSO); + frame->mSubsets.push_back(subset); + } + } +} + +void Asteroids::ReleaseSubsets() +{ + WaitForAll(); + + for (UINT i = 0; i < NUM_FRAMES_TO_BUFFER; ++i) { + for (auto j : mFrame[i].mSubsets) { + j->~SubsetD3D12(); + _aligned_free(j); + } + mFrame[i].mSubsets.clear(); + } + + mSubsetCount = 0; + mDrawsPerSubset = 0; +} + + +void Asteroids::CreateMeshes() +{ + auto asteroidMeshes = mAsteroids->Meshes(); + std::vector skyboxVertices; + CreateSkyboxMesh(&skyboxVertices); + + // Simple linear allocate + UINT64 asteroidVBSize = asteroidMeshes->vertices.size() * sizeof(asteroidMeshes->vertices[0]); + UINT64 asteroidIBSize = asteroidMeshes->indices.size() * sizeof(asteroidMeshes->indices[0]); + UINT64 skyboxVBSize = skyboxVertices.size() * sizeof(SkyboxVertex); + + UINT64 asteroidVBOffset = 0; + UINT64 asteroidIBOffset = asteroidVBOffset + asteroidVBSize; + UINT64 skyboxVBOffset = asteroidIBOffset + asteroidIBSize; + UINT64 totalSize = skyboxVBOffset + skyboxVBSize; + + mMeshUpload = new UploadHeap(mDevice, totalSize); + auto bufferWO = (BYTE*)mMeshUpload->DataWO(); + auto gpuVA = mMeshUpload->Heap()->GetGPUVirtualAddress(); + + // Asteroid vertices + { + memcpy(bufferWO + asteroidVBOffset, asteroidMeshes->vertices.data(), asteroidVBSize); + + mAsteroidVertexBufferView.BufferLocation = gpuVA + asteroidVBOffset; + mAsteroidVertexBufferView.SizeInBytes = static_cast(asteroidVBSize); + mAsteroidVertexBufferView.StrideInBytes = sizeof(asteroidMeshes->vertices[0]); + } + + // Asteroid indices + { + memcpy(bufferWO + asteroidIBOffset, asteroidMeshes->indices.data(), asteroidIBSize); + + mAsteroidIndexBufferView.BufferLocation = gpuVA + asteroidIBOffset; + mAsteroidIndexBufferView.SizeInBytes = static_cast(asteroidIBSize); + mAsteroidIndexBufferView.Format = sizeof(IndexType) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + } + + // Skybox vertices + { + memcpy(bufferWO + skyboxVBOffset, skyboxVertices.data(), skyboxVBSize); + + mSkyboxVertexBufferView.BufferLocation = gpuVA + skyboxVBOffset; + mSkyboxVertexBufferView.SizeInBytes = static_cast(skyboxVBSize); + mSkyboxVertexBufferView.StrideInBytes = sizeof(skyboxVertices[0]); + } +} + + +void Asteroids::CreateGUIResources() +{ + auto font = mGUI->Font(); + auto textureDesc = CD3DX12_RESOURCE_DESC::Tex2D( + DXGI_FORMAT_R8_UNORM, font->BitmapWidth(), font->BitmapHeight(), 1, 1); + + ThrowIfFailed(mDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &textureDesc, + D3D12_RESOURCE_STATE_COMMON, + nullptr, + IID_PPV_ARGS(&mFontTexture) + )); + + D3D11_SUBRESOURCE_DATA initialData = {}; + initialData.pSysMem = font->Pixels(); + initialData.SysMemPitch = font->BitmapWidth(); + + InitializeTexture2D(mDevice, mCommandQueue, mFontTexture, &textureDesc, 1, &initialData); + + // Load any GUI sprite textures + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i>=0 ? (*mGUI)[i] : mD3D12Sprite; + if (control->TextureFile().length() > 0 && mSpriteTextures.find(control->TextureFile()) == mSpriteTextures.end()) { + ID3D12Resource* texture = nullptr; + ThrowIfFailed(CreateTexture2DFromDDS_XXXX8( + mDevice, mCommandQueue, &texture, control->TextureFile().c_str(), DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)); + mSpriteTextures[control->TextureFile()] = texture; + } + } +} + +void Asteroids::WaitForAll() +{ + ThrowIfFailed(mCommandQueue->Signal(mFence, ++mCurrentFence)); + ThrowIfFailed(mFence->SetEventOnCompletion(mCurrentFence, mFenceEventHandle)); + WaitForSingleObject(mFenceEventHandle, INFINITE); +} + +void Asteroids::WaitForReadyToRender() +{ + // Wait for both the GPU to be done with our per-frame resources + HANDLE handles[] = { mFenceEventHandle }; + + ThrowIfFailed(mFence->SetEventOnCompletion(mFrame[mCurrentFrameIndex].mFrameCompleteFence, mFenceEventHandle)); + WaitForMultipleObjects(ARRAYSIZE(handles), handles, TRUE, INFINITE); +} + +void Asteroids::RenderSubset( + D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView, + size_t frameIndex, float frameTime, + SubsetD3D12* subset, UINT subsetIdx, + XMVECTOR cameraEye, XMMATRIX viewProjection, + const Settings& settings) +{ + UINT drawStart = mDrawsPerSubset * subsetIdx; + UINT drawEnd = std::min(drawStart + mDrawsPerSubset, (UINT)NUM_ASTEROIDS); + assert(drawStart < drawEnd); + auto staticAsteroidData = mAsteroids->StaticData(); + auto dynamicAsteroidData = mAsteroids->DynamicData(); + // Frame data + auto frame = &mFrame[frameIndex]; + auto drawConstantBuffers = frame->mDynamicUpload->DataWO()->mDrawConstantBuffers; + auto indirectArgs = frame->mDynamicUpload->DataWO()->mIndirectArgs; + + auto cmdLst = subset->Begin(mAsteroidPSO); + + // Root signature and common bindings + cmdLst->SetGraphicsRootSignature(mAsteroidsRootSignature); + ID3D12DescriptorHeap* heaps[2] = {mSRVDescs->Heap(), mSMPDescs->Heap()}; + cmdLst->SetDescriptorHeaps(ARRAYSIZE(heaps), heaps); + + // Common state + cmdLst->IASetIndexBuffer(&mAsteroidIndexBufferView); + cmdLst->IASetVertexBuffers(0, 1, &mAsteroidVertexBufferView); + cmdLst->RSSetViewports(1, &mViewPort); + cmdLst->RSSetScissorRects(1, &mScissorRect); + cmdLst->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + cmdLst->OMSetRenderTargets(1, &renderTargetView, true, &mDepthStencilView); + + // Set textures (all as a single descriptor table) and samplers + cmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, mSRVDescs->GPU(0)); + cmdLst->SetGraphicsRootDescriptorTable(RP_SMP, mSampler); + + if (!settings.executeIndirect) + { + // Standard draw path + auto constantsPointer = frame->mDrawConstantBuffersGPUVA + sizeof(DrawConstantBuffer) * drawStart; + for (UINT drawIdx = drawStart; drawIdx < drawEnd; ++drawIdx) + { + auto staticData = &staticAsteroidData[drawIdx]; + auto dynamicData = &dynamicAsteroidData[drawIdx]; + + XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mWorld, dynamicData->world); + XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mViewProjection, viewProjection); + + // Set root cbuffer + //cmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, mSRVDescs->GPU(0)); + cmdLst->SetGraphicsRootConstantBufferView(RP_DRAW_CBV, constantsPointer); + constantsPointer += sizeof(DrawConstantBuffer); + + cmdLst->DrawIndexedInstanced(dynamicData->indexCount, 1, dynamicData->indexStart, staticData->vertexStart, 0); + } + } + else + { + // ExecuteIndirect path + for (UINT drawIdx = drawStart; drawIdx < drawEnd; ++drawIdx) + { + auto dynamicData = &dynamicAsteroidData[drawIdx]; + + XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mWorld, dynamicData->world); + XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mViewProjection, viewProjection); + + auto drawIndexed = &indirectArgs[drawIdx].mDrawIndexed; + drawIndexed->IndexCountPerInstance = dynamicData->indexCount; + drawIndexed->StartIndexLocation = dynamicData->indexStart; + } + + UINT64 offset = (BYTE*)(&indirectArgs[drawStart]) - (BYTE*)frame->mDynamicUpload->DataWO(); + cmdLst->ExecuteIndirect(mCommandSignature, drawEnd - drawStart, + frame->mDynamicUpload->Heap(), offset, + nullptr, 0); + } + + subset->End(); +} + +void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Settings& settings) +{ + // Pick the right swap chain buffer based on where DXGI says we are... + auto backBufferIndex = mSwapChain->GetCurrentBackBufferIndex(); + assert(backBufferIndex < NUM_SWAP_CHAIN_BUFFERS); + auto swapChainBuffer = &mSwapChainBuffer[backBufferIndex]; + + // And the right frame data based on our own rotation/fences + assert(mCurrentFrameIndex < NUM_FRAMES_TO_BUFFER); + auto frame = &mFrame[mCurrentFrameIndex]; + + QueryPerformanceCounter((LARGE_INTEGER*)&mTotalUpdateTicks); + // Update asteroid simulation + if (settings.multithreadedRendering) + { + concurrency::parallel_for(0, mSubsetCount, [&](UINT subsetIdx) { + UINT drawStart = mDrawsPerSubset * subsetIdx; + UINT drawEnd = std::min(drawStart + mDrawsPerSubset, (UINT)NUM_ASTEROIDS); + mAsteroids->Update(frameTime, camera.Eye(), settings, drawStart, drawEnd - drawStart); + }); + } + else + { + mAsteroids->Update(frameTime, camera.Eye(), settings, 0, (UINT)NUM_ASTEROIDS); + } + LONG64 currCounter; + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mTotalUpdateTicks = currCounter - mTotalUpdateTicks; + + mTotalRenderTicks = currCounter; + // Generate command lists + if (settings.multithreadedRendering) + { + concurrency::parallel_for(0, mSubsetCount, [&](UINT subsetIdx) { + RenderSubset(swapChainBuffer->mRenderTargetView, mCurrentFrameIndex, frameTime, + frame->mSubsets[subsetIdx], subsetIdx, camera.Eye(), camera.ViewProjection(), settings); + }); + } + else + { + LONG64 SubsetUpdateTicks = 0, SubsetRenderTicks = 0; + for (unsigned int subsetIdx = 0; subsetIdx < mSubsetCount; ++subsetIdx) { + RenderSubset(swapChainBuffer->mRenderTargetView, mCurrentFrameIndex, frameTime, + frame->mSubsets[subsetIdx], subsetIdx, camera.Eye(), camera.ViewProjection(), settings); + } + } + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mTotalRenderTicks = currCounter - mTotalRenderTicks; + + LONG64 prevCounter = currCounter; + // Set up pre and post commands + { + auto cmdAlloc = frame->mCmdAlloc; + auto dynamicUploadWO = frame->mDynamicUpload->DataWO(); + ThrowIfFailed(cmdAlloc->Reset()); + + // Set resource states for rendering + ResourceBarrier rb; + rb.AddTransition(swapChainBuffer->mRenderTarget, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); + + // Pre + { + ThrowIfFailed(mPreCmdLst->Reset(cmdAlloc, mAsteroidPSO)); + rb.Submit(mPreCmdLst); + + // Don't need to clear color at the moment - skybox overwrites it all and no MSAA + //float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + //mPreCmdLst->ClearRenderTargetView(swapChainBuffer->mRenderTargetView, clearcol, 0, 0); + + // Clear depth + mPreCmdLst->ClearDepthStencilView(mDepthStencilView, D3D12_CLEAR_FLAG_DEPTH, 0.0f, 0, 0, nullptr); + + ThrowIfFailed(mPreCmdLst->Close()); + } + + rb.ReverseTransitions(); + + // Post + { + ThrowIfFailed(mPostCmdLst->Reset(cmdAlloc, mSkyboxPSO)); + + // Root signature and descriptor heaps + mPostCmdLst->SetGraphicsRootSignature(mGenericRootSignature); + ID3D12DescriptorHeap* heaps[2] = { frame->mSRVDescs->Heap(), mSMPDescs->Heap() }; + mPostCmdLst->SetDescriptorHeaps(2, heaps); + + mPostCmdLst->SetGraphicsRootDescriptorTable(RP_SMP, mSampler); + + // Common state + mPostCmdLst->RSSetViewports(1, &mViewPort); + mPostCmdLst->RSSetScissorRects(1, &mScissorRect); + mPostCmdLst->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + mPostCmdLst->OMSetRenderTargets(1, &swapChainBuffer->mRenderTargetView, true, &mDepthStencilView); + + // Draw skybox + { + auto constants = &frame->mDynamicUpload->DataWO()->mSkyboxConstants; + XMStoreFloat4x4(&constants->mViewProjection, camera.ViewProjection()); + + mPostCmdLst->IASetVertexBuffers(0, 1, &mSkyboxVertexBufferView); + + mPostCmdLst->SetGraphicsRootConstantBufferView(RP_DRAW_CBV, frame->mSkyboxConstants); + mPostCmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, frame->mSkyboxTexture); + mPostCmdLst->DrawInstanced(6 * 6, 1, 0, 0); + } + + // Draw sprites + { + auto vertexBase = dynamicUploadWO->mSpriteVertices; + auto vertexEnd = vertexBase; + + // Drop off any dynamic descriptors from the last frame + auto descHeap = frame->mSRVDescs; + descHeap->Resize(frame->mSRVDescsDynamicStart); + + mPostCmdLst->IASetVertexBuffers(0, 1, &frame->mSpriteVertexBufferView); + + for (int i = -1; i < (int)mGUI->size(); ++i) { + auto control = i >=0 ? (*mGUI)[i] : mD3D12Sprite; + if (!control->Visible()) continue; + + UINT numVertices = (UINT)(control->Draw(mViewPort.Width, mViewPort.Height, vertexEnd) - vertexEnd); + ID3D12Resource* texture = nullptr; + + // TODO: Could eliminate redundant state setting and cache descriptors... meh for now. + if (control->TextureFile().length() == 0) { // Font + mPostCmdLst->SetPipelineState(mFontPSO); + texture = mFontTexture; + } + else { // Sprite + mPostCmdLst->SetPipelineState(mSpritePSO); + texture = mSpriteTextures[control->TextureFile()]; + } + + if (texture) { + mPostCmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, descHeap->AppendSRV(texture)); + } + + mPostCmdLst->DrawInstanced(numVertices, 1, (UINT)(vertexEnd - vertexBase), 0); + vertexEnd += numVertices; + } + } + + // Final resource state transitions + rb.Submit(mPostCmdLst); + ThrowIfFailed(mPostCmdLst->Close()); + } + } + + // Set up command lists for submission + mCmdListsToSubmit.resize(0); + mCmdListsToSubmit.push_back(mPreCmdLst); + if (settings.submitRendering) { + for (auto &i :frame->mSubsets) + mCmdListsToSubmit.push_back(i->mCmdLst); + } + mCmdListsToSubmit.push_back(mPostCmdLst); + + mCommandQueue->ExecuteCommandLists( + (UINT)mCmdListsToSubmit.size(), + CommandListCast(mCmdListsToSubmit.data())); + + if (settings.vsync) + ThrowIfFailed(mSwapChain->Present(1, 0)); + else + ThrowIfFailed(mSwapChain->Present(0, 0)); + + ThrowIfFailed(mCommandQueue->Signal(mFence, ++mCurrentFence)); + frame->mFrameCompleteFence = mCurrentFence; + mCurrentFrameIndex = (mCurrentFrameIndex + 1) % NUM_FRAMES_TO_BUFFER; + + //LONG64 currCounter; + QueryPerformanceCounter((LARGE_INTEGER*)&currCounter); + mTotalRenderTicks += currCounter - prevCounter; +} + +void Asteroids::GetPerfCounters(float &UpdateTime, float &RenderTime) +{ + UpdateTime = (float)mTotalUpdateTicks/(float)mPerfCounterFreq; + RenderTime = (float)mTotalRenderTicks/(float)mPerfCounterFreq; +} + +} // namespace AsteroidsD3D12 diff --git a/Projects/Asteroids/src/asteroids_d3d12.h b/Projects/Asteroids/src/asteroids_d3d12.h new file mode 100644 index 0000000..3021d28 --- /dev/null +++ b/Projects/Asteroids/src/asteroids_d3d12.h @@ -0,0 +1,182 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "camera.h" +#include "settings.h" +#include "simulation.h" +#include "subset_d3d12.h" +#include "descriptor.h" +#include "upload_heap.h" +#include "util.h" +#include "gui.h" + +namespace AsteroidsD3D12 { + +CBUFFER_ALIGN struct DrawConstantBuffer { + DirectX::XMFLOAT4X4 mWorld; + DirectX::XMFLOAT4X4 mViewProjection; + DirectX::XMFLOAT3 mSurfaceColor; + float unused0; + DirectX::XMFLOAT3 mDeepColor; + float unused1; + UINT mTextureIndex; +}; + +CBUFFER_ALIGN struct SkyboxConstantBuffer { + DirectX::XMFLOAT4X4 mViewProjection; +}; + +struct ExecuteIndirectArgs { + D3D12_GPU_VIRTUAL_ADDRESS mConstantBuffer; + D3D12_DRAW_INDEXED_ARGUMENTS mDrawIndexed; +}; + +struct DynamicUploadHeap { + DrawConstantBuffer mDrawConstantBuffers[NUM_ASTEROIDS]; + SkyboxConstantBuffer mSkyboxConstants; + ExecuteIndirectArgs mIndirectArgs[NUM_ASTEROIDS]; + SpriteVertex mSpriteVertices[MAX_SPRITE_VERTICES_PER_FRAME]; +}; + +class Asteroids { +public: + Asteroids(AsteroidsSimulation* asteroids, GUI *gui, UINT minCmdLsts, IDXGIAdapter* adapter); + ~Asteroids(); + + void WaitForReadyToRender(); + void Render(float frameTime, const OrbitCamera& camera, const Settings& settings); + + void ReleaseSwapChain(); + void ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height); + + void GetPerfCounters(float &UpdateTime, float &RenderTime); + +private: + void WaitForAll(); + + void RenderSubset( + D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView, + size_t frameIndex, float frameTime, + SubsetD3D12* subset, UINT subsetIdx, + DirectX::XMVECTOR cameraEye, DirectX::XMMATRIX viewProjection, + const Settings& settings); + + void CreatePSOs(); + + void CreateSubsets(UINT numHeapsPerFrame); + void ReleaseSubsets(); + + void CreateMeshes(); + void CreateGUIResources(); + + struct Frame { + std::vector mSubsets; + ID3D12CommandAllocator* mCmdAlloc = nullptr; + + UploadHeapT* mDynamicUpload = nullptr; + D3D12_VERTEX_BUFFER_VIEW mSpriteVertexBufferView; + D3D12_GPU_VIRTUAL_ADDRESS mDrawConstantBuffersGPUVA; + + // Descriptor heap and associated GPU handles + SRVDescriptorList* mSRVDescs = nullptr; + D3D12_GPU_VIRTUAL_ADDRESS mSkyboxConstants; + D3D12_GPU_DESCRIPTOR_HANDLE mSkyboxTexture; + UINT mSRVDescsDynamicStart = 0; + + UINT64 mFrameCompleteFence = 0; + } mFrame[NUM_FRAMES_TO_BUFFER]; + + // Swap chain resources + struct SwapChainBuffer { + ID3D12Resource* mRenderTarget = nullptr; + D3D12_CPU_DESCRIPTOR_HANDLE mRenderTargetView; + } mSwapChainBuffer[NUM_SWAP_CHAIN_BUFFERS]; + + // Swap chain stuff + IDXGISwapChain3* mSwapChain = nullptr; + DXGI_FORMAT mRTVFormat; + D3D12_VIEWPORT mViewPort; + D3D11_RECT mScissorRect; + + // Fences and synchronization + size_t mCurrentFrameIndex = 0; + ID3D12Fence* mFence = nullptr; + HANDLE mFenceEventHandle = NULL; + UINT64 mCurrentFence = 0; + + // Device + ID3D12Device* mDevice = nullptr; + ID3D12CommandQueue* mCommandQueue = nullptr; + + // Root signature, descriptors and binding + ID3D12RootSignature* mGenericRootSignature = nullptr; + ID3D12RootSignature* mAsteroidsRootSignature = nullptr; + ID3D12CommandSignature* mCommandSignature = nullptr; + RTVDescriptorList* mRTVDescs = nullptr; + DSVDescriptorList* mDSVDescs = nullptr; + SRVDescriptorList* mSRVDescs = nullptr; + SMPDescriptorList* mSMPDescs = nullptr; + D3D12_CPU_DESCRIPTOR_HANDLE mDepthStencilView; + D3D12_GPU_DESCRIPTOR_HANDLE mSampler; + D3D12_VERTEX_BUFFER_VIEW mSkyboxVertexBufferView; + D3D12_INDEX_BUFFER_VIEW mAsteroidIndexBufferView; + D3D12_VERTEX_BUFFER_VIEW mAsteroidVertexBufferView; + + // Command lists + ID3D12GraphicsCommandList* mPreCmdLst = nullptr; + ID3D12GraphicsCommandList* mPostCmdLst = nullptr; + + DXGI_FORMAT mDSVFormat; + ID3D12Resource* mDepthStencil = nullptr; + + AsteroidsSimulation* mAsteroids = nullptr; + ID3D12Resource* mAsteroidTextures[NUM_UNIQUE_TEXTURES]; + + // Mesh + UploadHeap* mMeshUpload = nullptr; + UINT mIndexOffsets[MESH_MAX_SUBDIV_LEVELS + 2]; // inclusive + UINT mNumVerticesPerMesh = 0; + + ID3D12PipelineState* mAsteroidPSO = nullptr; + + ID3D12PipelineState* mSkyboxPSO = nullptr; + ID3D12Resource* mSkybox = nullptr; + + ID3D12PipelineState* mFontPSO = nullptr; + ID3D12Resource* mFontTexture = nullptr; + + ID3D12PipelineState* mSpritePSO = nullptr; + std::map mSpriteTextures; + + GUI* mGUI = nullptr; + + // Transient, just here to avoid allocations each frame + std::vector mCmdListsToSubmit; + + UINT mSubsetCount = 0; + UINT mDrawsPerSubset = 0; + + GUISprite* mD3D12Sprite = nullptr; + + UINT64 mPerfCounterFreq = 0; + volatile LONG64 mTotalUpdateTicks = 0, mTotalRenderTicks = 0; +}; + +} // namespace AsteroidsD3D12 diff --git a/Projects/Asteroids/src/asteroids_d3d12.ico b/Projects/Asteroids/src/asteroids_d3d12.ico new file mode 100644 index 0000000..449296f Binary files /dev/null and b/Projects/Asteroids/src/asteroids_d3d12.ico differ diff --git a/Projects/Asteroids/src/camera.cpp b/Projects/Asteroids/src/camera.cpp new file mode 100644 index 0000000..ac5ceec --- /dev/null +++ b/Projects/Asteroids/src/camera.cpp @@ -0,0 +1,170 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#include "camera.h" +#include "util.h" +#include + +using namespace DirectX; + + +OrbitCamera::OrbitCamera() +{ + // Defaults + mCenter = XMVectorSet(0, 0, 0, 0); + mUp = XMVectorSet(0, 1, 0, 0); + mRadius = 1.0f; + mMinRadius = 1.0f; + mMaxRadius = 1.0f; + mLongAngle = 0.0f; + mLatAngle = 0.0f; + + // Set up interaction context (i.e. touch input processing, etc) + ThrowIfFailed(CreateInteractionContext(&mInteractionContext)); + ThrowIfFailed(SetPropertyInteractionContext(mInteractionContext, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, TRUE)); + + { + INTERACTION_CONTEXT_CONFIGURATION config[] = + { + {INTERACTION_ID_MANIPULATION, + INTERACTION_CONFIGURATION_FLAG_MANIPULATION | + INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_X | + INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_Y | + INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING | + INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_INERTIA | + INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING_INERTIA | + INTERACTION_CONFIGURATION_FLAG_MANIPULATION_MULTIPLE_FINGER_PANNING + }, + }; + + ThrowIfFailed(SetInteractionConfigurationInteractionContext(mInteractionContext, ARRAYSIZE(config), config)); + } + + ThrowIfFailed(RegisterOutputCallbackInteractionContext(mInteractionContext, OrbitCamera::StaticInteractionOutputCallback, this)); +} + + +OrbitCamera::~OrbitCamera() +{ + DestroyInteractionContext(mInteractionContext); +} + + +void OrbitCamera::View( + DirectX::XMVECTOR center, float radius, float minRadius, float maxRadius, + float longAngle, float latAngle) +{ + mCenter = center; + mRadius = radius; + mMinRadius = minRadius; + mMaxRadius = maxRadius; + mLongAngle = longAngle; + mLatAngle = latAngle; + UpdateData(); +} + + +void OrbitCamera::Projection(float fov, float aspect) +{ + float fovY = (aspect <= 1.0 ? fov : fov / aspect); + mProjection = XMMatrixPerspectiveFovRH(fovY, aspect, 10000.0f, 0.1f); + UpdateData(); +} + + +void OrbitCamera::UpdateData() +{ + mEye = XMVectorSet( + mRadius * std::sin(mLatAngle) * std::cos(mLongAngle), + mRadius * std::cos(mLatAngle), + mRadius * std::sin(mLatAngle) * std::sin(mLongAngle), + 0.0f); + + mView = XMMatrixLookAtRH(mEye, mCenter, mUp); + mViewProjection = XMMatrixMultiply(mView, mProjection); +} + + +void OrbitCamera::OrbitX(float angle) +{ + mLongAngle += angle; + UpdateData(); +} + + +void OrbitCamera::OrbitY(float angle) +{ + float limit = XM_PI * 0.01f; + mLatAngle = std::max(limit, std::min(XM_PI-limit, mLatAngle + angle)); + UpdateData(); +} + + +void OrbitCamera::ZoomRadius(float delta) +{ + mRadius = std::max(mMinRadius, std::min(mMaxRadius, mRadius + delta)); + UpdateData(); +} + +void OrbitCamera::ZoomRadiusScale(float delta) +{ + mRadius = std::max(mMinRadius, std::min(mMaxRadius, mRadius * delta)); + UpdateData(); +} + + +void OrbitCamera::AddPointer(UINT pointerId) +{ + AddPointerInteractionContext(mInteractionContext, pointerId); +} + + +void OrbitCamera::ProcessPointerFrames(UINT pointerId, const POINTER_INFO* pointerInfo) +{ + ProcessPointerFramesInteractionContext(mInteractionContext, 1, 1, pointerInfo); +} + + +void OrbitCamera::RemovePointer(UINT pointerId) +{ + RemovePointerInteractionContext(mInteractionContext, pointerId); +} + + +void OrbitCamera::ProcessInertia() +{ + ProcessInertiaInteractionContext(mInteractionContext); +} + + +VOID CALLBACK OrbitCamera::StaticInteractionOutputCallback(VOID *clientData, const INTERACTION_CONTEXT_OUTPUT *output) +{ + auto camera = reinterpret_cast(clientData); + camera->InteractionOutputCallback(output); +} + + +void OrbitCamera::InteractionOutputCallback(const INTERACTION_CONTEXT_OUTPUT *output) +{ + switch(output->interactionId) + { + case INTERACTION_ID_MANIPULATION: { + auto delta = &output->arguments.manipulation.delta; + OrbitX(delta->translationX * 0.0007f); + OrbitY(-delta->translationY * 0.0007f); + ZoomRadiusScale(1.0f / delta->scale); + + break; + } + + default: + break; + } +} diff --git a/Projects/Asteroids/src/camera.h b/Projects/Asteroids/src/camera.h new file mode 100644 index 0000000..69ffc3f --- /dev/null +++ b/Projects/Asteroids/src/camera.h @@ -0,0 +1,62 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include +#include + +class OrbitCamera +{ +public: + OrbitCamera(); + ~OrbitCamera(); + + void View(DirectX::XMVECTOR center, + float radius, float minRadius, float maxRadius, + float longAngle, float latAngle); + + // Uses the provided fov for the larger dimension + void Projection(float fov, float aspect); + + DirectX::XMVECTOR const& Eye() const { return mEye; } + DirectX::XMMATRIX const& ViewProjection() const { return mViewProjection; } + + void AddPointer(UINT pointerId); + void ProcessPointerFrames(UINT pointerId, const POINTER_INFO* pointerInfo); + void ProcessInertia(); + void RemovePointer(UINT pointerId); + + void OrbitX(float angle); + void OrbitY(float angle); + void ZoomRadius(float delta); + void ZoomRadiusScale(float delta); + +private: + void UpdateData(); + static VOID CALLBACK StaticInteractionOutputCallback(VOID *clientData, const INTERACTION_CONTEXT_OUTPUT *output); + void InteractionOutputCallback(const INTERACTION_CONTEXT_OUTPUT *output); + + DirectX::XMVECTOR mCenter; + DirectX::XMVECTOR mUp; + float mMinRadius; + float mMaxRadius; + + float mLatAngle; + float mLongAngle; + float mRadius; + + DirectX::XMVECTOR mEye; + DirectX::XMMATRIX mView; + DirectX::XMMATRIX mProjection; + DirectX::XMMATRIX mViewProjection; + + HINTERACTIONCONTEXT mInteractionContext; +}; diff --git a/Projects/Asteroids/src/common.hlsl b/Projects/Asteroids/src/common.hlsl new file mode 100644 index 0000000..3609db6 --- /dev/null +++ b/Projects/Asteroids/src/common.hlsl @@ -0,0 +1,45 @@ +#ifndef COMMON_HLSL +#define COMMON_HLSL + +struct VSIn +{ + float3 position : POSITION; + float3 normal : NORMAL; +}; + +struct VSOut +{ + float4 position : SV_Position; + float3 positionModel : POSITIONMODEL; + float3 normalWorld : NORMAL; + float3 albedo : ALBEDO; // Alternatively, can pass just "ao" to PS and read cbuffer in PS +}; + + +struct Skybox_VSIn +{ + float3 position : POSITION; + float3 uvFace : UVFACE; +}; + +struct Skybox_VSOut +{ + float4 position : SV_Position; + float3 coords : UVFACE; +}; + + +struct Font_VSIn +{ + float2 position : POSITION; + float2 uv : UV; +}; + +struct Font_VSOut +{ + float4 position : SV_Position; + float2 uv : UV; +}; + + +#endif diff --git a/Projects/Asteroids/src/common_defines.h b/Projects/Asteroids/src/common_defines.h new file mode 100644 index 0000000..4af7169 --- /dev/null +++ b/Projects/Asteroids/src/common_defines.h @@ -0,0 +1,6 @@ +#ifndef COMMON_H +#define COMMON_H + +#define NUM_UNIQUE_TEXTURES 10 + +#endif diff --git a/Projects/Asteroids/src/dds.h b/Projects/Asteroids/src/dds.h new file mode 100644 index 0000000..65fe730 --- /dev/null +++ b/Projects/Asteroids/src/dds.h @@ -0,0 +1,145 @@ +//-------------------------------------------------------------------------------------- +// dds.h +// +// This header defines constants and structures that are useful when parsing +// DDS files. DDS files were originally designed to use several structures +// and constants that are native to DirectDraw and are defined in ddraw.h, +// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar +// (compatible) constants and structures so that one can use DDS files +// without needing to include ddraw.h. +//-------------------------------------------------------------------------------------- + +#ifndef _DDS_H_ +#define _DDS_H_ + +#include +#include + +#pragma pack(push,1) + +#define DDS_MAGIC 0x20534444 // "DDS " + +struct DDS_PIXELFORMAT +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwFourCC; + DWORD dwRGBBitCount; + DWORD dwRBitMask; + DWORD dwGBitMask; + DWORD dwBBitMask; + DWORD dwABitMask; +}; + +#define DDS_FOURCC 0x00000004 // DDPF_FOURCC +#define DDS_RGB 0x00000040 // DDPF_RGB +#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS +#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE +#define DDS_ALPHA 0x00000002 // DDPF_ALPHA + +const DDS_PIXELFORMAT DDSPF_DXT1 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }; + +const DDS_PIXELFORMAT DDSPF_DXT2 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 }; + +const DDS_PIXELFORMAT DDSPF_DXT3 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 }; + +const DDS_PIXELFORMAT DDSPF_DXT4 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 }; + +const DDS_PIXELFORMAT DDSPF_DXT5 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 }; + +const DDS_PIXELFORMAT DDSPF_A8R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; + +const DDS_PIXELFORMAT DDSPF_A1R5G5B5 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; + +const DDS_PIXELFORMAT DDSPF_A4R4G4B4 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; + +const DDS_PIXELFORMAT DDSPF_R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; + +const DDS_PIXELFORMAT DDSPF_R5G6B5 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; + +// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat) +const DDS_PIXELFORMAT DDSPF_DX10 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 }; + +#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT +#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT +#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH +#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH +#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE + +#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT +#define DDS_WIDTH 0x00000004 // DDSD_WIDTH + +#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE +#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP +#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX + +#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX +#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX +#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY +#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY +#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ +#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ + +#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\ + DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\ + DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ ) + +#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP + +#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME + +// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION +typedef enum DDS_RESOURCE_DIMENSION +{ + DDS_DIMENSION_TEXTURE1D = 2, + DDS_DIMENSION_TEXTURE2D = 3, + DDS_DIMENSION_TEXTURE3D = 4, +} DDS_RESOURCE_DIMENSION; + +// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG +typedef enum DDS_RESOURCE_MISC_FLAG +{ + DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L, +} DDS_RESOURCE_MISC_FLAG; + +typedef struct +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwHeight; + DWORD dwWidth; + DWORD dwPitchOrLinearSize; + DWORD dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags + DWORD dwMipMapCount; + DWORD dwReserved1[11]; + DDS_PIXELFORMAT ddspf; + DWORD dwCaps; + DWORD dwCaps2; + DWORD dwCaps3; + DWORD dwCaps4; + DWORD dwReserved2; +} DDS_HEADER; + +typedef struct +{ + DXGI_FORMAT dxgiFormat; + UINT resourceDimension; + DWORD miscFlag; // see DDS_RESOURCE_MISC_FLAG + UINT arraySize; + UINT reserved; +} DDS_HEADER_DXT10; + +#pragma pack(pop) + +#endif // _DDS_H diff --git a/Projects/Asteroids/src/descriptor.h b/Projects/Asteroids/src/descriptor.h new file mode 100644 index 0000000..4c87286 --- /dev/null +++ b/Projects/Asteroids/src/descriptor.h @@ -0,0 +1,165 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "util.h" + +#include +#include +#include + +// Used for CPU-only desriptors; simple linear allocator. +class DescriptorArray +{ +public: + // device must live for the lifetime of this object (no explicit refcount increment) + DescriptorArray(ID3D12Device* device, UINT maxDescriptors, D3D12_DESCRIPTOR_HEAP_TYPE type, + bool shaderVisible = false) + : mDevice(device) + , mMaxSize(maxDescriptors) + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = type; + desc.Flags = shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + desc.NumDescriptors = mMaxSize; + + ThrowIfFailed(mDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&mHeap))); + + mCPUBegin = mHeap->GetCPUDescriptorHandleForHeapStart(); + mHandleIncrementSize = mDevice->GetDescriptorHandleIncrementSize(desc.Type); + + if (shaderVisible) { + mGPUBegin = mHeap->GetGPUDescriptorHandleForHeapStart(); + } + } + + ~DescriptorArray() + { + SafeRelease(&mHeap); + } + + // Direct access to handles + CD3DX12_CPU_DESCRIPTOR_HANDLE CPU(UINT index = 0) const + { + return CD3DX12_CPU_DESCRIPTOR_HANDLE(mCPUBegin, index, mHandleIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE GPU(UINT index = 0) const + { + return CD3DX12_GPU_DESCRIPTOR_HANDLE(mGPUBegin, index, mHandleIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE GPUEnd() const { return GPU(mCurrentSize); } + INT HandleIncrementSize() const { return mHandleIncrementSize; } + + // NOTE: Caller can fill in data at new handle and/or derived classes provide + // specialized methods to do it in one step. + CD3DX12_CPU_DESCRIPTOR_HANDLE Append() + { + assert(mCurrentSize < mMaxSize); + return CPU(mCurrentSize++); + } + + // Invalidates contents of any previous handles + void Clear() { mCurrentSize = 0; } + void Resize(UINT newSize) { mCurrentSize = newSize; } + UINT Size() const { return mCurrentSize; } + +protected: + ID3D12Device* mDevice = nullptr; + ID3D12DescriptorHeap* mHeap = nullptr; + CD3DX12_CPU_DESCRIPTOR_HANDLE mCPUBegin; + CD3DX12_GPU_DESCRIPTOR_HANDLE mGPUBegin; + UINT mHandleIncrementSize = 0; + UINT mCurrentSize = 0; + UINT mMaxSize = 0; +}; + + +// Render target views +class RTVDescriptorList : public DescriptorArray +{ +public: + RTVDescriptorList(ID3D12Device* device, UINT maxDescriptors) + : DescriptorArray( device, maxDescriptors, D3D12_DESCRIPTOR_HEAP_TYPE_RTV ) + {} + + using DescriptorArray::Append; + + D3D12_CPU_DESCRIPTOR_HANDLE Append(ID3D12Resource* resource, D3D12_RENDER_TARGET_VIEW_DESC* desc = nullptr) + { + auto handle = Append(); + mDevice->CreateRenderTargetView(resource, desc, handle); + return handle; + } +}; + +// Depth stencil views +class DSVDescriptorList : public DescriptorArray +{ +public: + DSVDescriptorList(ID3D12Device* device, UINT descriptorCount) + : DescriptorArray( device, descriptorCount, D3D12_DESCRIPTOR_HEAP_TYPE_DSV ) + {} + + using DescriptorArray::Append; + + D3D12_CPU_DESCRIPTOR_HANDLE Append(ID3D12Resource* resource, D3D12_DEPTH_STENCIL_VIEW_DESC* desc = nullptr) + { + auto handle = Append(); + mDevice->CreateDepthStencilView(resource, desc, handle); + return handle; + } +}; + +// SRVs, CBVs, UAVs, etc. +class SRVDescriptorList : public DescriptorArray +{ +public: + SRVDescriptorList(ID3D12Device* device, UINT descriptorCount) + : DescriptorArray( device, descriptorCount, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, true ) + {} + + ID3D12DescriptorHeap* Heap() { return mHeap; } + + // In this class it's more useful to have the GPU handle returned + // In the long run it's useful to have both (for copying, etc) but this suits our purposes for now + + D3D12_GPU_DESCRIPTOR_HANDLE AppendSRV(ID3D12Resource* resource, D3D12_SHADER_RESOURCE_VIEW_DESC* desc = nullptr) + { + auto handle = GPU(mCurrentSize); + mDevice->CreateShaderResourceView(resource, desc, DescriptorArray::Append()); + return handle; + } + + D3D12_GPU_DESCRIPTOR_HANDLE AppendCBV(D3D12_CONSTANT_BUFFER_VIEW_DESC* desc = nullptr) + { + auto handle = GPU(mCurrentSize); + mDevice->CreateConstantBufferView(desc, DescriptorArray::Append()); + return handle; + } +}; + +// Samplers +class SMPDescriptorList : public DescriptorArray +{ +public: + SMPDescriptorList(ID3D12Device* device, UINT descriptorCount) + : DescriptorArray( device, descriptorCount, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, true ) + {} + + ID3D12DescriptorHeap* Heap() { return mHeap; } + + D3D12_GPU_DESCRIPTOR_HANDLE Append(D3D12_SAMPLER_DESC* desc) + { + auto handle = GPU(mCurrentSize); + mDevice->CreateSampler(desc, DescriptorArray::Append()); + return handle; + } +}; diff --git a/Projects/Asteroids/src/font.h b/Projects/Asteroids/src/font.h new file mode 100644 index 0000000..cd32626 --- /dev/null +++ b/Projects/Asteroids/src/font.h @@ -0,0 +1,98 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "sprite.h" +#include "intel_clear_bd_50_usascii.inl" +#include "stb_font_consolas_bold_50_usascii.inl" + +#include +#include + +class BitmapFont +{ +public: + SpriteVertex* DrawString(const char* str, float x, float y, float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const + { + for (; *str; ++str) { + auto codePoint = *str - STB_SOMEFONT_FIRST_CHAR; + assert(codePoint >= 0 && codePoint < mFontData.size()); + const stb_fontchar* cd = &mFontData[codePoint]; + + outVertex[0] = {x + cd->x0, y + cd->y0, cd->s0, cd->t0}; + outVertex[1] = {x + cd->x1, y + cd->y0, cd->s1, cd->t0}; + outVertex[2] = {x + cd->x1, y + cd->y1, cd->s1, cd->t1}; + outVertex[3] = outVertex[0]; + outVertex[4] = outVertex[2]; + outVertex[5] = {x + cd->x0, y + cd->y1, cd->s0, cd->t1}; + + for (int i = 0; i < 6; ++i) { + outVertex[i].x = (outVertex[i].x / viewportWidth * 2.0f - 1.0f); + outVertex[i].y = -(outVertex[i].y / viewportHeight * 2.0f - 1.0f); + } + + outVertex += 6; + x += cd->advance_int; + } + + return outVertex; + } + + void GetDimensions(const char* str, int* width, int* height) const + { + UINT w = 0; + for (; *str; ++str) { + auto codePoint = *str - STB_SOMEFONT_FIRST_CHAR; + assert(codePoint >= 0 && codePoint < mFontData.size()); + const stb_fontchar* cd = &mFontData[codePoint]; + w += cd->advance_int; + } + + *width = w; + *height = FontHeight(); + } + + int BitmapWidth() const { return mBitmapWidth; } + int BitmapHeight() const { return mBitmapHeight; } + int FontHeight() const { return mFontHeight; } + + virtual const unsigned char* Pixels() const = 0; + +protected: + // Setup by derived class + std::vector mFontData; + int mBitmapWidth; + int mBitmapHeight; + int mFontHeight; + + BitmapFont() {} + BitmapFont(const BitmapFont&) {} +}; + + +class IntelClearBold : public BitmapFont +{ +public: + IntelClearBold() + { + mFontData.resize(STB_FONT_intelclearbd_NUM_CHARS); + stb_font_intelclearbd(mFontData.data(), mFontPixels, STB_FONT_intelclearbd_BITMAP_HEIGHT); + + mBitmapWidth = STB_FONT_intelclearbd_BITMAP_WIDTH; + mBitmapHeight = STB_FONT_intelclearbd_BITMAP_HEIGHT; + mFontHeight = 50; // This doesn't seem to get put into the file anywhere... + } + + virtual const unsigned char* Pixels() const override { return mFontPixels[0]; } + +private: + unsigned char mFontPixels[STB_FONT_intelclearbd_BITMAP_HEIGHT][STB_FONT_intelclearbd_BITMAP_WIDTH]; +}; diff --git a/Projects/Asteroids/src/font_ps.hlsl b/Projects/Asteroids/src/font_ps.hlsl new file mode 100644 index 0000000..3100db9 --- /dev/null +++ b/Projects/Asteroids/src/font_ps.hlsl @@ -0,0 +1,12 @@ +#include "sprite_vs.hlsl" + +Texture2D Tex;// : register(t0); +SamplerState Tex_sampler;// : register(s0); + +void font_ps(in float4 position : SV_Position, + in Font_VSOut vs_out, + out float4 color : SV_Target ) +{ + float alpha = Tex.Sample(Tex_sampler, vs_out.uv).r; + color = float4(1, 1, 1, 1) * alpha; +} diff --git a/Projects/Asteroids/src/gui.h b/Projects/Asteroids/src/gui.h new file mode 100644 index 0000000..d56aab6 --- /dev/null +++ b/Projects/Asteroids/src/gui.h @@ -0,0 +1,149 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "font.h" + +#include +#include + + +class GUIControl +{ +protected: + int mX; + int mY; + int mWidth; + int mHeight; + std::string mTextureFile = ""; + bool mVisible = true;; + +public: + GUIControl() {} + virtual ~GUIControl() {} + + // For now, empty string means use the font texture/shader... let's not overengineer this yet :) + std::string TextureFile() const { return mTextureFile; } + + void Visible(bool visible) { mVisible = visible; } + bool Visible() const { return mVisible; } + + virtual SpriteVertex* Draw(float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const = 0; + + bool HitTest(int x, int y) const + { + return mVisible && (x >= mX && x < (mX + mWidth) && y > mY && y < (mY + mHeight)); + } +}; + + +class GUIText : public GUIControl +{ +private: + std::string mText; + const BitmapFont* mFont; + + void ComputeDimensions() + { + mFont->GetDimensions(mText.c_str(), &mWidth, &mHeight); + } + +public: + // Font lifetime managed by caller + GUIText(int x, int y, const BitmapFont* font, const std::string& text) + : mFont(font), mText(text) + { + mX = x; + mY = y; + ComputeDimensions(); + } + + void Text(const std::string& text) + { + mText = text; + ComputeDimensions(); + } + + virtual SpriteVertex* Draw(float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const override + { + return mFont->DrawString(mText.c_str(), float(mX), float(mY), viewportWidth, viewportHeight, outVertex); + } +}; + + +class GUISprite : public GUIControl +{ +private: + std::string mSpriteFile; + +public: + GUISprite(int x, int y, int width, int height, const std::string& spriteFile) + : mSpriteFile(spriteFile) + { + mX = x; + mY = y; + mWidth = width; + mHeight = height; + mTextureFile = spriteFile; + } + + virtual SpriteVertex* Draw(float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const override + { + return DrawSprite(float(mX), float(mY), float(mWidth), float(mHeight), viewportWidth, viewportHeight, outVertex); + } +}; + + +class GUI +{ +private: + std::vector mControls; + IntelClearBold mFont; // Single font for the entire GUI works for now + +public: + GUI() + { + } + ~GUI() + { + for (auto i : mControls) { + delete i; + } + } + + const BitmapFont* Font() const { return &mFont; } + + GUIText* AddText(int x, int y, const std::string& text = "") + { + auto control = new GUIText(x, y, &mFont, text); + mControls.push_back(control); + return control; + } + + GUISprite* AddSprite(int x, int y, int width, int height, const std::string& spriteFile) + { + auto control = new GUISprite(x, y, width, height, spriteFile); + mControls.push_back(control); + return control; + } + + // NOTE: Caller needs to preadjust x/y for any stretching/scaling going on + GUIControl* HitTest(int x, int y) const + { + for (auto i : mControls) { + if (i->HitTest(x, y)) return i; + } + return nullptr; + } + + GUIControl* operator[](size_t i) { return mControls[i]; } + size_t size() const { return mControls.size(); } +}; diff --git a/Projects/Asteroids/src/intel_clear_bd_50_usascii.inl b/Projects/Asteroids/src/intel_clear_bd_50_usascii.inl new file mode 100644 index 0000000..7a294a5 --- /dev/null +++ b/Projects/Asteroids/src/intel_clear_bd_50_usascii.inl @@ -0,0 +1,920 @@ +// Font generated by stb_font_inl_generator.c (4/1 bpp) +// +// Following instructions show how to use the only included font, whatever it is, in +// a generic way so you can replace it with any other font by changing the include. +// To use multiple fonts, replace STB_SOMEFONT_* below with STB_FONT_intelclearbd_*, +// and separately install each font. Note that the CREATE function call has a +// totally different name; it's just 'stb_font_intelclearbd'. +// +/* // Example usage: + +static stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS]; + +static void init(void) +{ + // optionally replace both STB_SOMEFONT_BITMAP_HEIGHT with STB_SOMEFONT_BITMAP_HEIGHT_POW2 + static unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH]; + STB_SOMEFONT_CREATE(fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT); + ... create texture ... + // for best results rendering 1:1 pixels texels, use nearest-neighbor sampling + // if allowed to scale up, use bilerp +} + +// This function positions characters on integer coordinates, and assumes 1:1 texels to pixels +// Appropriate if nearest-neighbor sampling is used +static void draw_string_integer(int x, int y, char *str) // draw with top-left point x,y +{ + ... use texture ... + ... turn on alpha blending and gamma-correct alpha blending ... + glBegin(GL_QUADS); + while (*str) { + int char_codepoint = *str++; + stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR]; + glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0, y + cd->y0); + glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1, y + cd->y0); + glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1, y + cd->y1); + glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0, y + cd->y1); + // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct + x += cd->advance_int; + } + glEnd(); +} + +// This function positions characters on float coordinates, and doesn't require 1:1 texels to pixels +// Appropriate if bilinear filtering is used +static void draw_string_float(float x, float y, char *str) // draw with top-left point x,y +{ + ... use texture ... + ... turn on alpha blending and gamma-correct alpha blending ... + glBegin(GL_QUADS); + while (*str) { + int char_codepoint = *str++; + stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR]; + glTexCoord2f(cd->s0f, cd->t0f); glVertex2f(x + cd->x0f, y + cd->y0f); + glTexCoord2f(cd->s1f, cd->t0f); glVertex2f(x + cd->x1f, y + cd->y0f); + glTexCoord2f(cd->s1f, cd->t1f); glVertex2f(x + cd->x1f, y + cd->y1f); + glTexCoord2f(cd->s0f, cd->t1f); glVertex2f(x + cd->x0f, y + cd->y1f); + // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct + x += cd->advance; + } + glEnd(); +} +*/ + +#ifndef STB_FONTCHAR__TYPEDEF +#define STB_FONTCHAR__TYPEDEF +typedef struct +{ + // coordinates if using integer positioning + float s0,t0,s1,t1; + signed short x0,y0,x1,y1; + int advance_int; + // coordinates if using floating positioning + float s0f,t0f,s1f,t1f; + float x0f,y0f,x1f,y1f; + float advance; +} stb_fontchar; +#endif + +#define STB_FONT_intelclearbd_BITMAP_WIDTH 256 +#define STB_FONT_intelclearbd_BITMAP_HEIGHT 222 +#define STB_FONT_intelclearbd_BITMAP_HEIGHT_POW2 256 + +#define STB_FONT_intelclearbd_FIRST_CHAR 32 +#define STB_FONT_intelclearbd_NUM_CHARS 95 + +#define STB_FONT_intelclearbd_LINE_SPACING 27 + +static unsigned int stb__intelclearbd_pixels[]={ + 0x20266666,0x10ccccc9,0x00001333,0x00019990,0x009a9880,0x310ccccc, + 0x00001333,0x00066666,0x9aaa9880,0x26620000,0x09999999,0x00133331, + 0x33333310,0x40001333,0x00000019,0xcccc9800,0xfffff10c,0xfffff507, + 0x3fffff63,0xff00001d,0x9100001f,0x40dfffff,0x265ffffc,0x001fffff, + 0x3ffffdc0,0xfecba800,0xffffffff,0x7fec003d,0x5fffffff,0x00dffff9, + 0xffffffd0,0x26009fff,0xeffffedb,0x220001bd,0xacdffedb,0x50999999, + 0x223fffff,0xa83fffff,0xfb1fffff,0x09ffffff,0x01fff000,0xffffb800, + 0xff106fff,0xffe85fff,0x6c0005ff,0x4005ffff,0xffffffeb,0xffffffff, + 0xffb002ef,0xbfffffff,0x03ffffea,0xfffffd00,0x8809ffff,0xfffffffd, + 0x004fffff,0x7ffffe44,0xffffffff,0xffff52ff,0x3fffe23f,0xffffa83f, + 0xfffffb1f,0x80005fff,0x20000fff,0xfffffff9,0xffff706f,0xfffff50d, + 0x3fe20003,0xf3002fff,0xffffffff,0xffffffff,0xd803bfff,0xffffffff, + 0xfffff15f,0xfffe8007,0x04ffffff,0x3fffffea,0xffffffff,0xffd001ef, + 0xffffffff,0x25ffffff,0x11fffffa,0x507fffff,0x363fffff,0xffffffff, + 0xfb98000f,0x0009bdff,0x7ffffff4,0xffff06ff,0x3fffe07f,0xff50006f, + 0xf7001fff,0xdfffffff,0xffdb759b,0x09ffffff,0x7fffffec,0x3ff65fff, + 0x7f4005ff,0xffffffff,0xfffff904,0xffffffff,0x807fffff,0xcefffffd, + 0xfffffffc,0xffff52ff,0x3fffe23f,0xaaaa883f,0x7ffdcc0a,0xb1002fff, + 0xffffffff,0xf3005dff,0x037fffff,0x07ffffdc,0x1fffffc8,0xffffd800, + 0xffffd806,0x71001cff,0x09ffffff,0x2ffffec0,0x01fffff7,0x27ffff40, + 0xfffff980,0xecaaceff,0x0fffffff,0x7fffff10,0x0dffff70,0x21555551, + 0x03fffff8,0xffff9800,0xfffc803f,0xffffffff,0x2a01efff,0x802fffff, + 0x204ffffe,0x04fffff8,0x3fffff80,0x7ffffe40,0xf910001e,0x2003ffff, + 0x225ffffd,0x002fffff,0x013ffffa,0x77fffff4,0x3fffe601,0xfff505ff, + 0x3ffe20ff,0x7c4001ff,0x0003ffff,0x09fffff0,0xffffffc8,0xffffffff, + 0x3fee05ff,0xffa807ff,0x7ec01fff,0x54007fff,0x200fffff,0x03fffffa, + 0xffff3000,0xfffb001d,0xffffe8bf,0x3fffa004,0xfffb804f,0xe8800dff, + 0xc82fffff,0x3604ffff,0x4003ffff,0x83fffff8,0x00ccccc8,0x817ffff6, + 0xdffffffa,0xffecbfff,0x3ff200ff,0xffe806ff,0xffa806ff,0x32002fff, + 0x2206ffff,0x003fffff,0x7fffd400,0xffffd804,0x3ffffdc5,0x9ffffd00, + 0xfffff880,0x3fe6001f,0xffb86fff,0x3ffa06ff,0x666443ff,0xffff10cc, + 0xffff307f,0x7ffec03f,0x3fff605f,0x41fff0df,0x7e403fc8,0x7c406fff, + 0x8804ffff,0x004fffff,0x813ffffe,0x105ffffb,0x4437bd95,0x7ffec2aa, + 0x7ffec01f,0x7fffcc5f,0xfffd001f,0xfffa809f,0xfe8005ff,0x7cc1ffff, + 0xf980ffff,0x7cc1ffff,0xff11ffff,0xff307fff,0x7ec03fff,0x3fe05fff, + 0x3ffe1fff,0xffc80080,0x7fd406ff,0xff003fff,0x2600dfff,0x101fffff, + 0x301fffff,0x7ffffffd,0xf883fffe,0x7ec03fff,0xffe85fff,0xffd004ff, + 0xffb809ff,0xa8001fff,0xe82fffff,0x98beffff,0x0fffffeb,0x8fffffcc, + 0x83fffff8,0x01fffff9,0x417ffff6,0x7c6ffff8,0xf90000ff,0xfb80dfff, + 0xd002ffff,0x200fffff,0x207ffffb,0xa83ffffa,0xffffffff,0x40ffffcf, + 0x6c05fffc,0xfc85ffff,0xfd006fff,0xfc809fff,0x8000ffff,0x83fffff8, + 0xfffffff9,0x2fffffff,0x1fffff98,0x07fffff1,0x03fffff3,0x82ffffec, + 0x20fffff8,0x90000fff,0xd80dffff,0x001fffff,0x03fffffb,0x09ffffd0, + 0x207fffe4,0xfffffff8,0xffffffff,0x037ffd40,0x217ffff6,0x01fffff9, + 0x04ffffe8,0x03fffff4,0xfffff880,0xfffff505,0x7fffffff,0x3ffffe60, + 0x7fffff11,0x3fffff30,0x2ffffec0,0x47fffff0,0x90000fff,0xe80dffff, + 0x000fffff,0x05fffff9,0x2fffff88,0x21ffffe0,0x21effffc,0x0fffffe9, + 0x007fffcc,0x20bffffb,0x803fffff,0x404ffffe,0x006fffff,0x1bffffe0, + 0x3fffffee,0x00cfffff,0x47ffffe6,0x83fffff8,0x01fffff9,0x81fffff2, + 0xaefffffd,0xd0000fff,0xf80bffff,0x2007ffff,0x03fffffb,0x03ffffdc, + 0x88bffff1,0x880fffff,0x440fffff,0x3601ffff,0xf905ffff,0xfd00dfff, + 0x7c409fff,0x0005ffff,0x71fffffa,0x5537ffff,0x3e600355,0xff11ffff, + 0xff307fff,0x7d403fff,0x880affff,0xffffffff,0xf98001ff,0x7c03ffff, + 0x2006ffff,0x04fffffa,0x02ffffec,0x989ffff3,0x3204ffff,0xff80ffff, + 0x3ff602ff,0xfff505ff,0xffe801ff,0x7ffc04ff,0x3e0006ff,0x7f47ffff, + 0x980006ff,0xf11fffff,0xf307ffff,0x4403ffff,0xeffffffe,0x7ffffd40, + 0x0bdfffff,0x7fffff40,0x3fe200ff,0x26005fff,0x204fffff,0x02fffff8, + 0x50ffffea,0x5405ffff,0xfe80ffff,0x3ff602ff,0xfff105ff,0xffe807ff, + 0x7ff404ff,0x3e0007ff,0x7fc6ffff,0x40000fff,0x11fffff9,0x307fffff, + 0x803fffff,0xffffffe8,0xffffe980,0xcfffffff,0xffffff00,0xfff8801d, + 0x3e2004ff,0x2a05ffff,0x200fffff,0x5c1ffffa,0x2601ffff,0xff80ffff, + 0x3ff601ff,0x3ff605ff,0x7ff405ff,0x7fec04ff,0xf10007ff,0xfc8bffff, + 0xcccdffff,0x2601abcc,0xf11fffff,0xf307ffff,0x8803ffff,0x0ffffffd, + 0x3ffff660,0x2fffffff,0xeffffff8,0x7fffc400,0x7ffc004f,0x3ff605ff, + 0x7fd406ff,0x7ffdc1ff,0x3ffea01f,0x0ffff80f,0x17ffff60,0x0fffffb8, + 0x13ffffa0,0x1fffff70,0xffff3000,0xfffd889f,0xffffffff,0xff982eff, + 0xfff11fff,0xfff307ff,0x7f4403ff,0x00ffffff,0xfffffa88,0x7c1fffff, + 0x0effffff,0x3ffffe20,0x3ffe2005,0x3ffe04ff,0x7fd403ff,0x7ffd43ff, + 0x3ffee02f,0x3fffcc0f,0x17ffff60,0x2fffff88,0x13ffffa0,0x9fffff50, + 0xffff9000,0xfffd105f,0xffffffff,0xff989fff,0xfff11fff,0xfff307ff, + 0x7fd403ff,0x8000bfff,0xffffcfff,0xffa886ff,0x7fc03fff,0x2a006fff, + 0x504fffff,0x801fffff,0x4c4ffff9,0x3a04ffff,0x7e40ffff,0x7fec06ff, + 0x7ff405ff,0x3ffa04ff,0x7fcc04ff,0x2000ffff,0x87fffff8,0xfffffffa, + 0xffffffff,0x3ffe62ff,0xffff11ff,0xffff307f,0x7ffdc03f,0x3fe0007f, + 0xffffc88f,0xffffd01f,0xfffff809,0x3ffee007,0xfff903ff,0xfff100df, + 0xfffff0bf,0xfffff705,0x17fffc45,0x17ffff60,0x0fffff70,0x027ffff4, + 0x27ffffe4,0xfffffb00,0xfffff98b,0xfffb980a,0x3ffe64ff,0xffff11ff, + 0xffff307f,0x7ffec03f,0x3fe0005f,0x3ffffa0f,0xdffff903,0x7fffff80, + 0x3ffff200,0xfffff02f,0x3fffe009,0xfffffb86,0xffffdaae,0xffeaaeff, + 0xfffd806f,0x7ffcc05f,0xfffd01ff,0xfff1009f,0xd880bfff,0x40ffffff, + 0x804ffffc,0x266ffffd,0xf11fffff,0xf307ffff,0x6c03ffff,0x0005ffff, + 0xffb83ffe,0xfff904ff,0xfffd80df,0xffb000ff,0xff303fff,0x36003fff, + 0xff887fff,0xffffffff,0xffffff9f,0xd802ffff,0xe805ffff,0xfd04ffff, + 0x2e009fff,0xbeffffff,0xffeca88a,0xfe82ffff,0xfb802fff,0x3fe65fff, + 0xfff11fff,0xfff307ff,0x7fec03ff,0xf00c05ff,0x7ffe41ff,0xffff902f, + 0xffffc80d,0xfffd001f,0x3ffee0ff,0x3fea007f,0xfff983ff,0x71ffffff, + 0xffffffff,0x3fff6007,0xfffc805f,0xffffd06f,0x7fff4009,0xffffffff, + 0x4fffffff,0x0dffffd0,0x45ffffd0,0x11fffff9,0x307fffff,0x403fffff, + 0x205ffffd,0xfff80dfa,0x1fffff10,0x1bffff20,0x5fffff50,0x3ffffe00, + 0x9ffffd06,0x7fffc400,0xfffe880f,0x7fec2eff,0x2001efff,0x805ffffd, + 0x81fffff9,0x004ffffe,0x7fffffe4,0xffffffff,0x3ff203ff,0x260acfff, + 0x0fffffdb,0x47ffffe6,0x83fffff8,0x01fffff9,0x417ffff6,0x0acfffe8, + 0xffd73fff,0x7fe40dff,0x7fc406ff,0xf8803fff,0xf884ffff,0x4002ffff, + 0x205ffffc,0x2600ab98,0xd8000aba,0xf005ffff,0xfd07ffff,0x30009fff, + 0xfffffffd,0x1bffffff,0x7ffffc40,0xffffffff,0x7cc1ffff,0xff11ffff, + 0xff307fff,0x7ec03fff,0xff905fff,0xffffffff,0xffffffff,0x7fffe401, + 0xffffe806,0xffffa806,0xffffb82f,0xfff88007,0x000002ff,0xffffb000, + 0x3fff200b,0xffffe86f,0x3fb20004,0xffffffff,0x301dffff,0xffffffff, + 0x5fffffff,0x3fffff30,0x0fffffe2,0x07ffffe6,0x05ffffe8,0xffffffd3, + 0xffffffff,0xffc805ff,0xffb807ff,0x7ec01fff,0xffb06fff,0x2e000bff, + 0x004fffff,0xfd800000,0xf5005fff,0xfe81ffff,0x00004fff,0xfffb9751, + 0x7dffffff,0xfffeb881,0x2effffff,0x3ffe2000,0xfff983ff,0xfff301ff, + 0xfea807ff,0xffffffff,0xa800dfff,0x802fffff,0x204fffff,0x83fffff8, + 0x02fffff8,0x3ffff200,0x4a8002ef,0xfffd8000,0xfff1005f,0xfffe87ff, + 0x4000004f,0xffffffea,0x2ea601ff,0x0009abcc,0xfffff880,0xfffffb83, + 0xffffea80,0xfb95002f,0x39dfffff,0x7fffcc00,0x7fdc02ef,0xff700fff, + 0x3fea0fff,0x40000fff,0xdffffffd,0xeb9981ab,0x6c0001ff,0x2005ffff, + 0x745ffffd,0x0004ffff,0xfffb3000,0x00000dff,0xffff1000,0xfffe987f, + 0x3ffff67f,0x000fffff,0x003fff10,0x7fffffc0,0xff886fff,0xfff03fff, + 0x3ff607ff,0x500006ff,0xffffffff,0xfffffdff,0x6400bfff,0xffffeeee, + 0x3fee005f,0x3ffa0fff,0x3eeeefff,0x2e200000,0x00002fff,0xfff88000, + 0xffff73ff,0x7fecdfff,0x03ffffff,0x007ffc00,0xfffff500,0x3f20dfff, + 0xffa86fff,0xfff00fff,0x400007ff,0xffffffc8,0xffffffff,0xb000ffff, + 0xffffffff,0x7fc400bf,0x3ffa2fff,0x4fffffff,0xb5000000,0x00000000, + 0x4fffffe2,0xfffffffb,0x3fffff62,0xf80005ff,0x640000ff,0x6fffffff, + 0x3fffff10,0x04ffffd8,0x01fffff3,0xffd30000,0xffffffff,0x0017dfff, + 0x7fffffec,0x74005fff,0x3fa4ffff,0xffffffff,0x00000004,0x80000000, + 0x73fffff8,0x8bffffff,0x1efffffd,0x1fff0000,0xffb30000,0x7e40dfff, + 0x3fe24fff,0xff900fff,0x00000dff,0xffecba88,0x001cceff,0xffffffb0, + 0xb800bfff,0x3fa7ffff,0xffffffff,0x00000004,0x80000000,0x73fffff8, + 0x107fffff,0x00013555,0x000aaa80,0x05554c00,0x45555510,0x202aaaa8, + 0x001aaaaa,0x00100000,0xaaaa9800,0x002aaaaa,0x85555544,0xaaaaaaaa, + 0x000001aa,0x00000000,0xfffff880,0x00135513,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x4ccccc00, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x09999970, + 0x39999930,0x000cc000,0x1ddddd30,0x01331000,0x3bbbba60,0x40000000, + 0x00000998,0x00001998,0x3bbbba20,0x00262001,0x99999100,0xffdb9807, + 0x332a21bd,0x1599911c,0x6f7f6544,0x3fffee03,0x7ffe401f,0xb73000ff, + 0x7bdffffd,0x3ffea003,0xfd7000ff,0x7bdfffff,0xfffff301,0x44000003, + 0xfffffecb,0x54000bef,0xfffffedc,0x200003ee,0x02fffff8,0x7ffffecc, + 0xff88001d,0x3ee06fff,0x3fffffff,0x265ffff9,0xff54ffff,0x1dffffff, + 0x9fffff10,0x5ffffe80,0xffffd880,0xffffffff,0xffffa804,0x7ffdc00f, + 0xffffffff,0x7ffcc3ff,0x000001ff,0xfffffff7,0x17ffffff,0xffffe980, + 0xffffffff,0x440000bf,0x102fffff,0xfffffffb,0xf8800bff,0xfb06ffff, + 0xffffffff,0x5ffffb7f,0x27bfffe6,0xffffffff,0xffd81fff,0x3fe206ff, + 0x7d402fff,0xffffffff,0x1effffff,0x3ffffea0,0x3ffff600,0xffffffff, + 0xff31ffff,0x00003fff,0xfffffd88,0xffffffff,0xff9101ff,0xffffffff, + 0x03ffffff,0xffff8800,0xffffb02f,0x7fffffff,0x7fffc400,0xffffb86f, + 0xffffffff,0xf32fffff,0xfffddfff,0xffffffff,0xfffff50d,0x3fffee01, + 0x7fffe407,0xffffffff,0x03ffffff,0x01fffff5,0x3fffffee,0xffffffff, + 0xfff30fff,0x400003ff,0xfffffffa,0xffffffff,0xffff304f,0xffffffff, + 0x00bfffff,0xfffff100,0xfffff705,0xffffff9d,0x3ffe2001,0x7ffc46ff, + 0xca9befff,0x2fffffff,0xfffffff3,0xfffb537b,0xfff05fff,0x3ff607ff, + 0x3fe604ff,0xacefffff,0xfffffeca,0xfffa80ff,0xfff980ff,0xaabdffff, + 0x22fffecb,0x01fffff9,0xffff1000,0x559bffff,0x201fff97,0xfffffffe, + 0xfdcaabce,0x880000ff,0xd82fffff,0x7e43ffff,0xf1002fff,0xfc8dffff, + 0xf705ffff,0x265fffff,0x04ffffff,0x0dfffff7,0x20bffff9,0x201fffff, + 0x1efffffe,0x3ffffe60,0xffffa85f,0xffffb80f,0x46d9805f,0x01fffff9, + 0xffff9000,0x077009ff,0x3fffffee,0x025c400d,0xffff8800,0x7ffff82f, + 0x04ffff98,0x0aaaaaa0,0x01fffffd,0x97ffffec,0x07fffff9,0x43fffff4, + 0x987ffff8,0x2e06ffff,0x00dfffff,0xfffffe88,0x7ffffd42,0xfffffc80, + 0x3fe60000,0x80001fff,0x2ffffff9,0x7ffcc000,0x00002fff,0xffff1000, + 0xbffff05f,0x09ffff10,0xffff8000,0x7ffd404f,0xffff32ff,0xfffb807f, + 0xfffe80ff,0x7fffe42f,0xfffff103,0x7fcc003f,0x7fd46fff,0xffe80fff, + 0x4c0007ff,0x511fffff,0x807bdfd9,0x04fffffe,0xffffd800,0x3000004f, + 0x239bffb7,0x82fffff8,0xfa87fffd,0x00002fff,0x0fffffe2,0x5fffff10, + 0x07ffffe6,0x3fffff50,0x89ffff50,0x500ffffe,0x00bfffff,0x3fffffd0, + 0x07ffffd4,0x17fffff4,0xffff3000,0xffffd13f,0xf101dfff,0x001fffff, + 0xfffff880,0xb800000f,0xffffffff,0x2fffff8b,0x42ffffb8,0x0007fffc, + 0x7ffffcc0,0x7fffc402,0xfffff32f,0xffff9801,0xdffff02f,0x02ffffc4, + 0x03fffff7,0xfffff500,0x7ffffd45,0xfffffc80,0x3fe60005,0xffffbfff, + 0x1fffffff,0x1fffffcc,0x7ffcc000,0x800003ff,0xfffffffd,0xffffcfff, + 0xffff982f,0xbffff91f,0xffa80000,0xff801fff,0xfff32fff,0xff9801ff, + 0xff902fff,0x3ffee3ff,0x3fff202f,0xf88000ff,0x3ea3ffff,0xfb80ffff, + 0x0bffffff,0x7fffcc00,0xffffffff,0x5c6fffff,0x002fffff,0xfffffb80, + 0x7dc00002,0xffffffff,0xffffffff,0xdffff702,0x03fffffb,0xfff98000, + 0x7fc402ff,0xfff32fff,0xffa801ff,0xff301fff,0x3fff67ff,0x7ffff407, + 0xfff10007,0x7ffd4bff,0xfffd00ff,0x17bfffff,0xfffff300,0xfb537bff, + 0x645fffff,0x000fffff,0xfffffc80,0x3e200000,0x9befffff,0xffffffca, + 0x3fff602f,0x01ffffff,0xfff88000,0x7fcc03ff,0xfff32fff,0xffb803ff, + 0x3fa00fff,0x9ffff5ff,0x6fffff80,0x3fffe000,0x3fffea6f,0xffff300f, + 0xdfffffff,0x3ffe6017,0xff704fff,0x7fecdfff,0xb00007ff,0x4c0fffff, + 0xaaaaaaaa,0x3ffff22a,0xffff705f,0x7fc405ff,0x00dfffff,0x3ffe0000, + 0x7fe406ff,0xfff32fff,0xffe809ff,0x7fdc07ff,0x1ffffaff,0x3ffffe20, + 0x3ffa0005,0x3ffea7ff,0x3fa200ff,0xffffffff,0xff984fff,0x7f407fff, + 0x3ffe7fff,0xf00007ff,0x640fffff,0xffffffff,0x3ffffa5f,0x3fffa00f, + 0xfff502ff,0x5c0dffff,0x77440bde,0x7fec4eee,0xff101fff,0x3e65ffff, + 0x300fffff,0x809fffff,0xfffffff8,0xffff806f,0x3fe0006f,0x3fea7fff, + 0xea800fff,0xffffffff,0x3e60efff,0x5c03ffff,0xfd0fffff,0x0000ffff, + 0x81fffffa,0xfffffffc,0x3fffe5ff,0x7ffd404f,0x7fec42ff,0x4fffffff, + 0x889fffd0,0x4c6fffff,0x42ffffff,0xfffffff9,0xffffff32,0xffffa83d, + 0xffd801ff,0x803fffff,0x007ffffe,0x97ffffe0,0x00fffffa,0x3fff6e20, + 0x25ffffff,0x01fffff9,0x8fffffd4,0x00fffffd,0xffffd800,0xffff900f, + 0x22bfffff,0x403fffff,0x22fffff8,0xcfffffe8,0x444fffff,0x7c41ffff, + 0xfd86ffff,0xfeffffff,0xffffffff,0xffffff32,0xffffdfff,0x2a00bfff, + 0x0fffffff,0x7ffffd80,0xffff1000,0x7fffd49f,0x3660000f,0x2fffffff, + 0x01fffff3,0x2fffff98,0x03fffff7,0xffff7000,0x3fff203f,0x35ffffff, + 0x805fffff,0x22fffff8,0x52fffffc,0x547fffff,0xff887fff,0xff986fff, + 0xffffffff,0x2fffffef,0xfffffff3,0xffffffff,0x7fc003ff,0x7005ffff, + 0x001fffff,0x7fffff30,0x07ffffd4,0x7ff44000,0xfff35fff,0xff9801ff, + 0xfff52fff,0x500005ff,0x007fffff,0xaaffffdc,0x801fffff,0xf32fffff, + 0xfa85ffff,0xffd2ffff,0xffff109f,0x3ffa60bf,0x8dffffff,0xf32fffff, + 0xffb3ffff,0x3dffffff,0xffffc800,0xfff5002f,0xf90009ff,0x7d43ffff, + 0x0000ffff,0xdfffff50,0x03ffffe6,0x3fffff50,0x1bffffe6,0x3ffe6000, + 0x3ee006ff,0xfff35fff,0xff8805ff,0xfff72fff,0x3ffee0df,0x1ffffbff, + 0x4fffff88,0x3ffff620,0xffff14ff,0x3fffe65f,0xfffff91f,0xf30001bf, + 0x4c00ffff,0x00ffffff,0x3ffffe20,0x3fffea0f,0x3e00000f,0xff36ffff, + 0xfb803fff,0xff10ffff,0x0005ffff,0xffffff88,0xffff7003,0x1fffffcb, + 0x3ffffe60,0x09ffff92,0x7fffffdc,0x7fc406ff,0x1553003f,0x2fffff88, + 0x83fffff3,0x40001aa9,0x004ffffa,0x27ffffe4,0xfffffb00,0xfffffa87, + 0x44001501,0xf35fffff,0xe809ffff,0x7dc7ffff,0x000effff,0x7ffffdc0, + 0xfffb800f,0x3ffffe5f,0x7fffe406,0x9ffffb2f,0xfffffc80,0x7fcc01ff, + 0xf880003f,0xff32ffff,0x00003fff,0x3ffffa20,0x7ffc4001,0x6c405fff, + 0x986fffff,0x882fffff,0xfc800cff,0xff33ffff,0x2601ffff,0xe85fffff, + 0x02ffffff,0xfffd0498,0xfb807fff,0x3ff65fff,0xff101fff,0x3ee5ffff, + 0x6c00efff,0x806fffff,0x0002fffb,0x2fffff88,0x03fffff3,0xffb30000, + 0x2e0009ff,0xbeffffff,0xffeca88a,0xf882ffff,0x21aeffff,0x9bcffffd, + 0xfffeba88,0xfff31fff,0xfa83dfff,0x981fffff,0xdfffffff,0xfdaa99ab, + 0xffff982f,0x89abdfff,0x5ffffd99,0x3fffffe6,0x7ffffcc2,0xffff32ff, + 0x3f6a03bf,0x400effff,0x0000fffd,0x2fffff88,0x03fffff3,0x3ffee000, + 0x001fffff,0x3fffffa0,0xffffffff,0x205fffff,0x7fffffff,0xfffffff5, + 0xffffffff,0x7fcc7fff,0xefffffff,0x5fffffff,0x3fffff60,0xffffffff, + 0xff906fff,0xffffffff,0xffffffff,0xfffffd8b,0xfffffeff,0x3fa2ffff, + 0xeeffffff,0xfffffffe,0xff100eff,0x220000bf,0xf32fffff,0x0003ffff, + 0x3ffffee0,0x440004ff,0xfffffffc,0xffffffff,0x7ffe404f,0xffd37fff, + 0xffffffff,0x8bffffff,0xfceffff9,0xffffffff,0x7fdc01ff,0xffffffff, + 0x03ffffff,0xfffffff7,0xffffffff,0xfff98bff,0xffffffff,0x22ffffed, + 0xfffffff9,0xffffffff,0x706fffff,0x00005fff,0x4bffffe2,0x01fffff9, + 0xffff7000,0x40000dff,0xfffffffa,0x1effffff,0xfffff880,0x7fffd47f, + 0xffffffff,0xfff984ff,0xfffff95f,0x2003dfff,0xffffffe8,0xdfffffff, + 0x3fff6201,0xffffffff,0xe983ffff,0xffffffff,0x85ffffb5,0xfffffff9, + 0x9cffffff,0x505ffffe,0x440000fd,0xf32fffff,0x0003ffff,0x3ffffee0, + 0x4400000c,0xffffffec,0x44003eff,0x707ffffc,0xfffffffd,0x3e6019ff, + 0x3ff21eff,0x000dffff,0xfffffdb8,0x001dffff,0x3fffff66,0x0befffff, + 0x3ffff620,0x3ffa64ef,0xfffd702f,0x41bfffff,0x05ffffe8,0xf8800002, + 0xff32ffff,0x00003fff,0x0026aaa2,0x5d440000,0x200000ab,0x97310009, + 0x40000135,0x00001aa8,0x026b2a62,0x5dd4c000,0x5300009a,0x22000015, + 0x0009aaa9,0x20000000,0x26099999,0x00001999,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xa8800000,0x0000abdb,0x4eeedc98,0x01ddddd3,0x33331000,0x33333333, + 0x98800133,0x001abcdb,0x5e6e5d44,0x2200000a,0x002eeeee,0x26200033, + 0x20009bcb,0x20019998,0x00eeeee9,0x654c4000,0xed802acd,0xddd34eee, + 0x7fd407dd,0x2fffffff,0xfffd9800,0xfff36fff,0xb00003ff,0xffffffff, + 0x05ffffff,0x3ffffae0,0x802effff,0xfffffffb,0x100003ff,0x107fffff, + 0xfffffd97,0xfff5003b,0x2003ffff,0x2007fffd,0x01fffff9,0xfffd3000, + 0x07ffffff,0x9afffff4,0x903fffff,0xffffffff,0x44009fff,0xffffffff, + 0x3fffff36,0xfffd0000,0xffffffff,0xd8805fff,0xffffffff,0xf105ffff, + 0xffffffff,0x0001ffff,0x3fffff88,0x7fffffdc,0x00efffff,0xfffffff7, + 0xff9807ff,0x3e6003ff,0x0001ffff,0x7ffffecc,0xffffffff,0x5ffffe80, + 0x87fffff3,0xffffffe8,0xefffffff,0xffffd800,0xff36ffff,0x00003fff, + 0xffffffff,0x5fffffff,0x7ffffd40,0xffffffff,0xfffe881f,0xffffffff, + 0x20000eff,0x33fffff8,0xfffffffd,0x1dffffff,0xdfffff98,0x201fffff, + 0x000ffffd,0x07ffffe6,0xffffb000,0xffffffff,0xfffd0dff,0x3fffe6bf, + 0x7fffe43f,0xffffefff,0x7cc04fff,0xceffffff,0x3fffff33,0xffff0000, + 0xffffffff,0x3e605fff,0xefffffff,0x906ffffe,0x9dffffff,0x9ffffffd, + 0x7ffc4000,0xffff73ff,0xffffffff,0xffd8bfff,0xfffd30df,0x3fffe60b, + 0x7ffcc004,0x440001ff,0xfeffffff,0x4fffffff,0x9afffff4,0x223fffff, + 0x0bffffff,0xffffff71,0x7fffd401,0xffff304f,0xf880003f,0x9999dfff, + 0x00999999,0x3dfffffb,0x7fc07aa0,0x7cc1efff,0x0007ffff,0x8fffffe2, + 0x9abdfffd,0x7fffffdb,0x307fffe2,0xfb01ffff,0x98001fff,0x001fffff, + 0x40aefb80,0x6fffffd9,0x9afffff4,0x323fffff,0x703fffff,0x409fffff, + 0x207ffffb,0x01fffff9,0x7fffcc00,0x7fcc0003,0x20004fff,0x04fffff8, + 0x01fffff9,0x3fffe200,0x8077e23f,0x31fffffe,0x3fe0ffff,0x7ffcc1ff, + 0xff98004f,0x00001fff,0xfffff005,0x5ffffe8f,0x27fffff3,0x06fffff8, + 0x07ffffec,0x06ffffc8,0x07ffffe6,0xffff5000,0xffe80007,0x4c0005ff, + 0x301fffff,0x005fffff,0x3ffffe20,0x7fd40043,0xfff52fff,0x0bfffe0d, + 0x001ffffb,0x3fffff30,0x64000000,0x3a1fffff,0xff35ffff,0x3fea7fff, + 0x7dc03fff,0x32a2ffff,0xcfffffec,0xfff32ccc,0x3f6e23ff,0x3ea02def, + 0x20002fff,0x01fffff9,0x7fffc400,0xffff301f,0x3e20001f,0x8003ffff, + 0x71fffffa,0x3fa0dfff,0x3ffe23ff,0xff30004f,0x32203fff,0x0003cccc, + 0xd1ffffee,0x3e6bffff,0xff73ffff,0xf8801fff,0x3ee3ffff,0xffffffff, + 0xfff34fff,0xffff33ff,0x2e09ffff,0x0001ffff,0x417fffee,0x3ff60009, + 0xfff904ff,0x7c4000bf,0x8003ffff,0x2a7ffffd,0xfff07fff,0x7fffe45f, + 0xfff30000,0x3ffa03ff,0x20001fff,0x745ffffe,0xff15ffff,0x3ff25fff, + 0xfff007ff,0x7ffdc9ff,0xffffffff,0xfffff34f,0xfffffff9,0xff907fff, + 0xdfdb53ff,0x7fe4017b,0xffd913ff,0xfb805bff,0x7d42ffff,0x0003ffff, + 0x0fffffe2,0xfffff700,0x83fffcc7,0xff11ffff,0x4c0009ff,0xc81fffff, + 0x003fffff,0x3ffffe60,0xafffff43,0xb2fffff8,0x200fffff,0x2e5ffffe, + 0xffffffff,0xff34ffff,0xffffffff,0x1fffffff,0xfeffffc8,0x3fffffff, + 0x55ffffb0,0xffffffff,0x3f6201bf,0xffdfffff,0x000effff,0x3ffffe20, + 0x3ffee003,0x7ffc45ff,0x7fffd41f,0x81ffff90,0x301bcdba,0xa83fffff, + 0x005fffff,0xff955553,0xfe81dfff,0xfff15fff,0x3fffa5ff,0xfffd006f, + 0x7f6654df,0xccccffff,0xffffff32,0xfff9359f,0xffd87fff,0xffffffff, + 0xfe86ffff,0xffffcfff,0x6fffffff,0x7ffffe40,0x04ffffff,0xffff8800, + 0xfff7003f,0xff901dff,0x3ffaa5df,0xbffff14f,0x7fffff4c,0x7ffcc0df, + 0x3ffe21ff,0x3f2006ff,0xffffffff,0xffffe80d,0x5fffff15,0x017ffffe, + 0x83ffffec,0x206ffffc,0x3ffffff9,0x4fffff98,0x7ffffff4,0xffffffff, + 0x7ffffc3f,0xffffffff,0x404fffff,0xfffffffe,0x100006ff,0x007fffff, + 0x1dfffff9,0x3ffffe20,0x90ffffff,0x3ea3ffff,0xffffffff,0x3fffe60e, + 0x3ffff61f,0x3ff2000f,0x1fffffff,0x2bffffd0,0xf2fffff8,0x200bffff, + 0x907ffffd,0x4c0dffff,0x206fffff,0x545fffff,0xdcdffffe,0xffffffff, + 0xffffff10,0xf93135df,0x301fffff,0xfffffffd,0x003dffff,0xfffff880, + 0x7fffd403,0x7fd400ef,0x2fffffff,0x74bffff1,0xffedffff,0x3ffe64ff, + 0xffff91ff,0xffc8005f,0xffffffff,0x7ffff40d,0x5fffff15,0x01bffffa, + 0x837ffff4,0x206ffffc,0x03fffff9,0x41bffff6,0xffd503da,0x7ffc7fff, + 0x3ee06fff,0x7e42ffff,0xfeffffff,0x04ffffff,0x3fffe200,0x7fffc03f, + 0xfd1000ef,0x641dffff,0xff71ffff,0x7ffdc3df,0xfffff30f,0x9fffffdb, + 0xffff9000,0xdfffffff,0xafffff41,0xb2fffff8,0x200fffff,0x905ffffe, + 0x4c0dffff,0x202fffff,0x006ffffc,0x3ffffe60,0x3fffffe4,0x7ffffc01, + 0x3ffffee3,0x7ffe542c,0xf10003ff,0x4c07ffff,0x002fffff,0x4409a988, + 0x3f65ffff,0xfffe83ff,0xffffff33,0x00dfffff,0x7fedcc00,0x3ffa4fff, + 0xffff15ff,0x3ffff25f,0xfffff007,0x3ffff209,0x3fffe606,0x3fff201f, + 0x7fc0006f,0x3ff65fff,0xffd807ff,0x3fffe5ff,0x7ffe404f,0xff10007f, + 0x7d407fff,0x0000ffff,0x1ffffc80,0x320bfffe,0xfff34fff,0xffffffff, + 0xf1000009,0x3a1fffff,0xff15ffff,0x3fee3fff,0x7cc01fff,0xf903ffff, + 0x7cc0dfff,0x3201ffff,0x0006ffff,0x937ffff4,0xb00fffff,0x3e69ffff, + 0x4c01ffff,0x001fffff,0x2fffff98,0x3ffffea0,0x7c400000,0x7ffc5fff, + 0x5fffc81f,0xfffffff3,0x005fffff,0xffff9000,0x3ffffa3f,0xa8666665, + 0x404fffff,0x02fffffb,0x40dffff9,0x01fffff9,0x01bffff2,0x9fffff00, + 0x03ffffdc,0xa9ffffec,0x400fffff,0x02fffff8,0xfffffa80,0x0ccccc01, + 0x7fe40000,0x3ffe21ff,0x6fffb81f,0x33fffff3,0x01fffffd,0xfffa8000, + 0xffffd2ff,0x7fffc00b,0x7fff406f,0xfff900ff,0x7ffcc0df,0x3ff201ff, + 0x260006ff,0x263fffff,0x401fffff,0xf32fffff,0x9803ffff,0x001fffff, + 0x0fffffc8,0x40000000,0xf86ffff8,0xffc81fff,0xfffff35f,0x3ffffe63, + 0x7dc00005,0xffd1ffff,0x7dc00bff,0xf904ffff,0x6407ffff,0x2606ffff, + 0x201fffff,0x4c6ffffc,0xfffe802f,0x7ffec1ff,0x3ffee05f,0x3fffe0ff, + 0x7ffe405f,0x100d40ff,0x00ffffff,0xf7000000,0xffd05fff,0x7fffb05f, + 0x87ffffe6,0x02fffffb,0x3e200664,0x3fa7ffff,0xddd35fff,0xffff87dd, + 0xfda8adff,0x6407ffff,0x2606ffff,0x201fffff,0x226ffffc,0x109beffe, + 0xdfffffd5,0x9fffff30,0xfffffb81,0x7fffff45,0x3ff2a0ac,0x7fc46fff, + 0xfea989ad,0x5404ffff,0x002eeeee,0x1bfffe00,0x7c2fffec,0xfff32fff, + 0xfffe83ff,0xfff500ff,0x7fdcc359,0x3fa5ffff,0xfff55fff,0xfffb89ff, + 0xffffffff,0x6403ffff,0x2606ffff,0x201fffff,0x326ffffc,0xffffffff, + 0xffffffff,0xfffffb01,0xfffffddf,0xfffa81ff,0xffefffff,0x42ffffff, + 0xfffffffc,0x0fffffff,0x7ffffdc0,0xff700003,0x3fe605ff,0xffea8dff, + 0x3fffe66f,0x7fffd41f,0xffff885f,0xffffffff,0x3a1fffff,0xff55ffff, + 0xff909fff,0xffffffff,0xf9009fff,0x7cc0dfff,0x3201ffff,0x3f66ffff, + 0xffffffff,0x03ffffff,0x3fffff62,0xffffffff,0xfffff703,0xffffffff, + 0xfff987ff,0xffffffff,0xfb803fff,0x0003ffff,0x80dffff0,0xfffffffc, + 0x3fe62fff,0xffd81fff,0x7fd43fff,0xffffffff,0x42ffffff,0xf55ffffe, + 0x2a09ffff,0xffffffff,0xf9002fff,0x7cc0dfff,0x3201ffff,0x7546ffff, + 0xffffffff,0x7002ffff,0xffffffff,0xfb805fff,0xffffffff,0xd883ffff, + 0xffffffff,0x7003ffff,0x007fffff,0x5ffff700,0xffffd880,0x7cc3ffff, + 0xf881ffff,0x441fffff,0xfffffffd,0x83ffffff,0xf55ffffe,0x4409ffff, + 0xfffffffd,0x3ff2000d,0x3fe606ff,0x3f201fff,0xfd706fff,0x9fffffff, + 0xfffb3000,0x0019ffff,0x3ffffee2,0x400bffff,0xffffffd9,0x2e000dff, + 0x003fffff,0x06ffff80,0x3ffffae0,0xffff981d,0xffff701f,0x3fb660df, + 0x3fffffff,0x57ffffa0,0x04fffffa,0x00155510,0x1bffff20,0x1fffff98, + 0x1bffff20,0x026aaa20,0x55544000,0x54c40000,0x300009aa,0x00035775, + 0x0fffffee,0x40000000,0x7fcc0198,0x3fa01fff,0x9804ffff,0x00009aaa, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x32e62000,0x3ba001bc,0x2e003eee,0x3aa6eeee, + 0x0004eeee,0x77774400,0x3bbbb25e,0xeec8003e,0xddd52eee,0xdddddddd, + 0xdddddddd,0x77647ddd,0xb1004eee,0x6c1bdddd,0xeeeeeeee,0x8009acde, + 0xeeeeeee8,0xeeeeeeee,0xdb2eeeee,0xdddddddd,0x6c01359b,0x0004eeee, + 0xffffc880,0x400dffff,0x004fffff,0x99fffff2,0x007fffff,0x7ffd4000, + 0x3ffea5ff,0xff8006ff,0xff70ffff,0xffffffff,0xffffffff,0x7cc9ffff, + 0x801fffff,0x43fffffc,0xfffffffe,0x3fffffff,0x7ffffc40,0xffffffff, + 0x3fffffff,0xfffffffd,0x5fffffff,0x17ffffa0,0xfff50000,0xffffffff, + 0x7fffc03d,0x3ff2004f,0x7fffc7ff,0x7fcc00ff,0xfc806fff,0x7fc3ffff, + 0x2000ffff,0x25fffffa,0xfffffffb,0xffffffff,0x4fffffff,0x37ffffdc, + 0x3ffffe60,0xfffffe85,0xffffffff,0xff101fff,0xffffffff,0xffffffff, + 0x3fffa7ff,0xffffffff,0x741effff,0x0005ffff,0x3ffffe60,0xffffffff, + 0xfffff02f,0x7ffe4009,0x7fffec7f,0x7ffdc02f,0x7ec00fff,0x7e41ffff, + 0x2003ffff,0x22fffffc,0xfffffffb,0xffffffff,0x4fffffff,0x2fffffe8, + 0x3fffffa0,0xfffffe80,0xffffffff,0xf880efff,0xffffffff,0xffffffff, + 0xfffd3fff,0xffffffff,0xe8dfffff,0x0005ffff,0x3fffffa0,0xffffdcce, + 0xffff80ff,0x3ff2004f,0x7ffdc7ff,0x7fec04ff,0x7c02ffff,0xf987ffff, + 0x2005ffff,0x20ffffff,0xccccccca,0xcfffffec,0x2ccccccc,0x6fffff98, + 0x7fffff70,0x3bffffa0,0xffeecccc,0x9905ffff,0x99999999,0xffff9999, + 0x3fffa5ff,0xdcaaaadf,0x24ffffff,0x005ffffe,0xfffff700,0xfffff309, + 0x9fffff07,0x7fffe400,0x7ffffc47,0x7ffffc05,0x3fe204ff,0xfff05fff, + 0xf3001fff,0x000bffff,0x00dffffb,0x7ffffe40,0x7ffffc43,0x3ffffa05, + 0x3fffea04,0x900000ff,0x749fffff,0x2a04ffff,0xd0ffffff,0x000bffff, + 0x17ffffa0,0x86ffffa8,0x004fffff,0x21fffff2,0x207ffffe,0xfffffff9, + 0x3fffea06,0xffff902f,0xfff7005f,0xfb0005ff,0x8000dfff,0x20fffffe, + 0x00fffffd,0x013ffffa,0x03fffff7,0xffff5000,0xffffe8bf,0x7fffdc04, + 0xbffffd2f,0x3ffe0000,0x7ff401ff,0x7fffc2ff,0x3ff2004f,0xfffc87ff, + 0xfff900ff,0x203fffff,0x00fffffc,0x0bfffff3,0x0fffffd0,0x3ffff600, + 0x7fcc0006,0xfff55fff,0xffe805ff,0x7fc404ff,0x40003fff,0x86fffff9, + 0x404ffffe,0xd3fffff8,0x000bffff,0x1fffff10,0x5ffffd80,0x027ffffc, + 0x0fffff90,0x05fffff5,0x3ffffffa,0xfffb03ff,0xfffe80df,0x7ffc407f, + 0xfb0004ff,0x0000dfff,0xd5fffff9,0xd00bffff,0xf009ffff,0x0007ffff, + 0x7fffffc4,0x4ffffe80,0x4fffff80,0x00bffffd,0xfffff500,0xdffffb00, + 0x04fffff8,0x1fffff20,0x13ffffe2,0x3fbfffe2,0xfff05fff,0xffb809ff, + 0x3ea01fff,0x0001ffff,0x00dffffb,0xffffd100,0x01ffffff,0x09ffffd0, + 0x2fffff88,0xfffd1000,0x3ffa03ff,0xfff804ff,0xffffd4ff,0xff30000b, + 0xfe801fff,0x7ffc7fff,0x3f2004ff,0xffd07fff,0xfff50bff,0x0fffff5f, + 0x05fffff1,0x4fffff88,0x1bffff60,0xffffd800,0xff500006,0x5fffffff, + 0x3ffffa00,0x7fffdc04,0xffb0001f,0x7f405fff,0x7c404fff,0xffd3ffff, + 0x10000bff,0x805fffff,0x7c7fffff,0x2004ffff,0x707ffffc,0xf90fffff, + 0xfffb1fff,0xffffa83f,0xfffd800f,0x3fffe06f,0x3f60003f,0x00006fff, + 0x3ffffff6,0x3ffa005f,0x3fea04ff,0x90005fff,0x809fffff,0x404ffffe, + 0xd2fffffa,0x000bffff,0x1bffffe0,0xffffffb8,0x13ffffe0,0x7ffffc80, + 0x3fffff30,0xf76fffe8,0xffb87fff,0xff5006ff,0xff303fff,0x40001fff, + 0x006ffffd,0x3fffe200,0x3a000fff,0xaaadffff,0xfffffecb,0xffa8001f, + 0xfe805fff,0x3e604fff,0xfd0fffff,0x0000bfff,0x3bfffff6,0xffff910b, + 0x7ffc3fff,0x3f2004ff,0x3fe07fff,0x3fe22fff,0xffff14ff,0x3ffffd8d, + 0xfffff100,0xbffff907,0xfffd8000,0x7400006f,0x00ffffff,0x3fffffa0, + 0xffffffff,0x98002fff,0x00efffff,0xadffffe8,0xfffdbaaa,0x3ffa4fff, + 0x300005ff,0xffffffff,0xfffffffd,0x7fffc1ff,0x3ff2004f,0x3ff607ff, + 0x3ffea4ff,0x3ffffa1f,0x07ffffe0,0x6ffffd80,0x02ffffe8,0x7fffec00, + 0x3f200006,0x05ffffff,0x3fffffa0,0xffffffff,0xf88002ef,0x000fffff, + 0xfffffffd,0xffffffff,0xffffe8df,0x3f200005,0xffffffff,0x7ffffeff, + 0x027ffffc,0x0fffff90,0xb2ffffdc,0xffc8ffff,0xffff12ff,0xfffa800f, + 0x3ffe60ff,0x6c0000ff,0x0006ffff,0xffffff30,0x3a005fff,0xffffffff, + 0x001fffff,0x3fffffa0,0x3fffa001,0xffffffff,0x741effff,0x0005ffff, + 0x7ffffe40,0xffacffff,0x7fffc6ff,0x3ff2004f,0x3fe207ff,0x3fffe7ff, + 0xa7fffcc5,0x005ffffa,0x22fffff8,0x005ffffb,0x6ffffd80,0xfffd0000, + 0x1fffffff,0xdffffd00,0xfffffd99,0x3ff60007,0x74003fff,0xffffffff, + 0x03ffffff,0x00bffffd,0xfffd5000,0x3fee7dff,0x7fff45ff,0x3ff6005f, + 0x7ff406ff,0xffff99ff,0x76ffff83,0x0007ffff,0x6cbffff9,0x0002ffff, + 0x06ffffd8,0xffffb800,0x5fffffbf,0x4ffffe80,0x07fffff4,0x3ffff200, + 0xffe8004f,0xdeeeefff,0x3fa00abc,0x00005fff,0x7ec0d4c0,0x7fec4fff, + 0x3fa006ff,0x7e405fff,0xfffbafff,0xffffd81f,0x01ffffd8,0x7ffff980, + 0x00fffff1,0x3ffff600,0x7fcc0006,0xfffb3fff,0xffe805ff,0x7ffcc4ff, + 0x3ea006ff,0x0005ffff,0x009ffffd,0x5ffffe80,0x10000000,0xc85fffff, + 0x2007ffff,0x404fffff,0xfdcffffa,0xfff706ff,0x0dfffd5f,0x7ffff400, + 0x04ffffaa,0xffffb000,0xffe8000d,0x3ffe26ff,0x3fa00fff,0xffc84fff, + 0xf9803fff,0x000effff,0x09ffffd0,0xffffe800,0x00000005,0x70dffff9, + 0x007fffff,0x07fffff7,0xfeffff88,0xff104fff,0x9ffffdff,0x7ffdc000, + 0x1ffffdcf,0xfffb0000,0x7dc000df,0x7dc2ffff,0x3a05ffff,0xf884ffff, + 0x200fffff,0x0ffffff8,0x3fffa000,0x7f40004f,0x00005fff,0x3fee0062, + 0xff882fff,0x2601ffff,0x00ffffff,0xffffffe8,0x3ffa02ff,0x02ffffff, + 0x3fffe200,0x006fffff,0x3ffff600,0xfff10006,0x3ffa0bff,0xffd02fff, + 0x3fea09ff,0x3fa05fff,0x0001ffff,0x027ffff4,0x3ffffa00,0x3f600005, + 0xfb5309bd,0x5c0dffff,0xacffffff,0xffffca88,0xff7004ff,0x01ffffff, + 0x7fffffe4,0x740000ff,0xffffffff,0x3f600003,0xd0006fff,0x201fffff, + 0x0ffffff9,0x04ffffe8,0x0ffffff6,0x37fffff6,0xaaaaaaaa,0xd1aaaaaa, + 0x0009ffff,0xaeffffe8,0xaaaaaaaa,0xfff302aa,0xffffffff,0xf803ffff, + 0xffffffff,0xffffffff,0x3ffe6007,0x5406ffff,0x6fffffff,0xfffb8000, + 0x000fffff,0x3ffff600,0xfffb8006,0x7fe403ff,0xffe85fff,0x3fe604ff, + 0x7f40ffff,0xffffffff,0xffffffff,0xfffd3fff,0xfe80009f,0xffffffff, + 0x5fffffff,0xffffffd0,0xdfffffff,0xffff5003,0xffffffff,0x8005ffff, + 0x3fffffff,0xffffff80,0xf880004f,0x06ffffff,0x7ffec000,0x7fc4006f, + 0xf8806fff,0x742fffff,0x6404ffff,0x745fffff,0xffffffff,0xffffffff, + 0xffd3ffff,0xe80009ff,0xffffffff,0xffffffff,0xfffff705,0xbfffffff, + 0x7ff4c001,0xffffffff,0xd8000eff,0x01ffffff,0xffffffd8,0xffb00001, + 0x0007ffff,0x6ffffd80,0x7fffec00,0xfff5002f,0x7ff41fff,0x7fc404ff, + 0x3fa2ffff,0xffffffff,0xffffffff,0xfffd3fff,0xfe80009f,0xffffffff, + 0x5fffffff,0x3fffee20,0x003dffff,0x3ffffae0,0x003effff,0x3ffffee0, + 0xffff7007,0x540000ff,0x00ffffff,0x7ffec000,0x3fea006f,0x6c005fff, + 0x3a5fffff,0xa804ffff,0xd0ffffff,0xffffffff,0xffffffff,0x3fa7ffff, + 0x40004fff,0xfffffffe,0xffffffff,0x2aa6005f,0x9800000a,0x0001abba, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x77775400,0x3b62004e,0x3bb65eee,0xd3002eee, + 0x776cdddd,0x30002eee,0x36bddddd,0xb004eeee,0x6c7ddddd,0xeeeeeeee, + 0xeeeeeeee,0x09ddddb2,0x277776c0,0x440cccc0,0xeed80999,0xeeeeeeee, + 0x1eeeeeee,0x3372ea20,0x2666202a,0x99999999,0x09999999,0xdddddddb, + 0x003579bd,0xffffff10,0x3ffee003,0x3fffa2ff,0xf9800fff,0x3ffa7fff, + 0xb0006fff,0x3adfffff,0xc805ffff,0x746fffff,0xffffffff,0xffffffff, + 0x0bffffd3,0x37ffff40,0x21fffe60,0xfe84fffc,0xffffffff,0xffffffff, + 0xfffffb82,0xc82effff,0xffffffff,0xffffffff,0xffffd5ff,0xffffffff, + 0xfb8005bf,0xf004ffff,0xfe8dffff,0x803fffff,0x3a7ffff9,0x03ffffff, + 0x7ffffcc0,0xbffffd6f,0xfffff980,0x7ffff40f,0xffffffff,0xffd3ffff, + 0x7f400bff,0x7d406fff,0xfffd86ff,0xfffffe83,0xffffffff,0x3aa2ffff, + 0xffffffff,0x7e45ffff,0xffffffff,0xffffffff,0xfffffd5f,0xffffffff, + 0xfe800bff,0x5c00ffff,0x742fffff,0x0fffffff,0x3ffffcc0,0xdffffffd, + 0xffffd800,0xffffd6ff,0x7fffc40b,0xfffe82ff,0xffffffff,0xfd3fffff, + 0x7400bfff,0x5c06ffff,0xffe85fff,0xffffe81f,0xffffffff,0xf52fffff, + 0xffffffff,0x47ffffff,0xfffffffc,0xffffffff,0xfffd5fff,0xffffffff, + 0x007fffff,0x27ffffd4,0x17ffffa0,0x3ffffffa,0x7ffcc04f,0x3ffffa7f, + 0xf3003fff,0x2dffffff,0x205ffffe,0x04fffffd,0x99dffffd,0x99999999, + 0x3ffffa59,0x3fffa005,0x7ffe406f,0x80ffff83,0xcceffffe,0xcccccccc, + 0x3fffa1cc,0xffffeeff,0xff91ffff,0xffffffff,0xffffffff,0x3bffffab, + 0xfffeeccc,0x2001ffff,0x00fffffe,0x03fffff5,0xfffffffd,0x7ffcc01f, + 0x3ffffa7f,0xfb006fff,0x2dffffff,0x705ffffe,0x40dfffff,0x005ffffe, + 0x0bffffd0,0x37ffff40,0x10bfff60,0x3fa0ffff,0x40005fff,0x2209dff8, + 0x2fffffea,0x33333331,0xfd333333,0x3ffa7fff,0xffd304ff,0x4c005fff, + 0xd03fffff,0x3a09ffff,0xffffffff,0x3fffe605,0x3fffffa7,0x7cc02fff, + 0x6fffffff,0x10bffffd,0x01ffffff,0x02fffff4,0x5ffffe80,0x3ffffa00, + 0x0ffff406,0x741bffe6,0x0005ffff,0x7fdc01a8,0x20004fff,0xd0fffff9, + 0x4409ffff,0x004fffff,0x437fffec,0x00fffffa,0xfffffffd,0x3fe603ff, + 0x3fffa7ff,0x406fffff,0xfffffffd,0xbffffd6f,0x5fffffd0,0x5ffffe80, + 0xffffd000,0x7fff400b,0x3fffea6f,0xffffffff,0xffffffff,0x0bffffd2, + 0x3e200000,0x0005ffff,0xe93ffff6,0x7c04ffff,0x4005ffff,0x42fffff8, + 0x204ffffe,0xffdffffe,0xfff305ff,0x7ffff4ff,0x302fffff,0xffffffff, + 0x3ffffadf,0x7ffffe45,0xffffe804,0xfffd0005,0x7ff400bf,0x3ffea6ff, + 0xffffffff,0xffffffff,0xbffffd2f,0x7c000000,0x0003ffff,0x41fffff1, + 0x404ffffe,0x003ffffe,0x26ffffc8,0x00fffff9,0x3afffffa,0xf981ffff, + 0x3ffa7fff,0x6ffffcff,0xf9ffffb0,0x3ffadfff,0x3ffea5ff,0xffd005ff, + 0x3a000bff,0x2005ffff,0x2a6ffffe,0xffffffff,0xffffffff,0xffd2ffff, + 0x00000bff,0x3ffffe60,0xfff90001,0xffffe8bf,0x3fffe204,0xff88001f, + 0xfffb2fff,0xfffe807f,0x6ffff9bf,0x27ffff98,0xfcbffffe,0x7fcc2fff, + 0xffffbcff,0x2bffffd6,0x0ffffffa,0xbffffd00,0x3fffa000,0x3ffa005f, + 0x333266ff,0xcccefffe,0xccdffffc,0xbffffd1c,0x32000000,0x0007ffff, + 0xd07ffffe,0x2209ffff,0x007ffffd,0x37fffee0,0x806ffff9,0xfb3ffffe, + 0xff985fff,0x3fffa7ff,0x6ffff8bf,0x5c7fffec,0xffd6ffff,0xffffffff, + 0x7f4003ff,0x9999efff,0x74099999,0xeeefffff,0xfeeeeeee,0x3206ffff, + 0xfff84fff,0xffffd01f,0xdddddddf,0x20005ddd,0x05fffffb,0xdffff700, + 0x9dffffd0,0xffffdb99,0xf80001df,0xfffeffff,0xfffe802f,0xdffff13f, + 0x27ffff98,0xf93ffffe,0x3fe65fff,0xffff74ff,0x3fffffad,0x03ffffff, + 0x7fffff40,0xffffffff,0x7ffff45f,0xffffffff,0xffffffff,0x0ffff606, + 0x201ffff1,0xfffffffe,0xffffffff,0xfffa8002,0xd0001fff,0xfd07ffff, + 0xffffffff,0x009fffff,0x3fffee00,0xd005ffff,0x7e47ffff,0x3fe63fff, + 0x3fffa7ff,0xdffff13f,0x5c3ffff6,0xffd6ffff,0xffffffff,0xffe8007f, + 0xffffffff,0x7f45ffff,0xffffffff,0xffffffff,0x3fa06fff,0x7ffcc2ff, + 0x3ffffa07,0xffffffff,0x64002fff,0x03ffffff,0xfffff500,0x3fffffa0, + 0xffffffff,0xd00002df,0x3fffffff,0x3ffffa00,0x9ffffe23,0x3a7ffff9, + 0x3f23ffff,0xffffcfff,0x5bfffee4,0xfffffffe,0x001fffff,0x3ffffffa, + 0xffffffff,0x7fffff45,0xffffffff,0x6fffffff,0x507fffe0,0x7f40dfff, + 0xffffffff,0x02ffffff,0xfffffb10,0x7ec0007f,0xffd04fff,0xffffffff, + 0x1bffffff,0xfffa8000,0x3a005fff,0x7dc3ffff,0xfff33fff,0x7ffff4ff, + 0x3ffffe23,0x3ee0ffff,0xfffd6fff,0xffffd5df,0x3fa001df,0xffffffff, + 0x745fffff,0xccceffff,0xfccccccc,0xf106ffff,0xfff70fff,0x7ffff409, + 0xccccccce,0xf9801ccc,0x02ffffff,0x3fffe600,0xffffd00f,0xd975555b, + 0x00dfffff,0xfffffd00,0x7fff4001,0xfffff83f,0x27ffff98,0x643ffffe, + 0x4fffffff,0xeb7fffdc,0x3f65ffff,0xd005ffff,0x555dffff,0x85555555, + 0x005ffffe,0x41bffffa,0xfc87fff9,0x3ffa03ff,0x200005ff,0xfffffffa, + 0x7fe40001,0x3ffa05ff,0x7fdc04ff,0x40003fff,0x007ffffd,0x41fffff4, + 0xf9cffffb,0x3ffa7fff,0x7ffc43ff,0x7dc0ffff,0xfffd6fff,0x7fffc4bf, + 0xffe803ff,0xfd0005ff,0x7400bfff,0xff56ffff,0xffffffff,0xffffffff, + 0x7fff45ff,0xf300005f,0x01bfffff,0xffff8800,0x3fffa01f,0xfffd804f, + 0x7ec0006f,0x74007fff,0xfd03ffff,0xffff5fff,0x1fffff4f,0x27ffffe4, + 0xeb7fffdc,0x7d45ffff,0x401fffff,0x005ffffe,0x0bffffd0,0xb7ffff40, + 0xfffffffa,0xffffffff,0x3a2fffff,0x0005ffff,0xffffff98,0xff700004, + 0xffe80dff,0xffb804ff,0x6c0007ff,0x4007ffff,0x503ffffe,0xfffdffff, + 0x7ffff4ff,0xfffff883,0x6ffffb80,0x90bffffd,0x01ffffff,0x02fffff4, + 0x5ffffe80,0x3ffffa00,0xffffff56,0xffffffff,0x45ffffff,0x005ffffe, + 0x7ffffc40,0x3e00002f,0x7402ffff,0xb804ffff,0x000fffff,0x1fffff60, + 0x7ffffd00,0x7ffffec0,0x3ffa7fff,0x333103ff,0x3fffee01,0x0bffffd6, + 0x17fffffa,0x05ffffe8,0xbffffd00,0x7ffff400,0xffd55516,0xff75559f, + 0x415555ff,0x005ffffe,0x7ffffec0,0x3ea00002,0xfe807fff,0xfd804fff, + 0x40007fff,0x007ffffd,0x01fffff4,0xfffffff3,0x7ffff4ff,0x7fdc0003, + 0xffffd6ff,0x3fffe60b,0xfffd03ff,0x3fa000bf,0x3a005fff,0xff06ffff, + 0xfff983ff,0x7ffff406,0x7ffc0005,0x400003ff,0x803ffffe,0x404ffffe, + 0x05fffffb,0x7fffec00,0x7fff4007,0x7ffec03f,0x3fa7ffff,0x40003fff, + 0xfd6ffffb,0x7dc0bfff,0xe81fffff,0x0005ffff,0x00bffffd,0x437ffff4, + 0x5c0ffff8,0x7f405fff,0xaaaaefff,0xaaaaaaaa,0x7fffff31,0x55555555, + 0xff980355,0xfe800fff,0xaaaadfff,0xfffffecb,0x7ec0003f,0x74007fff, + 0x4403ffff,0x7fffffff,0x00fffffa,0xdffff700,0x017ffffa,0x1ffffffb, + 0x05ffffe8,0xbffffd00,0x7ffff400,0x87fff986,0x7404fffc,0xffffffff, + 0xffffffff,0xfffff74f,0xffffffff,0xfd80bfff,0xfd004fff,0xffffffff, + 0xffffffff,0xffb0000d,0xfe800fff,0xfc803fff,0x3a7fffff,0x0003ffff, + 0xeb7fffdc,0x4405ffff,0x46ffffff,0x005ffffe,0x0bffffd0,0x37ffff40, + 0x6c37ffd4,0x7f402fff,0xffffffff,0xffffffff,0xffffffb4,0xffffffff, + 0x7fc40bff,0xfd001fff,0xffffffff,0xffffffff,0xffb00001,0xfe800fff, + 0xf8803fff,0x3a7fffff,0x0003ffff,0xeb7fffdc,0xa805ffff,0x24ffffff, + 0x005ffffe,0x0bffffd0,0x37ffff40,0x742fffdc,0x7f401fff,0xffffffff, + 0xffffffff,0xffffffb4,0xffffffff,0x7fe40bff,0x3fa005ff,0xffffffff, + 0x0cffffff,0xfffb0000,0xffe800ff,0xff7003ff,0x7ff4ffff,0x5c0003ff, + 0xffd6ffff,0x3f600bff,0xfd2fffff,0x2000bfff,0x005ffffe,0x21bffffa, + 0xff83fffc,0x7ff400ff,0xffffffff,0x4fffffff,0xfffffffb,0xffffffff, + 0x3ffe20bf,0x3fa002ff,0xffffffff,0x000bcdef,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xddddd100,0x3300000b,0x44000333,0xed809999,0xdeeeeeee,0x220001ac, + 0x00019999,0x00000000,0x00000000,0x00000000,0x00000000,0xf5000000, + 0x003fffff,0x3fffaa00,0xe88000ff,0xfe84ffff,0xffffffff,0x003effff, + 0x03ffffe4,0xdfffdb30,0xb9500179,0x007bdffd,0x3ffb2e60,0x93000bde, + 0x017bdfdb,0xffedb980,0x664402cd,0x3b2a20ac,0xcc882def,0x3f6e60ac, + 0xdb980acf,0xb0003eff,0x09ffffff,0xfffea800,0x8000ffff,0x84fffffd, + 0xfffffffe,0xffffffff,0xfff9001e,0xffb100ff,0xffffffff,0xfffd5019, + 0x5dffffff,0x7fffe400,0x04ffffff,0x3fffff62,0x8803ffff,0xfffffffd, + 0xff302eff,0x3ffe69ff,0x4c4fffff,0xff54ffff,0xc8dfffff,0xefffffff, + 0x3ffe2000,0x0007ffff,0xffffffd5,0xa8001fff,0x84ffffff,0xfffffffe, + 0xffffffff,0xffc804ff,0x7f4407ff,0xffffffff,0x3fa25fff,0xffffffff, + 0x4c01ffff,0xfffffffe,0xf505ffff,0xffffffff,0x7d40bfff,0xffffffff, + 0xf985ffff,0xfff9efff,0x3fffffff,0x27bfffe6,0xffffffff,0xfffff95f, + 0x400dffff,0xfffffffb,0x3fae002f,0xffffffff,0x3e2000ff,0x84ffffff, + 0xeefffffe,0xffffffee,0x7e403fff,0x7e407fff,0xffffffff,0x7ec1ffff, + 0xffffffff,0x2206ffff,0xffffffff,0x881fffff,0xffffffff,0x82ffffff, + 0xfffffff8,0xffffffff,0x7ffffcc4,0xffffffff,0xff30ffff,0xffffffff, + 0xfbffffff,0xffffffff,0x3fa005ff,0x5fffffff,0xfffff500,0xffffffff, + 0x7fff4001,0xfe84ffff,0xd5105fff,0x81ffffff,0xffffecc9,0x3a0ccccf, + 0x99bfffff,0xf885fdb9,0xeca9abef,0xb02fffff,0x9bffffff,0x360df975, + 0x52dfffff,0x81fffffb,0xaefffffd,0xfffffca9,0x3fffe61f,0xfc9acfff, + 0xf33fffff,0x59ffffff,0xfffffff7,0xfff759ff,0xf300dfff,0xffff5fff, + 0x3ffa001f,0xfffdefff,0xff9000ff,0x09ffffff,0x00bffffd,0x8bfffff9, + 0xfffffffb,0xf11fffff,0x4c07ffff,0xff805701,0xffa84fff,0x0202ffff, + 0x07ffffea,0x517fffec,0x209fffff,0x26fffff9,0x3ffffff9,0x4fffff98, + 0x5ffffff3,0xffffffd0,0xffffff03,0x1ffff900,0x005ffffb,0x5cffffea, + 0x800fffff,0xfffffffa,0xfffe84ff,0xfffd005f,0x7ffdc5ff,0xffffffff, + 0xfffff11f,0x64000007,0xfd85ffff,0x8001ffff,0x206ffffd,0x364ffffa, + 0x6407ffff,0xf30fffff,0x7c0dffff,0xff35ffff,0x3f20bfff,0xf905ffff, + 0xff00ffff,0x3ffeabff,0x0ffa005f,0x01fffff7,0xdfffff88,0xfe84ffff, + 0xf5005fff,0x7dcbffff,0xffffffff,0x3ffe1fff,0x0000cfff,0x6ffffa80, + 0x05ffffe8,0x5ffffd00,0x2ffffc40,0x809fffff,0x32fffff9,0x407fffff, + 0xf36ffffd,0x2a05ffff,0x502fffff,0x401fffff,0xf13ffffa,0x2001ffff, + 0xfffff700,0xffffd801,0x84ffffbb,0x005ffffe,0x99fffffa,0xfffffecc, + 0x3ee0cccc,0xceffffff,0x332a2001,0xffffeeee,0x7ffffc46,0xfff88003, + 0xeeeeeeff,0x16ffffee,0x007fffff,0x267fffff,0x202fffff,0xf36ffffc, + 0x2603ffff,0x501fffff,0x401fffff,0x360ffffd,0x0003ffff,0x07ffffdc, + 0x2dffff70,0xe84ffffb,0x2005ffff,0x80fffffc,0x807ffffc,0xfffffffd, + 0x32202eff,0xffffffff,0x7cc6ffff,0x8002ffff,0xfffffff9,0xffffffff, + 0xffff36ff,0xffff005f,0x3fffe69f,0x3fff201f,0xfffff36f,0x3fffe603, + 0xffff500f,0x3ffe201f,0x7fffdc6f,0x7fdc0006,0xff300fff,0x3fee1fff, + 0xfffe84ff,0x3ff2005f,0xffc81fff,0xfb3007ff,0xffffffff,0xfffff109, + 0xffffffff,0xffffa8df,0xff98001f,0xffffffff,0x6fffffff,0x03fffff5, + 0x2bffffd0,0x01fffff9,0x4dbffff2,0x301fffff,0x201fffff,0x00fffffa, + 0x887ffff7,0x001fffff,0x3ffffee0,0xffffe880,0x13fffee2,0x017ffffa, + 0x2fffffb8,0x07ffffc8,0x7fffecc0,0x3a23ffff,0xabdfffff,0x46ffffca, + 0x02fffff8,0xfffff880,0xaaaaaaab,0xff11aaaa,0xff005fff,0x3fe69fff, + 0x3f201fff,0xfff36fff,0x3fe603ff,0xff500fff,0x3fa01fff,0xffe81fff, + 0x2e0004ff,0xd80fffff,0x7dc5ffff,0xffe84fff,0x3ea005ff,0xfc83ffff, + 0x20007fff,0x7fffffd9,0x07ffffea,0x21bfffea,0x004fffff,0x03fffff0, + 0x7ffffc00,0x7fffc403,0xfffff32f,0x7fffe403,0x3fffff36,0x3ffffe60, + 0xfffff500,0xfffff101,0x1ffffee0,0xffffb800,0x7fffd40f,0x7fffdc0e, + 0x5ffffe84,0x3fffea00,0xffffc83f,0xffc80007,0xfff70fff,0x3fff20bf, + 0xffffe86f,0xfffd0007,0x7f40009f,0x7d406fff,0xff31ffff,0x7e403fff, + 0xfff36fff,0x3fe603ff,0xff500fff,0xff701fff,0x3fe609ff,0x70002fff, + 0x441fffff,0xb81fffff,0xfe84ffff,0x2e005fff,0xc81fffff,0x2807ffff, + 0x7ffffd40,0x09ffffb0,0x21bffffe,0x04fffffc,0xfffffc80,0xfff90001, + 0x7ff403ff,0x3ffe67ff,0x3ff201ff,0xffff36ff,0x3ffe603f,0xfff500ff, + 0xfffd01ff,0xdddddddf,0x00bfffff,0x3ffffee0,0x13ffffa0,0x427fffdc, + 0x005ffffe,0x03fffff2,0x01fffff2,0xe8815df7,0x3f27ffff,0x2e20ffff, + 0x887fffff,0x9effffff,0x3e21ae60,0x303fffff,0xffff10bb,0xffe885ff, + 0x3fe63fff,0x3f201fff,0xfff36fff,0x3fe603ff,0xff500fff,0xff981fff, + 0xffffffff,0xffffffff,0xfffb8000,0xffff70ff,0xb999999f,0x999dffff, + 0x017ffffa,0x07ffffd8,0x40fffff9,0xdefffff8,0x5ffffffe,0x3fffffea, + 0xffffffcd,0x7fd43eff,0xffffffff,0xffb82fff,0xeeefffff,0xfb82ffff, + 0xfeffffff,0x46ffffff,0x01fffff9,0x4dbffff2,0x301fffff,0x201fffff, + 0x40fffffa,0xfffffffc,0xffffffff,0xb8003fff,0xf90fffff,0xffffffff, + 0xffffffff,0x3fffafff,0xfff1005f,0x3fee0dff,0xff900fff,0xffffffff, + 0xfe81ffff,0xffffffff,0x5fffffdf,0xffffffd8,0x05ffffff,0xfffffffb, + 0x0dffffff,0x3ffffff6,0xffffffff,0x7ffffcc1,0x3ffff201,0x3fffff36, + 0x3ffffe60,0xfffff500,0xffffff81,0xffffffff,0x006fffff,0x0fffffb8, + 0xfffffff9,0xffffffff,0x3fafffff,0xf9005fff,0x2a07ffff,0x103fffff, + 0xfffffffb,0x305fffff,0xffffffff,0x3ffff69f,0xfffff705,0x1fffffff, + 0x3ffffee0,0x4fffffff,0x3ffffee0,0x0dffffff,0x1fffff98,0x5bffff20, + 0x01fffff9,0x01fffff3,0x83ffffea,0xaafffffa,0xdaaaaaaa,0x000fffff, + 0x87ffffdc,0xfffffffc,0xffffffff,0xffd7ffff,0xff500bff,0x7cc0dfff, + 0x1bcfffff,0xfffffd98,0x2200cfff,0x3efffffd,0x817fff62,0xffffffd8, + 0x6c400cff,0xffffffff,0xffd8800d,0x02efffff,0x07ffffe6,0x36ffffc8, + 0x203fffff,0x00fffff9,0x41fffff5,0x005ffffd,0x07fffff3,0xfffffb80, + 0x99999950,0xffb99999,0x3a999dff,0x2205ffff,0x2ffffffd,0x3ffffe20, + 0x2201ffff,0x0009aaa9,0x30026a62,0x554c4001,0x53100009,0x44000135, + 0x00001aa9,0x00000000,0xffff1000,0x7ffc007f,0x7dc006ff,0x0000ffff, + 0xd09ffff7,0x999dffff,0xfffffdb9,0xff900bff,0x03ffffff,0x00000000, + 0x00000000,0x00000000,0x00000000,0xff700000,0x64001fff,0x001fffff, + 0x03ffffee,0x7fffdc00,0xfffffe84,0xffffffff,0x000effff,0xfffffffd, + 0x00000003,0x00000000,0x00000000,0x00000000,0xd0000000,0x800dffff, + 0x04fffffa,0x3ffffee0,0xfff70000,0xffffd09f,0xffffffff,0x0007ffff, + 0x3fffffd5,0x00000000,0x00000000,0x00000000,0x00000000,0xf9800000, + 0x8003ffff,0x007fffff,0x03ffffee,0x7fffdc00,0xfffffe84,0xffffffff, + 0x880000df,0x00000019,0x00000000,0x00000000,0x00000000,0x00000000, + 0x03fffff9,0xfffffb00,0x3ffee005,0xf70000ff,0xffd09fff,0xdfffffff, + 0x00003579,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x30000000,0x44099999,0x910ccccc,0x00079999,0x00288540, + 0x33332e00,0xcccc9804,0x9999971c,0x66640000,0x999933cc,0x6664c059, + 0x999950cc,0x99999999,0x50019999,0x91005555,0xdb881599,0x33332005, + 0xdddd1004,0x3bba209d,0x3bbba604,0x7fffdc04,0x3fffe207,0xfffff11f, + 0xeb88000d,0x017df31f,0xffffb800,0x7ffe401f,0xffff70ff,0x2666203f, + 0xffff1009,0x7fffec7f,0xffffd00f,0x7ffffe4b,0xffffffff,0xfe801fff, + 0xff9806ff,0xfffd34ff,0x3ffea00f,0xff8802ff,0xff106fff,0x7ffd40bf, + 0x7ffdc06f,0x3ffe207f,0xffff11ff,0x322000df,0xff31ffff,0x200019ff, + 0x04fffff8,0x32fffff4,0x207fffff,0x506ffffb,0x443fffff,0xb85fffff, + 0x320effff,0xffffffff,0xffffffff,0x6fffe801,0x6ffff980,0x00fffffd, + 0x1bfffffa,0x3ffffe20,0x09fff026,0x02ffffcc,0x81ffffee,0x11fffff8, + 0x00dfffff,0xfffffda8,0xfffff31f,0xfb0005bf,0x7c40dfff,0x7f42ffff, + 0xffd04fff,0xff701fff,0xfff50dff,0x7ffc45ff,0x7ffe41ff,0xffffffff, + 0x801fffff,0x9806fffe,0xffbeffff,0xfa807fff,0x02ffffff,0x37ffffc4, + 0x4bffe1bd,0x3ffe63ea,0x7ffdc05f,0x3ffe207f,0xffff11ff,0xfd7100df, + 0x3fffffff,0x3fffffe6,0x5000beff,0x201fffff,0xc87ffffb,0xf886ffff, + 0xd83fffff,0xfb04ffff,0x7fe4dfff,0xccca84ff,0xfdcccccc,0x800effff, + 0x9806fffe,0xffffffff,0xfe806fff,0x06ffffff,0xafffffc4,0xffecfff9, + 0x3e66ffec,0x7dc05fff,0x3e207fff,0xff11ffff,0x6440dfff,0xffffffff, + 0x3ff623ef,0xffffffff,0xffff800c,0xffffb03f,0xfffff309,0xfffffa81, + 0xfffff85f,0xfffff101,0x0dffff37,0x7fffc400,0xffd000ef,0xfff300df, + 0x013dffff,0x3bfffea0,0x2202ffff,0xf94fffff,0xffffffff,0x3fe63fff, + 0x7fdc04ff,0x3fe207ff,0x2aaa1fff,0xffda82aa,0xcfffffff,0x3ffae201, + 0xdfffffff,0x3ffff201,0x1fffff05,0x07ffffe0,0xfffffff9,0x07ffff88, + 0x77ffffd4,0x0000ffff,0x1fffffd1,0x37fff400,0x7ffffcc0,0xffe8004f, + 0x6ffff8ff,0x73fff880,0xfffffffb,0x3e23bfff,0x7dc04fff,0x3e207fff, + 0x2001ffff,0xffffffeb,0x4000beff,0xffffffc9,0xf983efff,0xffa87fff, + 0x3ff606ff,0x7fffc3ff,0x3ea1ffff,0xfc804fff,0x3fffffff,0xfffd1000, + 0xfe8003ff,0xff9806ff,0x4000ffff,0xf94ffffa,0xf9805fff,0x7fd443ff, + 0xf881dfff,0x7dc04fff,0x3e207fff,0x3001ffff,0xffffffff,0x51000039, + 0xfffffffd,0xffffd03f,0x2ffffc85,0x97fffea0,0xffddfff9,0x3fffee3f, + 0xfffe8802,0x20005fff,0x01fffffd,0xfffffff9,0xffffffff,0x3ffe6bff, + 0xfe8004ff,0xfff30fff,0xfffb80df,0xfffffc82,0xffff881f,0x7fffdc03, + 0x3fffe207,0xfff3001f,0x00005bff,0x7fffe4c0,0xfffb81ff,0x7ffffc4f, + 0x3fffe200,0x2efffee7,0x3ff65fff,0x3fe6007f,0x0000ffff,0x05fffffb, + 0x7fffffe4,0xffffffff,0xfff35fff,0xfa8007ff,0x7ff45fff,0x3ff602ff, + 0x6fffdc0f,0xff80ffff,0x7fdc03ff,0x3fe207ff,0xf3001fff,0x017dffff, + 0x7ecc0000,0xf881ffff,0x3fe66fff,0xffd804ff,0x1fffb0ff,0x7fcffff1, + 0x3e6005ff,0x001fffff,0x2fffffc8,0x7ffffe40,0xffffffff,0xff35ffff, + 0xe8005fff,0x7dc2ffff,0xff106fff,0xffffb8bf,0x40efffb8,0x5c009999, + 0x2607ffff,0x001fffff,0xfffffff3,0x200005bf,0xfffffeb8,0xfffb01ff, + 0x3fffee3f,0xffffb801,0x7f4dfff2,0xffff89ff,0x3fffa003,0x2000efff, + 0x03fffffb,0xffffffc8,0xffffffff,0xfff35fff,0x7d4003ff,0xfff06fff, + 0xfff705ff,0x22fffd85,0x0002fffe,0x07ffffdc,0x1fffffb8,0x3fffee00, + 0x0cffffff,0xfffda800,0x0cffffff,0x27ffff50,0x1006fffe,0xff59ffff, + 0x67ffe49f,0x000ffffa,0xfffffff9,0x3fee009f,0x31004fff,0xffd33333, + 0x333333ff,0x3ffffe61,0x3fffa001,0xffff903f,0x5c1faa0d,0x0077cc6f, + 0x7fffd400,0xffffb01f,0xfd50003f,0xffffffff,0xffb8805b,0xefffffff, + 0xffff800b,0x03ffff8d,0x33bfffa0,0x3fea2fff,0x06fffcef,0xfdffff50, + 0xa805ffff,0x004fffff,0x0dfffd00,0x3fffff30,0x3fffea00,0xffff300f, + 0x3300405f,0x4c000050,0x883fffff,0x11ffffff,0x409ddddd,0xffffffd9, + 0x2a0cffff,0xfffffffd,0x64001dff,0xfffbffff,0x3ff2000f,0x447ffeff, + 0xfffeffff,0xffff8803,0xfffffb9f,0xfffff300,0x7f40000b,0xff9806ff, + 0xfd001fff,0xfd80bfff,0x00006fff,0x3e200000,0x221effff,0x1ffffffd, + 0x0dfffff1,0xfffff910,0x3e63ffff,0xffffffff,0xff10000c,0x0bffffff, + 0xfffff980,0xfffd85ff,0xd801ffff,0x3fa4ffff,0xff985fff,0x9999efff, + 0x00999999,0x806fffe8,0x01fffff9,0x1fffffa8,0x7ffffd40,0x00000001, + 0x3ffffa00,0xffffefff,0xff11ffff,0xa800dfff,0x1ffffffe,0xdffffff3, + 0x3f600007,0x02ffffff,0xffffff80,0xffffb83f,0xffb806ff,0x3fe60eff, + 0x7ff43fff,0xffffffff,0x02ffffff,0x806fffe8,0x01fffff9,0x01999988, + 0x01333330,0x00000000,0x7fffffd4,0xffedffff,0xffff11ff,0x366000df, + 0xff31ffff,0x00003bff,0xffffffa8,0xfff90007,0xff301fff,0x9809ffff, + 0xc82fffff,0x3a0fffff,0xffffffff,0xffffffff,0x6fffe802,0xfffff980, + 0x00000001,0x00000000,0xfffffd80,0xfffb5fff,0x3fffe23f,0x6440006f, + 0x19ff31ff,0x7fc00000,0x0004ffff,0x0dfffff5,0x0ffffffc,0x17ffffa0, + 0x37ffffc4,0xfffffffd,0xffffffff,0xfffd005f,0xffff300d,0x0000003f, + 0x00000000,0x3ffee000,0xfd30dfff,0x3ffe23ff,0x200006ff,0x0000710a, + 0x3ffff200,0xff10001f,0x7e409fff,0x7e407fff,0x2a00ffff,0xfd4fffff, + 0xffffffff,0x5fffffff,0x05555500,0x3fffff30,0x00000000,0x00000000, + 0x00554c40,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0xaaaaaa88,0xaaaaaaaa,0xddd30aaa, + 0x7777649d,0x0aaaaaa1,0x0b37b2a0,0x22bdddd0,0x515eeeee,0x55555555, + 0x3bba1555,0xeeeeeeee,0xeeeeeeee,0x00000001,0x00000000,0x00000000, + 0x00000000,0x3fe20000,0xffffffff,0x0fffffff,0x74dffff5,0x3ee2ffff, + 0xd102ffff,0x3dffffff,0x2dffff10,0x76fffff8,0xffffffff,0x3fe3ffff, + 0xffffffff,0xffffffff,0x0000002f,0x00000000,0x00000000,0x00000000, + 0x3e200000,0xffffffff,0xffffffff,0x4bffff30,0x6c1ffffd,0xfd06ffff, + 0xffffffff,0x5ffff989,0x2dfffff1,0xfffffffb,0xff1fffff,0xffffffff, + 0xffffffff,0x0000005f,0x00000000,0x00000000,0x00000000,0x7c400000, + 0xffffffff,0xffffffff,0x4bffff30,0x441ffffd,0x543fffff,0xffffffff, + 0xfebbefff,0xfff14fff,0x3ffeedff,0xffffffff,0xffffff1f,0xffffffff, + 0x005fffff,0x00000000,0x00000000,0x00000000,0x00000000,0x77777440, + 0xeeeeeeee,0xff30eeee,0x7ffecbff,0xffffa81f,0x7ffffe47,0xffffffcb, + 0x12ffffff,0x2edfffff,0xffffffff,0x1111ffff,0x11111111,0x11111111, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x24ffff98, + 0x900ffffc,0x7ec7ffff,0x3f621fff,0xffffffff,0x3ffffe26,0x22222226, + 0x00088888,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xfff88000,0x3ffff24f,0x3ffffa00,0x01ffffd0,0xffffffd5,0x0000003d, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xf8800000, + 0x3ff24fff,0x266200ff,0xddddb099,0x3deeca80,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0xfff10000,0x3fffe47f, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x88000000,0xeeeeeeee,0xeeeeeeee,0x8ffffe0e,0x0007fffb,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xfff10000, + 0xffffffff,0x41ffffff,0x26209999,0x00000199,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0xfffff100,0xffffffff, + 0x0001ffff,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x80000000,0xfffffff8,0xffffffff,0x000000ff,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x54400000, + 0xaaaaaaaa,0xaaaaaaaa,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, +}; + +static signed short stb__intelclearbd_x[95]={ 0,2,1,0,1,1,1,1,1,0,1,2,1,1, +1,0,0,2,2,1,1,1,1,1,1,1,1,1,2,2,2,0,1,0,3,2,3,3,3,2,3,3,0,3, +3,3,3,1,3,1,3,1,0,2,0,0,0,0,1,3,0,0,1,0,4,1,2,1,1,1,0,1,2,2, +-1,2,2,2,2,1,2,1,2,1,0,2,0,0,0,0,1,0,3,0,1, }; +static signed short stb__intelclearbd_y[95]={ 38,11,11,11,7,11,10,11,9,9,11,15,32,25, +32,9,11,11,11,11,11,11,11,11,11,11,18,18,15,18,15,10,11,11,11,10,11,11,11,10,11,11,11,11, +11,11,11,10,11,10,11,10,11,11,11,11,11,11,11,9,9,9,11,42,8,17,10,17,10,17,10,17,10,10, +10,10,10,17,17,17,17,17,18,17,13,18,18,18,18,18,18,9,9,9,21, }; +static unsigned short stb__intelclearbd_w[95]={ 0,7,14,23,21,35,26,6,12,11,14,19,7,14, +7,17,23,15,18,20,21,20,21,20,21,21,7,7,19,19,19,18,36,26,21,22,23,19,18,23,22,6,18,23, +18,27,23,28,20,28,22,21,24,24,26,38,26,25,22,11,17,11,21,20,11,19,21,18,21,19,14,21,19,7, +10,20,9,31,19,21,21,21,14,17,14,19,21,30,20,21,18,15,7,15,21, }; +static unsigned short stb__intelclearbd_h[95]={ 0,27,11,27,36,28,29,11,36,36,14,20,14,6, +6,36,28,27,27,28,27,28,28,27,28,28,20,28,20,14,20,28,36,27,27,29,27,27,27,29,27,27,28,27, +27,27,27,29,27,33,27,29,27,28,27,27,27,27,27,36,36,36,17,5,8,22,29,22,29,22,28,30,28,28, +37,28,29,21,21,22,30,30,20,22,26,21,20,20,20,29,20,36,38,36,8, }; +static unsigned short stb__intelclearbd_s[95]={ 255,248,41,145,36,163,219,242,74,87,227, +162,219,98,90,99,1,28,189,220,44,60,81,208,103,1,21,246,29,21,49, +144,117,1,229,150,66,169,103,173,122,241,125,79,233,51,27,67,212,196,166, +106,114,23,87,48,139,1,189,184,166,154,197,113,56,123,128,143,197,162,25, +225,40,247,9,199,96,224,204,182,23,1,182,105,90,1,69,91,122,45,143, +58,1,20,68, }; +static unsigned short stb__intelclearbd_t[95]={ 1,71,206,129,1,71,40,185,1,1,185, +185,185,206,206,1,71,157,129,71,157,71,71,129,71,100,185,40,185,206,185, +71,1,157,129,40,157,129,129,40,129,71,71,129,100,129,129,40,100,1,100, +40,100,100,100,100,100,129,100,1,1,1,185,206,206,157,40,157,40,157,71, +1,71,1,1,71,40,157,157,157,40,40,185,157,157,185,185,185,185,40,185, +1,1,1,206, }; +static unsigned short stb__intelclearbd_a[95]={ 151,180,256,368,368,597,422,136, +200,200,249,368,155,253,155,262,368,368,368,368,368,368,368,368, +368,368,155,155,368,368,368,300,609,413,393,393,439,367,346,433, +447,190,327,411,340,528,451,479,390,479,395,379,386,448,412,600, +406,391,378,222,262,222,368,310,310,330,385,305,385,344,219,352, +376,175,175,351,196,557,376,375,385,385,242,300,226,368,329,480, +319,329,311,242,213,242,368, }; + +// Call this function with +// font: NULL or array length +// data: NULL or specified size +// height: STB_FONT_intelclearbd_BITMAP_HEIGHT or STB_FONT_intelclearbd_BITMAP_HEIGHT_POW2 +// return value: spacing between lines +static void stb_font_intelclearbd(stb_fontchar font[STB_FONT_intelclearbd_NUM_CHARS], + unsigned char data[STB_FONT_intelclearbd_BITMAP_HEIGHT][STB_FONT_intelclearbd_BITMAP_WIDTH], + int height) +{ + int i,j; + if (data != 0) { + unsigned int *bits = stb__intelclearbd_pixels; + unsigned int bitpack = *bits++, numbits = 32; + for (i=0; i < STB_FONT_intelclearbd_BITMAP_WIDTH*height; ++i) + data[0][i] = 0; // zero entire bitmap + for (j=1; j < STB_FONT_intelclearbd_BITMAP_HEIGHT-1; ++j) { + for (i=1; i < STB_FONT_intelclearbd_BITMAP_WIDTH-1; ++i) { + unsigned int value; + if (numbits==0) bitpack = *bits++, numbits=32; + value = bitpack & 1; + bitpack >>= 1, --numbits; + if (value) { + if (numbits < 3) bitpack = *bits++, numbits = 32; + data[j][i] = (bitpack & 7) * 0x20 + 0x1f; + bitpack >>= 3, numbits -= 3; + } else { + data[j][i] = 0; + } + } + } + } + + // build font description + if (font != 0) { + float recip_width = 1.0f / STB_FONT_intelclearbd_BITMAP_WIDTH; + float recip_height = 1.0f / height; + for (i=0; i < STB_FONT_intelclearbd_NUM_CHARS; ++i) { + // pad characters so they bilerp from empty space around each character + font[i].s0 = (stb__intelclearbd_s[i]) * recip_width; + font[i].t0 = (stb__intelclearbd_t[i]) * recip_height; + font[i].s1 = (stb__intelclearbd_s[i] + stb__intelclearbd_w[i]) * recip_width; + font[i].t1 = (stb__intelclearbd_t[i] + stb__intelclearbd_h[i]) * recip_height; + font[i].x0 = stb__intelclearbd_x[i]; + font[i].y0 = stb__intelclearbd_y[i]; + font[i].x1 = stb__intelclearbd_x[i] + stb__intelclearbd_w[i]; + font[i].y1 = stb__intelclearbd_y[i] + stb__intelclearbd_h[i]; + font[i].advance_int = (stb__intelclearbd_a[i]+8)>>4; + font[i].s0f = (stb__intelclearbd_s[i] - 0.5f) * recip_width; + font[i].t0f = (stb__intelclearbd_t[i] - 0.5f) * recip_height; + font[i].s1f = (stb__intelclearbd_s[i] + stb__intelclearbd_w[i] + 0.5f) * recip_width; + font[i].t1f = (stb__intelclearbd_t[i] + stb__intelclearbd_h[i] + 0.5f) * recip_height; + font[i].x0f = stb__intelclearbd_x[i] - 0.5f; + font[i].y0f = stb__intelclearbd_y[i] - 0.5f; + font[i].x1f = stb__intelclearbd_x[i] + stb__intelclearbd_w[i] + 0.5f; + font[i].y1f = stb__intelclearbd_y[i] + stb__intelclearbd_h[i] + 0.5f; + font[i].advance = stb__intelclearbd_a[i]/16.0f; + } + } +} + +#ifndef STB_SOMEFONT_CREATE +#define STB_SOMEFONT_CREATE stb_font_intelclearbd +#define STB_SOMEFONT_BITMAP_WIDTH STB_FONT_intelclearbd_BITMAP_WIDTH +#define STB_SOMEFONT_BITMAP_HEIGHT STB_FONT_intelclearbd_BITMAP_HEIGHT +#define STB_SOMEFONT_BITMAP_HEIGHT_POW2 STB_FONT_intelclearbd_BITMAP_HEIGHT_POW2 +#define STB_SOMEFONT_FIRST_CHAR STB_FONT_intelclearbd_FIRST_CHAR +#define STB_SOMEFONT_NUM_CHARS STB_FONT_intelclearbd_NUM_CHARS +#define STB_SOMEFONT_LINE_SPACING STB_FONT_intelclearbd_LINE_SPACING +#endif + diff --git a/Projects/Asteroids/src/mesh.cpp b/Projects/Asteroids/src/mesh.cpp new file mode 100644 index 0000000..bef24b6 --- /dev/null +++ b/Projects/Asteroids/src/mesh.cpp @@ -0,0 +1,352 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#include "mesh.h" +#include "noise.h" +#include +#include + +using namespace DirectX; + +void CreateIcosahedron(Mesh *outMesh) +{ + static const float a = std::sqrt(2.0f / (5.0f - std::sqrt(5.0f))); + static const float b = std::sqrt(2.0f / (5.0f + std::sqrt(5.0f))); + + static const size_t num_vertices = 12; + static const Vertex vertices[num_vertices] = // x, y, z + { + {-b, a, 0}, + { b, a, 0}, + {-b, -a, 0}, + { b, -a, 0}, + { 0, -b, a}, + { 0, b, a}, + { 0, -b, -a}, + { 0, b, -a}, + { a, 0, -b}, + { a, 0, b}, + {-a, 0, -b}, + {-a, 0, b}, + }; + + static const size_t num_triangles = 20; + static const IndexType indices[num_triangles*3] = + { + 0, 5, 11, + 0, 1, 5, + 0, 7, 1, + 0, 10, 7, + 0, 11, 10, + 1, 9, 5, + 5, 4, 11, + 11, 2, 10, + 10, 6, 7, + 7, 8, 1, + 3, 4, 9, + 3, 2, 4, + 3, 6, 2, + 3, 8, 6, + 3, 9, 8, + 4, 5, 9, + 2, 11, 4, + 6, 10, 2, + 8, 7, 6, + 9, 1, 8, + }; + + outMesh->clear(); + outMesh->vertices.insert(outMesh->vertices.end(), vertices, vertices + num_vertices); + outMesh->indices.insert(outMesh->indices.end(), indices, indices + num_triangles*3); +} + + +// Maps edge (lower index first!) to +struct Edge +{ + Edge(IndexType i0, IndexType i1) + : v0(i0), v1(i1) + { + if (v0 > v1) + std::swap(v0, v1); + } + IndexType v0; + IndexType v1; + + bool operator<(const Edge &c) const + { + return v0 < c.v0 || (v0 == c.v0 && v1 < c.v1); + } +}; + +typedef std::map MidpointMap; + +inline IndexType EdgeMidpoint(Mesh *mesh, MidpointMap *midpoints, Edge e) +{ + auto index = midpoints->find(e); + if (index == midpoints->end()) + { + auto a = mesh->vertices[e.v0]; + auto b = mesh->vertices[e.v1]; + + Vertex m; + m.x = (a.x + b.x) * 0.5f; + m.y = (a.y + b.y) * 0.5f; + m.z = (a.z + b.z) * 0.5f; + + index = midpoints->insert(std::make_pair(e, static_cast(mesh->vertices.size()))).first; + mesh->vertices.push_back(m); + } + return index->second; +} + + +void SubdivideInPlace(Mesh *outMesh) +{ + MidpointMap midpoints; + + std::vector newIndices; + newIndices.reserve(outMesh->indices.size() * 4); + outMesh->vertices.reserve(outMesh->vertices.size() * 2); + + assert(outMesh->indices.size() % 3 == 0); // trilist + size_t triangles = outMesh->indices.size() / 3; + for (size_t t = 0; t < triangles; ++t) + { + auto t0 = outMesh->indices[t*3+0]; + auto t1 = outMesh->indices[t*3+1]; + auto t2 = outMesh->indices[t*3+2]; + + auto m0 = EdgeMidpoint(outMesh, &midpoints, Edge(t0, t1)); + auto m1 = EdgeMidpoint(outMesh, &midpoints, Edge(t1, t2)); + auto m2 = EdgeMidpoint(outMesh, &midpoints, Edge(t2, t0)); + + IndexType indices[] = { + t0, m0, m2, + m0, t1, m1, + m0, m1, m2, + m2, m1, t2, + }; + newIndices.insert(newIndices.end(), indices, indices + 4*3); + } + + std::swap(outMesh->indices, newIndices); // Constant time +} + + +void SpherifyInPlace(Mesh *outMesh, float radius) +{ + for (auto &v : outMesh->vertices) { + float n = radius / std::sqrt(v.x*v.x + v.y*v.y + v.z*v.z); + v.x *= n; + v.y *= n; + v.z *= n; + } +} + + +void ComputeAvgNormalsInPlace(Mesh *outMesh) +{ + for (auto &v : outMesh->vertices) { + v.nx = 0.0f; + v.ny = 0.0f; + v.nz = 0.0f; + } + + assert(outMesh->indices.size() % 3 == 0); // trilist + size_t triangles = outMesh->indices.size() / 3; + for (size_t t = 0; t < triangles; ++t) + { + auto v1 = &outMesh->vertices[outMesh->indices[t*3+0]]; + auto v2 = &outMesh->vertices[outMesh->indices[t*3+1]]; + auto v3 = &outMesh->vertices[outMesh->indices[t*3+2]]; + + // Two edge vectors u,v + auto ux = v2->x - v1->x; + auto uy = v2->y - v1->y; + auto uz = v2->z - v1->z; + auto vx = v3->x - v1->x; + auto vy = v3->y - v1->y; + auto vz = v3->z - v1->z; + + // cross(u,v) + float nx = uy*vz - uz*vy; + float ny = uz*vx - ux*vz; + float nz = ux*vy - uy*vx; + + // Do not normalize... weight average by contributing face area + v1->nx += nx; v1->ny += ny; v1->nz += nz; + v2->nx += nx; v2->ny += ny; v2->nz += nz; + v3->nx += nx; v3->ny += ny; v3->nz += nz; + } + + // Normalize + for (auto &v : outMesh->vertices) { + float n = 1.0f / std::sqrt(v.nx*v.nx + v.ny*v.ny + v.nz*v.nz); + v.nx *= n; + v.ny *= n; + v.nz *= n; + } +} + + +void CreateGeospheres(Mesh *outMesh, unsigned int subdivLevelCount, unsigned int* outSubdivIndexOffsets) +{ + CreateIcosahedron(outMesh); + outSubdivIndexOffsets[0] = 0; + + std::vector vertices(outMesh->vertices); + std::vector indices(outMesh->indices); + + for (unsigned int i = 0; i < subdivLevelCount; ++i) { + outSubdivIndexOffsets[i+1] = (unsigned int)indices.size(); + SubdivideInPlace(outMesh); + + // Ensure we add the proper offset to the indices from this subdiv level for the combined mesh + // This avoids also needing to track a base vertex index for each subdiv level + IndexType vertexOffset = (IndexType)vertices.size(); + vertices.insert(vertices.end(), outMesh->vertices.begin(), outMesh->vertices.end()); + + for (auto newIndex : outMesh->indices) { + indices.push_back(newIndex + vertexOffset); + } + } + outSubdivIndexOffsets[subdivLevelCount+1] = (unsigned int)indices.size(); + + SpherifyInPlace(outMesh); + + // Put the union of vertices/indices back into the mesh object + std::swap(outMesh->indices, indices); + std::swap(outMesh->vertices, vertices); +} + + +void CreateAsteroidsFromGeospheres(Mesh *outMesh, + unsigned int subdivLevelCount, unsigned int meshInstanceCount, + unsigned int rngSeed, + unsigned int* outSubdivIndexOffsets, unsigned int* vertexCountPerMesh) +{ + assert(subdivLevelCount <= meshInstanceCount); + + std::mt19937 rng(rngSeed); + + Mesh baseMesh; + CreateGeospheres(&baseMesh, subdivLevelCount, outSubdivIndexOffsets); + + // Per unique mesh + *vertexCountPerMesh = (unsigned int)baseMesh.vertices.size(); + std::vector vertices; + vertices.reserve(meshInstanceCount * baseMesh.vertices.size()); + // Reuse indices for the different unique meshes + + auto randomNoise = std::uniform_real_distribution(0.0f, 10000.0f); + auto randomPersistence = std::normal_distribution(0.95f, 0.04f); + float noiseScale = 0.5f; + float radiusScale = 0.9f; + float radiusBias = 0.3f; + + // Create and randomize unique vertices for each mesh instance + for (unsigned int m = 0; m < meshInstanceCount; ++m) { + Mesh newMesh(baseMesh); + NoiseOctaves<4> textureNoise(randomPersistence(rng)); + float noise = randomNoise(rng); + + for (auto &v : newMesh.vertices) { + float radius = textureNoise(v.x*noiseScale, v.y*noiseScale, v.z*noiseScale, noise); + radius = radius * radiusScale + radiusBias; + v.x *= radius; + v.y *= radius; + v.z *= radius; + } + ComputeAvgNormalsInPlace(&newMesh); + + vertices.insert(vertices.end(), newMesh.vertices.begin(), newMesh.vertices.end()); + } + + // Copy to output + std::swap(outMesh->indices, baseMesh.indices); + std::swap(outMesh->vertices, vertices); +} + + +void CreateSkyboxMesh(std::vector* outVertices) +{ + // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx + + // Cube mesh centered at zero + static const float c = 0.5f; + static const DirectX::XMFLOAT3 vertexPos[] = { // x, y, z + {-c, c, -c}, // 0 + { c, c, -c}, // 1 + { c, c, c}, // 2 + {-c, c, c}, // 3 + {-c, -c, c}, // 4 + { c, -c, c}, // 5 + { c, -c, -c}, // 6 + {-c, -c, -c}, // 7 + }; + + static const size_t numIndices = 6*6; + static const unsigned int indices[numIndices] = { + 2, 6, 1, 2, 5, 6, // right (+c, ., .), face 0 + 0, 4, 3, 0, 7, 4, // left (-c, ., .), face 1 + 0, 2, 1, 0, 3, 2, // top ( ., +c, .), face 2 + 4, 6, 5, 4, 7, 6, // bottom ( ., -c, .), face 3 + 3, 5, 2, 3, 4, 5, // back ( ., ., +c), face 4 + 1, 6, 7, 1, 7, 0, // front ( ., ., -c), face 5 + }; + + // Flatten out the indexed mesh and add the per-face parameters + std::vector vertices(numIndices); + for (size_t i = 0; i < numIndices; ++i) { + auto &v = vertices[i]; + + v.x = vertexPos[indices[i]].x; + v.y = vertexPos[indices[i]].y; + v.z = vertexPos[indices[i]].z; + + auto face = i / 6; + v.face = (float)face; + + // Face uv's are fairly manual + switch (face) + { + case 0: + v.u = -v.z; + v.v = -v.y; + break; + case 1: + v.u = v.z; + v.v = -v.y; + break; + case 2: + v.u = v.x; + v.v = v.z; + break; + case 3: + v.u = v.x; + v.v = -v.z; + break; + case 4: + v.u = v.x; + v.v = -v.y; + break; + case 5: + v.u = -v.x; + v.v = -v.y; + break; + }; + // Move to 0..1 + v.u += 0.5f; + v.v += 0.5f; + } + + std::swap(*outVertices, vertices); +} diff --git a/Projects/Asteroids/src/mesh.h b/Projects/Asteroids/src/mesh.h new file mode 100644 index 0000000..4031a7e --- /dev/null +++ b/Projects/Asteroids/src/mesh.h @@ -0,0 +1,74 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include +#include + +typedef unsigned short IndexType; + +// NOTE: This data could be compressed, but it's not really the bottleneck at the moment +struct Vertex +{ + float x; + float y; + float z; + float nx; + float ny; + float nz; +}; + +struct Mesh +{ + void clear() + { + vertices.clear(); + indices.clear(); + } + + std::vector vertices; + std::vector indices; +}; + +void CreateIcosahedron(Mesh *outMesh); + +// 1 face -> 4 faces +void SubdivideInPlace(Mesh *outMesh); + +void SpherifyInPlace(Mesh *outMesh, float radius = 1.0f); + +void ComputeAvgNormalsInPlace(Mesh *outMesh); + +// subdivIndexOffset array should be [subdivLevels+2] in size +void CreateGeospheres(Mesh *outMesh, unsigned int subdivLevelCount, unsigned int* outSubdivIndexOffsets); + +// Returns a combined "mesh" that includes: +// - A set of indices for each subdiv level (outSubdivIndexOffsets for offsets/counts) +// - A set of vertices for each mesh instance (base vertices per mesh computed from vertexCountPerMesh) +// - Indices already have the vertex offsets for the correct subdiv level "baked-in", so only need the mesh offset +void CreateAsteroidsFromGeospheres(Mesh *outMesh, + unsigned int subdivLevelCount, unsigned int meshInstanceCount, + unsigned int rngSeed, + unsigned int* outSubdivIndexOffsets, unsigned int* vertexCountPerMesh); + + +struct SkyboxVertex +{ + float x; + float y; + float z; + float u; + float v; + float face; +}; + +// Skybox mesh... vertices-only currently +void CreateSkyboxMesh(std::vector* outVertices); \ No newline at end of file diff --git a/Projects/Asteroids/src/noise.h b/Projects/Asteroids/src/noise.h new file mode 100644 index 0000000..250ae5c --- /dev/null +++ b/Projects/Asteroids/src/noise.h @@ -0,0 +1,57 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "simplexnoise1234.h" + +// Very simple multi-octave simplex noise helper +// Returns noise in the range [0, 1] vs. the usual [-1, 1] +template +class NoiseOctaves +{ +private: + float mWeights[N]; + float mWeightNorm; + +public: + NoiseOctaves(float persistence = 0.5f) + { + float weightSum = 0.0f; + for (size_t i = 0; i < N; ++i) { + mWeights[i] = persistence; + weightSum += persistence; + persistence *= persistence; + } + mWeightNorm = 0.5f / weightSum; // Will normalize to [-0.5, 0.5] + } + + // Returns [0, 1] + float operator()(float x, float y, float z) const + { + float r = 0.0f; + for (size_t i = 0; i < N; ++i) { + r += mWeights[i] * snoise3(x, y, z); + x *= 2.0f; y *= 2.0f; z *= 2.0f; + } + return r * mWeightNorm + 0.5f; + } + + // Returns [0, 1] + float operator()(float x, float y, float z, float w) const + { + float r = 0.0f; + for (size_t i = 0; i < N; ++i) { + r += mWeights[i] * snoise4(x, y, z, w); + x *= 2.0f; y *= 2.0f; z *= 2.0f; w *= 2.0f; + } + return r * mWeightNorm + 0.5f; + } +}; \ No newline at end of file diff --git a/Projects/Asteroids/src/settings.h b/Projects/Asteroids/src/settings.h new file mode 100644 index 0000000..d130eca --- /dev/null +++ b/Projects/Asteroids/src/settings.h @@ -0,0 +1,92 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "camera.h" +#include "common_defines.h" + +// Profiling +#define ENABLE_VTUNE_TASK_PROFILING 1 + +// Content settings +#ifdef _DEBUG +enum { NUM_ASTEROIDS = 2000 }; +#else +enum { NUM_ASTEROIDS = 50000 }; +#endif +enum { TEXTURE_DIM = 256 }; // Req'd to be pow2 at the moment +enum { TEXTURE_ANISO = 2 }; +enum { NUM_UNIQUE_MESHES = 1000 }; +enum { MESH_MAX_SUBDIV_LEVELS = 3 }; // 4x polys for each step. +// See common_defines.h for NUM_UNIQUE_TEXTURES (also needed by shader now) + +#define SIM_ORBIT_RADIUS 450.f +#define SIM_DISC_RADIUS 120.f +#define SIM_MIN_SCALE 0.2f + +// In FLIP swap chains the compositor owns one of your buffers at any given point +// Thus to run unconstrained (>vsync) frame rates, you need 3 buffers +enum { NUM_SWAP_CHAIN_BUFFERS = 5 }; + +// In D3D12, this is the pipeline depth in frames - larger = more latency, shorter = potential bubbles. +// Usually 2-4 are good values. +enum { NUM_FRAMES_TO_BUFFER = 3 }; + +// In D3D12 this is the number of command buffers we generate for the main scene rendering +// Also effectively max thread parallelism +enum { NUM_SUBSETS = 4 }; + +// Buffer size for dynamic sprite data +enum { MAX_SPRITE_VERTICES_PER_FRAME = 6 * 1024 }; + + +// This structure is often copied/passed by value so don't put anything really expensive in it. +struct Settings +{ + double closeAfterSeconds = 0.0; + + // Will be scaled based on DPI at app start for convenience + double renderScale = 1.0; // 1.0 = window dimensions, <1 = upscaling, >1 = supersampling + int windowWidth = 1080; + int windowHeight = 720; + int renderWidth; + int renderHeight; + + int numThreads = 0; // 0 means #cpu-1 + unsigned int lockedFrameRate = 15; + + bool logFrameTimes = false; + bool vsync = 0; + + bool windowed = true; + enum RenderMode + { + NativeD3D11, + NativeD3D12, + DiligentD3D11, + DiligentD3D12, + DiligentGL + }mode = DiligentD3D11; + + bool lockFrameRate = false; + bool animate = true; + + // Multithreading actually makes debugging annoying so disable by default +#if defined(_DEBUG) + bool multithreadedRendering = true; +#else + bool multithreadedRendering = true; +#endif + + bool submitRendering = true; + bool executeIndirect = false; + bool warp = false; +}; diff --git a/Projects/Asteroids/src/simplexnoise1234.c b/Projects/Asteroids/src/simplexnoise1234.c new file mode 100644 index 0000000..a0f0814 --- /dev/null +++ b/Projects/Asteroids/src/simplexnoise1234.c @@ -0,0 +1,499 @@ +/* SimplexNoise1234, Simplex noise with true analytic + * derivative in 1D to 4D. + * + * Author: Stefan Gustavson, 2003-2005 + * Contact: stegu@itn.liu.se + */ + + /* +This code was GPL licensed until February 2011. +As the original author of this code, I hereby +release it irrevocably into the public domain. +Please feel free to use it for whatever you want. +Credit is appreciated where appropriate, and I also +appreciate being told where this code finds any use, +but you may do as you like. Alternatively, if you want +to have a familiar OSI-approved license, you may use +This code under the terms of the MIT license: + +Copyright (C) 2003-2005 by Stefan Gustavson. All rights reserved. +This code is licensed to you under the terms of the MIT license: + +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. +*/ + +/** \file + \brief C implementation of Perlin Simplex Noise over 1,2,3, and 4 dimensions. + \author Stefan Gustavson (stegu@itn.liu.se) +*/ + +/* + * This implementation is "Simplex Noise" as presented by + * Ken Perlin at a relatively obscure and not often cited course + * session "Real-Time Shading" at Siggraph 2001 (before real + * time shading actually took on), under the title "hardware noise". + * The 3D function is numerically equivalent to his Java reference + * code available in the PDF course notes, although I re-implemented + * it from scratch to get more readable code. The 1D, 2D and 4D cases + * were implemented from scratch by me from Ken Perlin's text. + * + * This file has no dependencies on any other file, not even its own + * header file. The header file is made for use by external code only. + */ + + +// We don't need to include this. It does no harm, but no use either. +#include "simplexnoise1234.h" + +#pragma warning(disable: 4244) // conversion double -> float + +#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) ) + +//--------------------------------------------------------------------- +// Static data + +/* + * Permutation table. This is just a random jumble of all numbers 0-255, + * repeated twice to avoid wrapping the index at 255 for each lookup. + * This needs to be exactly the same for all instances on all platforms, + * so it's easiest to just keep it as static explicit data. + * This also removes the need for any initialisation of this class. + * + * Note that making this an int[] instead of a char[] might make the + * code run faster on platforms with a high penalty for unaligned single + * byte addressing. Intel x86 is generally single-byte-friendly, but + * some other CPUs are faster with 4-aligned reads. + * However, a char[] is smaller, which avoids cache trashing, and that + * is probably the most important aspect on most architectures. + * This array is accessed a *lot* by the noise functions. + * A vector-valued noise over 3D accesses it 96 times, and a + * float-valued 4D noise 64 times. We want this to fit in the cache! + */ +unsigned char perm[512] = {151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 +}; + +//--------------------------------------------------------------------- + +/* + * Helper functions to compute gradients-dot-residualvectors (1D to 4D) + * Note that these generate gradients of more than unit length. To make + * a close match with the value range of classic Perlin noise, the final + * noise values need to be rescaled to fit nicely within [-1,1]. + * (The simplex noise functions as such also have different scaling.) + * Note also that these noise functions are the most practical and useful + * signed version of Perlin noise. To return values according to the + * RenderMan specification from the SL noise() and pnoise() functions, + * the noise values need to be scaled and offset to [0,1], like this: + * float SLnoise = (noise(x,y,z) + 1.0) * 0.5; + */ + +float grad1( int hash, float x ) { + int h = hash & 15; + float grad = 1.0f + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0 + if (h&8) grad = -grad; // Set a random sign for the gradient + return ( grad * x ); // Multiply the gradient with the distance +} + +float grad2( int hash, float x, float y ) { + int h = hash & 7; // Convert low 3 bits of hash code + float u = h<4 ? x : y; // into 8 simple gradient directions, + float v = h<4 ? y : x; // and compute the dot product with (x,y). + return ((h&1)? -u : u) + ((h&2)? -2.0f*v : 2.0f*v); +} + +float grad3( int hash, float x, float y , float z ) { + int h = hash & 15; // Convert low 4 bits of hash code into 12 simple + float u = h<8 ? x : y; // gradient directions, and compute dot product. + float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15 + return ((h&1)? -u : u) + ((h&2)? -v : v); +} + +float grad4( int hash, float x, float y, float z, float t ) { + int h = hash & 31; // Convert low 5 bits of hash code into 32 simple + float u = h<24 ? x : y; // gradient directions, and compute dot product. + float v = h<16 ? y : z; + float w = h<8 ? z : t; + return ((h&1)? -u : u) + ((h&2)? -v : v) + ((h&4)? -w : w); +} + + // A lookup table to traverse the simplex around a given point in 4D. + // Details can be found where this table is used, in the 4D noise method. + /* TODO: This should not be required, backport it from Bill's GLSL code! */ + static unsigned char simplex[64][4] = { + {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, + {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, + {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, + {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0}}; + +// 1D simplex noise +float snoise1(float x) { + + int i0 = FASTFLOOR(x); + int i1 = i0 + 1; + float x0 = x - i0; + float x1 = x0 - 1.0f; + + float n0, n1; + + float t0 = 1.0f - x0*x0; +// if(t0 < 0.0f) t0 = 0.0f; // this never happens for the 1D case + t0 *= t0; + n0 = t0 * t0 * grad1(perm[i0 & 0xff], x0); + + float t1 = 1.0f - x1*x1; +// if(t1 < 0.0f) t1 = 0.0f; // this never happens for the 1D case + t1 *= t1; + n1 = t1 * t1 * grad1(perm[i1 & 0xff], x1); + // The maximum value of this noise is 8*(3/4)^4 = 2.53125 + // A factor of 0.395 would scale to fit exactly within [-1,1], but + // we want to match PRMan's 1D noise, so we scale it down some more. + return 0.25f * (n0 + n1); + +} + +// 2D simplex noise +float snoise2(float x, float y) { + +#define F2 0.366025403 // F2 = 0.5*(sqrt(3.0)-1.0) +#define G2 0.211324865 // G2 = (3.0-Math.sqrt(3.0))/6.0 + + float n0, n1, n2; // Noise contributions from the three corners + + // Skew the input space to determine which simplex cell we're in + float s = (x+y)*F2; // Hairy factor for 2D + float xs = x + s; + float ys = y + s; + int i = FASTFLOOR(xs); + int j = FASTFLOOR(ys); + + float t = (float)(i+j)*G2; + float X0 = i-t; // Unskew the cell origin back to (x,y) space + float Y0 = j-t; + float x0 = x-X0; // The x,y distances from the cell origin + float y0 = y-Y0; + + // For the 2D case, the simplex shape is an equilateral triangle. + // Determine which simplex we are in. + int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords + if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) + else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1) + + // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and + // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where + // c = (3-sqrt(3))/6 + + float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords + float y1 = y0 - j1 + G2; + float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords + float y2 = y0 - 1.0f + 2.0f * G2; + + // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds + int ii = i & 0xff; + int jj = j & 0xff; + + // Calculate the contribution from the three corners + float t0 = 0.5f - x0*x0-y0*y0; + if(t0 < 0.0f) n0 = 0.0f; + else { + t0 *= t0; + n0 = t0 * t0 * grad2(perm[ii+perm[jj]], x0, y0); + } + + float t1 = 0.5f - x1*x1-y1*y1; + if(t1 < 0.0f) n1 = 0.0f; + else { + t1 *= t1; + n1 = t1 * t1 * grad2(perm[ii+i1+perm[jj+j1]], x1, y1); + } + + float t2 = 0.5f - x2*x2-y2*y2; + if(t2 < 0.0f) n2 = 0.0f; + else { + t2 *= t2; + n2 = t2 * t2 * grad2(perm[ii+1+perm[jj+1]], x2, y2); + } + + // Add contributions from each corner to get the final noise value. + // The result is scaled to return values in the interval [-1,1]. + return 40.0f * (n0 + n1 + n2); // TODO: The scale factor is preliminary! + } + +// 3D simplex noise +float snoise3(float x, float y, float z) { + +// Simple skewing factors for the 3D case +#define F3 0.333333333 +#define G3 0.166666667 + + float n0, n1, n2, n3; // Noise contributions from the four corners + + // Skew the input space to determine which simplex cell we're in + float s = (x+y+z)*F3; // Very nice and simple skew factor for 3D + float xs = x+s; + float ys = y+s; + float zs = z+s; + int i = FASTFLOOR(xs); + int j = FASTFLOOR(ys); + int k = FASTFLOOR(zs); + + float t = (float)(i+j+k)*G3; + float X0 = i-t; // Unskew the cell origin back to (x,y,z) space + float Y0 = j-t; + float Z0 = k-t; + float x0 = x-X0; // The x,y,z distances from the cell origin + float y0 = y-Y0; + float z0 = z-Z0; + + // For the 3D case, the simplex shape is a slightly irregular tetrahedron. + // Determine which simplex we are in. + int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords + int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords + +/* This code would benefit from a backport from the GLSL version! */ + if(x0>=y0) { + if(y0>=z0) + { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order + else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order + else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order + } + else { // x0 y0) ? 32 : 0; + int c2 = (x0 > z0) ? 16 : 0; + int c3 = (y0 > z0) ? 8 : 0; + int c4 = (x0 > w0) ? 4 : 0; + int c5 = (y0 > w0) ? 2 : 0; + int c6 = (z0 > w0) ? 1 : 0; + int c = c1 + c2 + c3 + c4 + c5 + c6; + + int i1, j1, k1, l1; // The integer offsets for the second simplex corner + int i2, j2, k2, l2; // The integer offsets for the third simplex corner + int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner + + // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. + // Many values of c will never occur, since e.g. x>y>z>w makes x=3 ? 1 : 0; + j1 = simplex[c][1]>=3 ? 1 : 0; + k1 = simplex[c][2]>=3 ? 1 : 0; + l1 = simplex[c][3]>=3 ? 1 : 0; + // The number 2 in the "simplex" array is at the second largest coordinate. + i2 = simplex[c][0]>=2 ? 1 : 0; + j2 = simplex[c][1]>=2 ? 1 : 0; + k2 = simplex[c][2]>=2 ? 1 : 0; + l2 = simplex[c][3]>=2 ? 1 : 0; + // The number 1 in the "simplex" array is at the second smallest coordinate. + i3 = simplex[c][0]>=1 ? 1 : 0; + j3 = simplex[c][1]>=1 ? 1 : 0; + k3 = simplex[c][2]>=1 ? 1 : 0; + l3 = simplex[c][3]>=1 ? 1 : 0; + // The fifth corner has all coordinate offsets = 1, so no need to look that up. + + float x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords + float y1 = y0 - j1 + G4; + float z1 = z0 - k1 + G4; + float w1 = w0 - l1 + G4; + float x2 = x0 - i2 + 2.0f*G4; // Offsets for third corner in (x,y,z,w) coords + float y2 = y0 - j2 + 2.0f*G4; + float z2 = z0 - k2 + 2.0f*G4; + float w2 = w0 - l2 + 2.0f*G4; + float x3 = x0 - i3 + 3.0f*G4; // Offsets for fourth corner in (x,y,z,w) coords + float y3 = y0 - j3 + 3.0f*G4; + float z3 = z0 - k3 + 3.0f*G4; + float w3 = w0 - l3 + 3.0f*G4; + float x4 = x0 - 1.0f + 4.0f*G4; // Offsets for last corner in (x,y,z,w) coords + float y4 = y0 - 1.0f + 4.0f*G4; + float z4 = z0 - 1.0f + 4.0f*G4; + float w4 = w0 - 1.0f + 4.0f*G4; + + // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds + int ii = i & 0xff; + int jj = j & 0xff; + int kk = k & 0xff; + int ll = l & 0xff; + + // Calculate the contribution from the five corners + float t0 = 0.6f - x0*x0 - y0*y0 - z0*z0 - w0*w0; + if(t0 < 0.0f) n0 = 0.0f; + else { + t0 *= t0; + n0 = t0 * t0 * grad4(perm[ii+perm[jj+perm[kk+perm[ll]]]], x0, y0, z0, w0); + } + + float t1 = 0.6f - x1*x1 - y1*y1 - z1*z1 - w1*w1; + if(t1 < 0.0f) n1 = 0.0f; + else { + t1 *= t1; + n1 = t1 * t1 * grad4(perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]], x1, y1, z1, w1); + } + + float t2 = 0.6f - x2*x2 - y2*y2 - z2*z2 - w2*w2; + if(t2 < 0.0f) n2 = 0.0f; + else { + t2 *= t2; + n2 = t2 * t2 * grad4(perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]], x2, y2, z2, w2); + } + + float t3 = 0.6f - x3*x3 - y3*y3 - z3*z3 - w3*w3; + if(t3 < 0.0f) n3 = 0.0f; + else { + t3 *= t3; + n3 = t3 * t3 * grad4(perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]], x3, y3, z3, w3); + } + + float t4 = 0.6f - x4*x4 - y4*y4 - z4*z4 - w4*w4; + if(t4 < 0.0f) n4 = 0.0f; + else { + t4 *= t4; + n4 = t4 * t4 * grad4(perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]], x4, y4, z4, w4); + } + + // Sum up and scale the result to cover the range [-1,1] + return 27.0f * (n0 + n1 + n2 + n3 + n4); // TODO: The scale factor is preliminary! + } +//--------------------------------------------------------------------- diff --git a/Projects/Asteroids/src/simplexnoise1234.h b/Projects/Asteroids/src/simplexnoise1234.h new file mode 100644 index 0000000..18c42f9 --- /dev/null +++ b/Projects/Asteroids/src/simplexnoise1234.h @@ -0,0 +1,70 @@ +/* SimplexNoise1234, Simplex noise with true analytic + * derivative in 1D to 4D. + * + * Author: Stefan Gustavson, 2003-2005 + * Contact: stegu@itn.liu.se + */ + +/* +This code was GPL licensed until February 2011. +As the original author of this code, I hereby +release it irrevocably into the public domain. +Please feel free to use it for whatever you want. +Credit is appreciated where appropriate, and I also +appreciate being told where this code finds any use, +but you may do as you like. Alternatively, if you want +to have a familiar OSI-approved license, you may use +This code under the terms of the MIT license: + +Copyright (C) 2003-2005 by Stefan Gustavson. All rights reserved. +This code is licensed to you under the terms of the MIT license: + +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. +*/ + +/** \file + \brief Header for "simplexnoise1234.c" for producing Perlin simplex noise. + \author Stefan Gustavson (stegu@itn.liu.se) +*/ + +/* + * This is a clean, fast, modern and free Perlin Simplex noise function. + * It is a stand-alone compilation unit with no external dependencies, + * highly reusable without source code modifications. + * + * + * Note: + * Replacing the "float" type with "double" can actually make this run faster + * on some platforms. Having both versions could be useful. + */ + +/** 1D, 2D, 3D and 4D float Perlin simplex noise + */ +#ifdef __cplusplus +extern "C" { +#endif + + float snoise1( float x ); + float snoise2( float x, float y ); + float snoise3( float x, float y, float z ); + float snoise4( float x, float y, float z, float w ); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Projects/Asteroids/src/simulation.cpp b/Projects/Asteroids/src/simulation.cpp new file mode 100644 index 0000000..74e9019 --- /dev/null +++ b/Projects/Asteroids/src/simulation.cpp @@ -0,0 +1,250 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#include "simulation.h" +#include "settings.h" +#include "texture.h" +#include "util.h" + +#include +#include +#include +#include +#include + +using namespace DirectX; + +static int const COLOR_SCHEMES[] = { + 156, 139, 113, 55, 49, 40, + 156, 139, 113, 58, 38, 14, + 156, 139, 113, 98, 101, 104, + 156, 139, 113, 205, 197, 178, + 153, 146, 136, 88, 88, 88, + 189, 181, 164, 148, 108, 102, +}; + +static int const NUM_COLOR_SCHEMES = (int) (sizeof(COLOR_SCHEMES) / (6 * sizeof(int))); + +static XMVECTOR RandomPointOnSphere(std::mt19937& rng) +{ + std::normal_distribution dist; + + XMVECTOR r; + for (;;) { + r = XMVectorSet(dist(rng), dist(rng), dist(rng), 0.0f); + auto d2 = XMVectorGetX(XMVector3LengthSq(r)); + if (d2 > std::numeric_limits::min()) { + return XMVector3Normalize(r); + } + } + // Unreachable +} + +// From http://guihaire.com/code/?p=1135 +static inline float VeryApproxLog2f(float x) +{ + union { float f; uint32_t i; } ux; + ux.f = x; + return (float)ux.i * 1.1920928955078125e-7f - 126.94269504f; +} + + +AsteroidsSimulation::AsteroidsSimulation(unsigned int rngSeed, unsigned int asteroidCount, + unsigned int meshInstanceCount, unsigned int subdivCount, + unsigned int textureCount) + : mAsteroidStatic(asteroidCount) + , mAsteroidDynamic(asteroidCount) + , mIndexOffsets(subdivCount + 2) // Mesh subdivs are inclusive on both ends and need forward differencing for count + , mSubdivCount(subdivCount) +{ + std::mt19937 rng(rngSeed); + + // Create meshes + std::cout + << "Creating " << meshInstanceCount << " meshes, each with " + << subdivCount << " subdivision levels..." << std::endl; + + CreateAsteroidsFromGeospheres(&mMeshes, mSubdivCount, meshInstanceCount, + rng(), mIndexOffsets.data(), &mVertexCountPerMesh); + + CreateTextures(textureCount, rng()); + + // Constants + std::normal_distribution orbitRadiusDist(SIM_ORBIT_RADIUS, 0.6f * SIM_DISC_RADIUS); + std::normal_distribution heightDist(0.0f, 0.4f); + std::uniform_real_distribution angleDist(-XM_PI, XM_PI); + std::uniform_real_distribution radialVelocityDist(5.0f, 15.0f); + std::uniform_real_distribution spinVelocityDist(-2.0f, 2.0f); + std::normal_distribution scaleDist(1.3f, 0.7f); + std::normal_distribution colorSchemeDist(0, NUM_COLOR_SCHEMES - 1); + std::uniform_int_distribution textureIndexDist(0, textureCount-1); + + auto instancesPerMesh = std::max(1U, asteroidCount / meshInstanceCount); + + // Approximate SRGB->Linear for colors + float linearColorSchemes[NUM_COLOR_SCHEMES * 6]; + for (int i = 0; i < ARRAYSIZE(linearColorSchemes); ++i) { + linearColorSchemes[i] = std::powf((float)COLOR_SCHEMES[i] / 255.0f, 2.2f); + } + + // Create a torus of asteroids that spin around the ring + for (unsigned int i = 0; i < asteroidCount; ++i) { + auto scale = scaleDist(rng); +#if SIM_USE_GAMMA_DIST_SCALE + scale = scale * 0.3f; +#endif + scale = std::max(scale, SIM_MIN_SCALE); + auto scaleMatrix = XMMatrixScaling(scale, scale, scale); + + auto orbitRadius = orbitRadiusDist(rng); + auto discPosY = float(SIM_DISC_RADIUS) * heightDist(rng); + + auto disc = XMMatrixTranslation(orbitRadius, discPosY, 0.0f); + + auto positionAngle = angleDist(rng); + auto orbit = XMMatrixRotationY(positionAngle); + + auto meshInstance = (unsigned int)(i / instancesPerMesh); // Vcache friendly ordering + + // Static data + mAsteroidStatic[i].spinVelocity = spinVelocityDist(rng) / scale; // Smaller asteroids spin faster + mAsteroidStatic[i].orbitVelocity = radialVelocityDist(rng) / (scale * orbitRadius); // Smaller asteroids go faster, and use arc length + mAsteroidStatic[i].vertexStart = mVertexCountPerMesh * meshInstance; + mAsteroidStatic[i].spinAxis = XMVector3Normalize(RandomPointOnSphere(rng)); + mAsteroidStatic[i].scale = scale; + mAsteroidStatic[i].textureIndex = textureIndexDist(rng); + + auto colorScheme = ((int)abs(colorSchemeDist(rng))) % NUM_COLOR_SCHEMES; + auto c = linearColorSchemes + 6 * colorScheme; + mAsteroidStatic[i].surfaceColor = XMFLOAT3(c[0], c[1], c[2]); + mAsteroidStatic[i].deepColor = XMFLOAT3(c[3], c[4], c[5]); + + // Initialize dynamic data + mAsteroidDynamic[i].world = scaleMatrix * disc * orbit; + + assert(mAsteroidStatic[i].scale > 0.0f); + assert(mAsteroidStatic[i].orbitVelocity > 0.0f); + } +} + + +void AsteroidsSimulation::Update(float frameTime, DirectX::XMVECTOR cameraEye, const Settings& settings, + size_t startIndex, size_t count) +{ + bool animate = settings.animate; + + // TODO: This constant should really depend on resolution and/or be configurable... + static const float minSubdivSizeLog2 = std::log2f(0.0019f); + + size_t last = count ? startIndex + count : mAsteroidDynamic.size(); + for (size_t i = startIndex; i < last; ++i) { + const AsteroidStatic& staticData = mAsteroidStatic[i]; + AsteroidDynamic& dynamicData = mAsteroidDynamic[i]; + + if (animate) { + auto orbit = XMMatrixRotationY(staticData.orbitVelocity * frameTime); + auto spin = XMMatrixRotationNormal(staticData.spinAxis, staticData.spinVelocity * frameTime); + dynamicData.world = spin * dynamicData.world * orbit; + } + + // Pick LOD based on approx screen area - can be very approximate + auto position = dynamicData.world.r[3]; + auto distanceToEyeRcp = XMVectorGetX(XMVector3ReciprocalLengthEst(XMVectorSubtract(cameraEye, position))); + // Add one subdiv for each factor of 2 past min + auto relativeScreenSizeLog2 = VeryApproxLog2f(staticData.scale * distanceToEyeRcp); + float subdivFloat = std::max(0.0f, relativeScreenSizeLog2 - minSubdivSizeLog2); + auto subdiv = std::min(mSubdivCount, (unsigned int)subdivFloat); + + // TODO: Ignore/cull/force lowest subdiv if offscreen? + + dynamicData.indexStart = mIndexOffsets[subdiv]; + dynamicData.indexCount = mIndexOffsets[subdiv+1] - dynamicData.indexStart; + } +} + + +void AsteroidsSimulation::CreateTextures(unsigned int textureCount, unsigned int rngSeed) +{ + mTextureDim = TEXTURE_DIM; + mTextureCount = textureCount; + mTextureArraySize = 3; + { + DWORD msbIndex = 0; + auto result = _BitScanReverse(&msbIndex, mTextureDim); + assert(result); // Should only fail if mTextureDim = 0 + mTextureMipLevels = msbIndex + 1; + } + + assert((mTextureDim & (mTextureDim-1)) == 0); // Must be pow2 currently; we don't handle wacky mip chains + + std::cout + << "Creating " << textureCount << " " + << mTextureDim << "x" << mTextureDim << " textures..." << std::endl; + + // Allocate space + UINT texelSizeInBytes = 4; // RGBA8 + UINT extraSpaceForMips = 2; + UINT totalTextureSizeInBytes = texelSizeInBytes * mTextureDim * mTextureDim * mTextureArraySize * extraSpaceForMips; + totalTextureSizeInBytes = Align(totalTextureSizeInBytes, 64U); // Avoid false sharing + + mTextureDataBuffer.resize(totalTextureSizeInBytes * textureCount); + mTextureSubresources.resize(mTextureArraySize * mTextureMipLevels * textureCount); + + // Parallel over textures + std::vector rngSeeds(textureCount); + { + std::mt19937 seeds; + for (auto &i : rngSeeds) i = seeds(); + } + + concurrency::parallel_for(UINT(0), textureCount, [&](UINT t) { + std::mt19937 rng(rngSeeds[t]); + auto randomNoise = std::uniform_real_distribution(0.0f, 10000.0f); + auto randomNoiseScale = std::uniform_real_distribution(100, 150); + auto randomPersistence = std::normal_distribution(0.9f, 0.2f); + + BYTE* data = mTextureDataBuffer.data() + t * totalTextureSizeInBytes; + for (UINT a = 0; a < mTextureArraySize; ++a) { + for (UINT m = 0; m < mTextureMipLevels; ++m) { + auto width = mTextureDim >> m; + auto height = mTextureDim >> m; + + D3D11_SUBRESOURCE_DATA initialData = {}; + initialData.pSysMem = data; + initialData.SysMemPitch = width * texelSizeInBytes; + mTextureSubresources[SubresourceIndex(t, a, m)] = initialData; + + data += initialData.SysMemPitch * height; + } + } + + // Use same parameters for each of the tri-planar projection planes/cube map faces/etc. + float noiseScale = randomNoiseScale(rng) / float(mTextureDim); + float persistence = randomPersistence(rng); + float strength = 1.5f; + + for (UINT a = 0; a < mTextureArraySize; ++a) { + float redScale = 255.0f; + float greenScale = 255.0f; + float blueScale = 255.0f; + + // DEBUG colors +#if 0 + redScale = t & 1 ? 255.0f : 0.0f; + greenScale = t & 2 ? 255.0f : 0.0f; + blueScale = t & 4 ? 255.0f : 0.0f; +#endif + + FillNoise2D_RGBA8(&mTextureSubresources[SubresourceIndex(t, a)], mTextureDim, mTextureDim, mTextureMipLevels, + randomNoise(rng), persistence, noiseScale, strength, + redScale, greenScale, blueScale); + } + }); // parallel_for +} diff --git a/Projects/Asteroids/src/simulation.h b/Projects/Asteroids/src/simulation.h new file mode 100644 index 0000000..c14270d --- /dev/null +++ b/Projects/Asteroids/src/simulation.h @@ -0,0 +1,90 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include // For D3D11_SUBRESOURCE_DATA +#include +#include +#include +#include + +#include "mesh.h" +#include "settings.h" + +// We may want to ISPC-ify this down the road and just let it own the data structure in AoSoA format or similar +// For now we'll just do the dumb thing and see if it's fast enough +struct AsteroidDynamic +{ + DirectX::XMMATRIX world; + // These depend on chosen subdiv level, hence are not constant + unsigned int indexStart; + unsigned int indexCount; +}; + +struct AsteroidStatic +{ + DirectX::XMFLOAT3 surfaceColor; + DirectX::XMFLOAT3 deepColor; + DirectX::XMVECTOR spinAxis; + float scale; + float spinVelocity; + float orbitVelocity; + unsigned int vertexStart; + unsigned int textureIndex; +}; + +class AsteroidsSimulation +{ +private: + // NOTE: Memory could be optimized further for efficient cache traversal, etc. + std::vector mAsteroidStatic; + std::vector mAsteroidDynamic; + + Mesh mMeshes; + std::vector mIndexOffsets; + unsigned int mSubdivCount; + unsigned int mVertexCountPerMesh; + + unsigned int mTextureDim; + unsigned int mTextureCount; + unsigned int mTextureArraySize; + unsigned int mTextureMipLevels; + std::vector mTextureDataBuffer; + std::vector mTextureSubresources; + + unsigned int SubresourceIndex(unsigned int texture, unsigned int arrayElement = 0, unsigned int mip = 0) + { + return mip + mTextureMipLevels * (arrayElement + mTextureArraySize * texture); + } + + void CreateTextures(unsigned int textureCount, unsigned int rngSeed); + +public: + AsteroidsSimulation(unsigned int rngSeed, unsigned int asteroidCount, + unsigned int meshInstanceCount, unsigned int subdivCount, + unsigned int textureCount); + + const Mesh* Meshes() { return &mMeshes; } + const D3D11_SUBRESOURCE_DATA* TextureData(unsigned int textureIndex) + { + return mTextureSubresources.data() + SubresourceIndex(textureIndex); + } + + unsigned int GetTextureMipLevels()const{return mTextureMipLevels;} + + const AsteroidStatic* StaticData() const { return mAsteroidStatic.data(); } + const AsteroidDynamic* DynamicData() const { return mAsteroidDynamic.data(); } + + // Can optionall provide a range of asteroids to update; count = 0 => to the end + // This is useful for multithreading + void Update(float frameTime, DirectX::XMVECTOR cameraEye, const Settings& settings, + size_t startIndex = 0, size_t count = 0); +}; diff --git a/Projects/Asteroids/src/skybox_ps.hlsl b/Projects/Asteroids/src/skybox_ps.hlsl new file mode 100644 index 0000000..4107073 --- /dev/null +++ b/Projects/Asteroids/src/skybox_ps.hlsl @@ -0,0 +1,16 @@ +struct Skybox_VSOut +{ + float3 coords : UVFACE; +}; + +TextureCube Skybox;// : register(t0); +SamplerState Skybox_sampler;// : register(s0); + +void skybox_ps(in float4 position : SV_Position, + in Skybox_VSOut vsoutput, + out float4 color : SV_Target) +{ + //return input.coords.xyzx; + float4 tex = Skybox.Sample(Skybox_sampler, vsoutput.coords); + color = float4(tex.xyz, 1.0f); +} diff --git a/Projects/Asteroids/src/skybox_vs.hlsl b/Projects/Asteroids/src/skybox_vs.hlsl new file mode 100644 index 0000000..acefcd5 --- /dev/null +++ b/Projects/Asteroids/src/skybox_vs.hlsl @@ -0,0 +1,20 @@ +cbuffer SkyboxConstantBuffer// : register(b0) +{ + float4x4 mViewProjection; +}; + +struct Skybox_VSOut +{ + float3 coords : UVFACE; +}; + +void skybox_vs( in float3 in_position : ATTRIB0, + in float3 uvFace : ATTRIB1, + out float4 position : SV_Position, + out Skybox_VSOut vsoutput) +{ + // NOTE: Don't translate skybox and make sure depth == 1 (no clipping) + position = mul(mViewProjection, float4(in_position, 0.0f)).xyww; + position.z = 0.0f; // 1-z + vsoutput.coords = in_position.xyz; +} diff --git a/Projects/Asteroids/src/sprite.h b/Projects/Asteroids/src/sprite.h new file mode 100644 index 0000000..4a8311d --- /dev/null +++ b/Projects/Asteroids/src/sprite.h @@ -0,0 +1,36 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +struct SpriteVertex { + float x; + float y; + float u; + float v; +}; + +inline SpriteVertex* DrawSprite(float x, float y, float width, float height, float viewportWidth, float viewportHeight, SpriteVertex* outVertex) +{ + outVertex[0] = {x , y , 0.0f, 0.0f}; + outVertex[1] = {x + width, y , 1.0f, 0.0f}; + outVertex[2] = {x + width, y + height, 1.0f, 1.0f}; + outVertex[3] = outVertex[0]; + outVertex[4] = outVertex[2]; + outVertex[5] = {x , y + height, 0.0f, 1.0f}; + + for (int i = 0; i < 6; ++i) { + outVertex[i].x = (outVertex[i].x / viewportWidth * 2.0f - 1.0f); + outVertex[i].y = -(outVertex[i].y / viewportHeight * 2.0f - 1.0f); + } + + outVertex += 6; + return outVertex; +} diff --git a/Projects/Asteroids/src/sprite_ps.hlsl b/Projects/Asteroids/src/sprite_ps.hlsl new file mode 100644 index 0000000..fa47f83 --- /dev/null +++ b/Projects/Asteroids/src/sprite_ps.hlsl @@ -0,0 +1,11 @@ +#include "sprite_vs.hlsl" + +Texture2D Tex;// : register(t0); +SamplerState Tex_sampler;// : register(s0); + +void sprite_ps(in float4 position : SV_Position, + in Font_VSOut vs_out, + out float4 color : SV_Target ) +{ + color = Tex.Sample(Tex_sampler, vs_out.uv); +} diff --git a/Projects/Asteroids/src/sprite_vs.hlsl b/Projects/Asteroids/src/sprite_vs.hlsl new file mode 100644 index 0000000..6fea9e5 --- /dev/null +++ b/Projects/Asteroids/src/sprite_vs.hlsl @@ -0,0 +1,14 @@ + +struct Font_VSOut +{ + float2 uv : UV; +}; + +void sprite_vs( float2 in_position : ATTRIB0, + float2 in_uv : ATTRIB1, + out float4 position : SV_Position, + out Font_VSOut vs_out) +{ + position = float4(in_position, 0, 1); + vs_out.uv = in_uv; +} diff --git a/Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl b/Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl new file mode 100644 index 0000000..066ba29 --- /dev/null +++ b/Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl @@ -0,0 +1,1195 @@ +// Font generated by stb_font_inl_generator.c (4/1 bpp) +// +// Following instructions show how to use the only included font, whatever it is, in +// a generic way so you can replace it with any other font by changing the include. +// To use multiple fonts, replace STB_SOMEFONT_* below with STB_FONT_consolas_bold_50_usascii_*, +// and separately install each font. Note that the CREATE function call has a +// totally different name; it's just 'stb_font_consolas_bold_50_usascii'. +// +/* // Example usage: + +static stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS]; + +static void init(void) +{ + // optionally replace both STB_SOMEFONT_BITMAP_HEIGHT with STB_SOMEFONT_BITMAP_HEIGHT_POW2 + static unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH]; + STB_SOMEFONT_CREATE(fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT); + ... create texture ... + // for best results rendering 1:1 pixels texels, use nearest-neighbor sampling + // if allowed to scale up, use bilerp +} + +// This function positions characters on integer coordinates, and assumes 1:1 texels to pixels +// Appropriate if nearest-neighbor sampling is used +static void draw_string_integer(int x, int y, char *str) // draw with top-left point x,y +{ + ... use texture ... + ... turn on alpha blending and gamma-correct alpha blending ... + glBegin(GL_QUADS); + while (*str) { + int char_codepoint = *str++; + stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR]; + glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0, y + cd->y0); + glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1, y + cd->y0); + glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1, y + cd->y1); + glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0, y + cd->y1); + // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct + x += cd->advance_int; + } + glEnd(); +} + +// This function positions characters on float coordinates, and doesn't require 1:1 texels to pixels +// Appropriate if bilinear filtering is used +static void draw_string_float(float x, float y, char *str) // draw with top-left point x,y +{ + ... use texture ... + ... turn on alpha blending and gamma-correct alpha blending ... + glBegin(GL_QUADS); + while (*str) { + int char_codepoint = *str++; + stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR]; + glTexCoord2f(cd->s0f, cd->t0f); glVertex2f(x + cd->x0f, y + cd->y0f); + glTexCoord2f(cd->s1f, cd->t0f); glVertex2f(x + cd->x1f, y + cd->y0f); + glTexCoord2f(cd->s1f, cd->t1f); glVertex2f(x + cd->x1f, y + cd->y1f); + glTexCoord2f(cd->s0f, cd->t1f); glVertex2f(x + cd->x0f, y + cd->y1f); + // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct + x += cd->advance; + } + glEnd(); +} +*/ + +#ifndef STB_FONTCHAR__TYPEDEF +#define STB_FONTCHAR__TYPEDEF +typedef struct +{ + // coordinates if using integer positioning + float s0,t0,s1,t1; + signed short x0,y0,x1,y1; + int advance_int; + // coordinates if using floating positioning + float s0f,t0f,s1f,t1f; + float x0f,y0f,x1f,y1f; + float advance; +} stb_fontchar; +#endif + +#define STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH 256 +#define STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT 317 +#define STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT_POW2 512 + +#define STB_FONT_consolas_bold_50_usascii_FIRST_CHAR 32 +#define STB_FONT_consolas_bold_50_usascii_NUM_CHARS 95 + +#define STB_FONT_consolas_bold_50_usascii_LINE_SPACING 33 + +static unsigned int stb__consolas_bold_50_usascii_pixels[]={ + 0x207fffff,0x08000000,0x00000000,0x0aa88000,0x2ea60000,0x359950cc, + 0x66540003,0xcccccccc,0x999950cc,0x99999999,0x3bb20001,0x8800002e, + 0x000000aa,0x2aaaa200,0x2aaaa61a,0x3fffe0aa,0x000ed83f,0x00fe6000, + 0xdfb95100,0x00000379,0x027fffd4,0xffffd300,0x3fff61ff,0xc8004fff, + 0xffffffff,0xff91ffff,0xffffffff,0x3a0003ff,0x80002fff,0xfffffdc8, + 0x00001cdf,0x3ffff200,0x3ffff20f,0x3fffe0ff,0x077fec3f,0x7fcc0000, + 0xff70003f,0xffffffff,0xf9800003,0x003fffff,0x7ffffe44,0xfffb0fff, + 0x005fffff,0x7fffffe4,0x91ffffff,0xffffffff,0x0003ffff,0x0007fffe, + 0xffffff50,0x09ffffff,0xff100000,0xffc8bfff,0x3fe0ffff,0x3ff63fff, + 0x00000eff,0x0fffffe6,0xffffd880,0xffffffff,0x3f200001,0x006fffff, + 0x7ffffff4,0xfffb0fff,0x03ffffff,0x3fffff20,0x1fffffff,0xfffffff9, + 0x003fffff,0x01ffff30,0x7fffec00,0xffffffff,0x00000dff,0x3ffffee0, + 0x7ffffe42,0x3ffffe0f,0xffffff13,0xf500001d,0x009fffff,0x3fffffe6, + 0xffffffff,0xfb00002f,0x00ffffff,0x7fffffd4,0xffb0ffff,0xdfffffff, + 0x3ffff200,0xffffffff,0xffffff91,0x03ffffff,0x0ffff500,0x3fffa200, + 0xffffffff,0x01efffff,0xfffd0000,0xffff90df,0x7fffc1ff,0x3fffe63f, + 0x20000eff,0x4ffffff9,0xfffff100,0xffb757df,0x0003ffff,0xffffff70, + 0x7fff400d,0x4c00aeff,0x3ffffffc,0x7ffffc80,0xfff98000,0xba8801ff, + 0xacffffec,0xfffb0009,0xffffffff,0xbfffffff,0xff500000,0xff707fff, + 0xfff8ffff,0x7ffcc3ff,0x10005fff,0x0bfffffd,0x7fffff40,0xffffd102, + 0xff10000b,0x2005ffff,0x05fffffa,0xfffff980,0xffffc806,0xff980007, + 0x3ea01fff,0xffffffff,0x405fffff,0xeffffff9,0xffca889b,0x001fffff, + 0x7fffec00,0xffffb80f,0x7ffffc7f,0xfffff983,0xffd8003f,0x32005fff, + 0x401fffff,0x00fffff8,0xfffe9800,0x3ffee003,0xf90000ff,0xf900ffff, + 0x0000ffff,0x03fffff3,0xffffffd3,0xffffffff,0xfffe80bf,0x3ee00fff, + 0x005fffff,0x3fffe200,0xffff704f,0xfffff8ff,0xfffff503,0x7fd4001f, + 0x2a006fff,0x001fffff,0x007ffff5,0x4000c400,0x005ffffc,0x3ffffe60, + 0x7fffe400,0xff980007,0x7fd41fff,0xffffffff,0x5fffffff,0x3ffffea0, + 0xfffb801f,0x00001fff,0x03fffff9,0x1fffffea,0x407fffff,0x05fffffd, + 0xffffff10,0x7fff4003,0x7ff4003f,0x0000006f,0x4ffffd80,0x3ffe2000, + 0x7fe401ff,0x980007ff,0x221fffff,0xffffffff,0xffffffff,0x3ffa05ff, + 0x3e004fff,0x004fffff,0xbfffff00,0x7ffffd40,0x1fffffc6,0xffffff10, + 0xffffb005,0x7fcc009f,0xfc8006ff,0x00001fff,0x7fff4000,0x7fc0003f, + 0x7e402fff,0x80007fff,0x21fffff9,0xdffffffe,0xa9ffffaa,0xff305fdc, + 0x4003ffff,0x06fffffd,0xffffb800,0x3ffea02f,0x7fffc6ff,0x7ffdc03f, + 0x3e600fff,0x000effff,0x00bffff6,0x13fffea0,0xddddddd3,0xdddddddd, + 0x3fa007dd,0x40003fff,0x402fffff,0x007ffffc,0xfffff980,0xffffff31, + 0x837ffd47,0xfffff701,0xfffa800d,0xe80007ff,0x5406ffff,0x7c6fffff, + 0xe803ffff,0x202fffff,0x02fffffc,0x1bfffe20,0xfff13008,0xffff989f, + 0xffffffff,0x004fffff,0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000, + 0xffff71ff,0x5fffb8ff,0x7fffe400,0x7fc4004f,0x0000ffff,0x0fffffe6, + 0xdfffff30,0x03fffff8,0x6fffff98,0xdfffff10,0xffffc800,0x77ffed43, + 0xfffd6fec,0xfffff98b,0xffffffff,0xd004ffff,0x0007ffff,0x02fffff8, + 0x03ffffe4,0x7fffcc00,0xfffff91f,0x04fffd8b,0x7fffff40,0xffff8003, + 0x360001ff,0x400fffff,0x45fffff9,0x003fffff,0x01fffffd,0x07fffff7, + 0x0ffffe80,0x3ffffff2,0xfffb6fff,0xfffff98d,0xffffffff,0xd004ffff, + 0x0007ffff,0x02fffff8,0x03ffffe4,0x7fffcc00,0xfffff91f,0x1ffff41f, + 0x3ffffa00,0xfff8003f,0x10002fff,0x009fffff,0x8bfffff3,0x003fffff, + 0x07fffff7,0x01fffffd,0x2ffffc40,0xfffffff9,0x3ff6bfff,0x77774c7f, + 0xeeeeeeee,0x004fffff,0x005fffff,0x3ffffe80,0x3ffffe40,0x7ffcc000, + 0xffff71ff,0x3ffe19ff,0x7ffc002f,0xe8002fff,0x003fffff,0x3fffff90, + 0xfffff100,0x3fffff8b,0xfffff300,0xfffff98d,0x7ffd4005,0xfffff12f, + 0x29ffffff,0x0007fffc,0x27ffffdc,0x7ffffc40,0x7fec0002,0x7fe404ff, + 0x980007ff,0xf31fffff,0x7fffffff,0x8003ffff,0x01ffffff,0xfffffe80, + 0xffff0003,0x3fe200df,0x7ffc4fff,0x3fa003ff,0x3ee1ffff,0x4002ffff, + 0xfb1ffffc,0xffb7ffff,0x3fff27ff,0x3ee0000f,0xa804ffff,0x001fffff, + 0x7ffffec0,0x3ffff200,0xff980007,0x3ffe1fff,0xffffffff,0x7fc4007f, + 0x8001ffff,0x03fffffd,0xfffffa80,0xffff1002,0xfffff89f,0x3ffee003, + 0x3fff22ff,0x7f4000ff,0x3fffe7ff,0x7ffff90f,0x007fffee,0xfffffb80, + 0x7fff4404,0xfa80006f,0x3204ffff,0x0007ffff,0x1fffff98,0x3fffffe6, + 0x1cffffff,0x3ffffe00,0xffe8002f,0xe8002fff,0x2007ffff,0x44fffff8, + 0x003fffff,0x8fffffea,0x007ffffd,0x9b7fffc4,0x3f25ffff,0xfff72fff, + 0x7dc0003f,0x2a24ffff,0xfffffcba,0xfd00003f,0x559dffff,0x1fffff25, + 0x3ffe6000,0x7ffdc1ff,0xffffffff,0xfe802eff,0x8003ffff,0x01ffffff, + 0x7ffffcc0,0x7fffc003,0x7ffffc4f,0x3ffe6003,0x3fffa4ff,0x7fcc006f, + 0xffff94ff,0x8ffffec5,0x000ffffb,0x3ffffee0,0x3ffffe64,0x0004ffff, + 0x3ffffa60,0xff95ffff,0x30000fff,0x503fffff,0xfffffffd,0x3dffffff, + 0x7fffff40,0xffff8003,0x7ec000ff,0x4000ffff,0x7c3fffff,0x2003ffff, + 0x25fffff8,0x005fffff,0xd97fffd4,0x3fa1ffff,0xfff90fff,0xffb8000f, + 0x3fe64fff,0x02dfffff,0xfeb88000,0xf95fffff,0x0000ffff,0x03fffff3, + 0x7fffffe4,0xffffffff,0xfffffb03,0xfff88009,0x7c4007ff,0x8005ffff, + 0x7c3fffff,0x4003ffff,0xf15fffff,0x8009ffff,0xfd2ffffa,0x7ff41fff, + 0xffff90ff,0xfffb8000,0x3ffe64ff,0x002cffff,0xffeb8800,0xff95ffff, + 0x30000fff,0x803fffff,0xfffffea8,0x2fffffff,0x6fffffc8,0x7fffd400, + 0x7fdc007f,0xf8001fff,0x7fc3ffff,0x7c003fff,0xff36ffff,0xb8007fff, + 0xfff1ffff,0x7ffff8ff,0x001ffff2,0x9fffff70,0x7fffffcc,0x00004fff, + 0x3fffffe6,0xfff95fff,0xf30000ff,0x2003ffff,0xfffffff8,0x41ffffff, + 0x0ffffffb,0x3ffff200,0x7ffc005f,0xfd0006ff,0xfff85fff,0x7f4003ff, + 0xfff36fff,0xfb8009ff,0xffff1fff,0x26ffff8d,0x0006fffd,0x27ffffdc, + 0xfffb7551,0x00005fff,0x3bfffffe,0xfff92aac,0xf30000ff,0x2003ffff, + 0xffcffffa,0x44ffffff,0x3ffffff8,0x3ffffe00,0x3fea001f,0xd0002fff, + 0xff85ffff,0x7c003fff,0xff35ffff,0xc800bfff,0xff88ffff,0x3ffe26ff, + 0x1bfffa6f,0xffff7000,0xfff9809f,0xa80006ff,0x204fffff,0x007ffffc, + 0xfffff980,0xdfff7001,0x3fffff62,0xffffd86f,0xffb800ef,0x74006fff, + 0x0007ffff,0x7ffffc00,0x3ffe2003,0xffff14ff,0xffd800df,0xffff88ff, + 0x93fffe66,0x0004ffff,0x27ffffdc,0x7ffffdc0,0x7fec0001,0x7fe406ff, + 0x980007ff,0x001fffff,0xfe89fff9,0xfa87ffff,0x00efffff,0x3fffffea, + 0x3ffe6003,0x000004ff,0x01fffffc,0x7fffff30,0x037ffffc,0x45ffff60, + 0x3ea6ffff,0xfff14fff,0xfb80005f,0x8804ffff,0x001fffff,0x27ffff40, + 0x1fffff20,0x3ffe6000,0xffb001ff,0xffffb87f,0xffff80ff,0x260aefff, + 0x7ffffffb,0x7fffe400,0x4000000f,0x003fffff,0x8bffffe6,0x007ffffe, + 0xf87fffe4,0x3ff66fff,0xffff74ff,0xffb80001,0xff004fff,0x80005fff, + 0x403ffffe,0x007ffffc,0xfffff980,0x5fffd001,0x6fffffa8,0xffffff70, + 0xffffffff,0x005fffff,0x2fffffc4,0x3bf66000,0x3fffff84,0x3fffee00, + 0x3ffff61f,0x3ff2001f,0xffffd0ff,0x9fffff51,0x0017fffa,0x3ffffee0, + 0xffffd004,0xfff80007,0x7fe402ff,0x980007ff,0x001fffff,0xfc83ffff, + 0x3205ffff,0xffffffff,0xffffffff,0x7fdc003f,0x20001fff,0x45fffff9, + 0x003fffff,0x83fffff6,0x04fffffc,0x47fffee0,0xffeffffd,0xffefffff, + 0xb80003ff,0x004fffff,0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000, + 0x103791ff,0x7dc1ffff,0x403fffff,0xfffffffc,0xffffffff,0xfffe8003, + 0x7ec0006f,0x3e1fffff,0x1003ffff,0x98bfffff,0x006fffff,0x5cbfffea, + 0xffffffff,0xffffffff,0xfb80000e,0xd004ffff,0x0007ffff,0x02fffff8, + 0x03ffffe4,0x7fffcc00,0x9bfffb1f,0x73ffff75,0xfffffffd,0xffff9001, + 0xffffffff,0xff50005d,0x80007fff,0x3fffffff,0x00fffffe,0x17ffffdc, + 0x0ffffff4,0x3ffff980,0xfffffff1,0xffffffd7,0x2e00001f,0x004fffff, + 0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000,0xffffb1ff,0xffffffff, + 0xffffffff,0xffea8003,0x02dfffff,0x3ffff600,0xffe80007,0x3fe2ffff, + 0xfd003fff,0x3ee0ffff,0x1004ffff,0x7d47ffff,0xff34ffff,0x0003ffff, + 0x7ffffdc0,0xffffd004,0xfff80007,0x7fe402ff,0x980007ff,0xfb1fffff, + 0xffffffff,0xffffffff,0x540005ff,0x003fffff,0x7ffffcc0,0xffc80004, + 0x3fe0ffff,0xf9803fff,0xf104ffff,0x001fffff,0x98dffff1,0x6dcc1cec, + 0xb800002c,0x004fffff,0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000, + 0xffffb1ff,0xffffffff,0x05dfffff,0xffff8800,0x7e40005f,0x0000ffff, + 0x85ffffb0,0x803fffff,0x01fffffd,0x13fffff6,0x0fffffc0,0x00000000, + 0x0fffffee,0x1fffff40,0x3fffe000,0x7ffe402f,0xf980007f,0xffb1ffff, + 0xffffffff,0x05dfffff,0x7fff4000,0x880601ff,0x005fffff,0x4055d400, + 0x403fffff,0x06fffffa,0x7fffffd4,0xffffc801,0x00000003,0x7ffffe40, + 0xffffb002,0x7fc40009,0x7e401fff,0x80007fff,0x41fffff9,0xfffedba9, + 0x001acdef,0xffffd800,0x27e443ff,0x2fffffb8,0x7c000000,0x2203ffff, + 0x01ffffff,0x6fffffd8,0x6ffff980,0x00000000,0x0fffffec,0x5ffffc80, + 0x3ffe6000,0x7fe400ff,0x980007ff,0x401fffff,0x000ffff9,0xfffa8000, + 0xffefffff,0xffe81fff,0x000006ff,0x3fffff80,0x3fffff20,0xffff1004, + 0xffd007ff,0x000005ff,0x3ffe2000,0x3ee007ff,0x0000ffff,0x00fffff7, + 0x00fffff9,0xfffff300,0x7fffa803,0x36000000,0xffffffff,0x546fffff, + 0x003fffff,0xfff80000,0xfff503ff,0xfa800dff,0x401fffff,0x02fffffb, + 0x00400440,0xdfffff90,0x7fffd400,0xff88004f,0xfc806fff,0x80007fff, + 0x01fffff9,0x002fffdc,0xffd10000,0xffffffff,0x7fec5fff,0x00000fff, + 0xfffff800,0xfffff983,0xffd8001f,0x2200ffff,0x01ffffff,0x4400fc88, + 0x7fe402df,0x2003ffff,0xdffffff8,0xfffb8801,0xfc803fff,0x80007fff, + 0x01fffff9,0x0027ffe4,0x3f220000,0xffffffff,0x4cccc1ef,0x00000009, + 0x87fffff0,0x3ffffff9,0xffff1000,0x7e401dff,0x1bdfffff,0x1fffb733, + 0xeffff880,0xfffedccc,0xb8005fff,0xffffffff,0xfffd90ef,0x00dfffff, + 0x3ffffff2,0x91ffffff,0xffffffff,0xe803ffff,0x00003fff,0xffdb1000, + 0x0007bdff,0xf0000000,0x7c47ffff,0x005fffff,0x7ffffcc0,0x3ffa00ef, + 0xffffffff,0x00ffffff,0x7fffffc4,0xffffffff,0xfd0000ff,0xffffffff, + 0x3fffff61,0x9002ffff,0xffffffff,0x3f23ffff,0xffffffff,0x7fc01fff, + 0x000002ff,0x00131000,0x00000000,0x13fffff8,0x0bfffffd,0x3ffe6000, + 0x3a205fff,0xffffffff,0x0fffffff,0x7ffffc40,0xffffffff,0x220002ff, + 0xfffffffe,0xfffffb0f,0x64007fff,0xffffffff,0xff91ffff,0xffffffff, + 0x000003ff,0x00000000,0x00000000,0x3fffff80,0x017ffff6,0xffff3000, + 0xfff9003f,0xffffffff,0xff1007df,0xffffffff,0x00019fff,0x3ffffaa0, + 0xffffb0ff,0xc8001bff,0xffffffff,0xff91ffff,0xffffffff,0x000003ff, + 0x00000000,0x00000000,0x3fffff80,0x0002ffec,0x01fff980,0x3fffae20, + 0x001cefff,0x7fffedc4,0x000ceeff,0x99753000,0x2af32a19,0x99500009, + 0x99999999,0x3332a199,0xcccccccc,0x0000000c,0x00000000,0x00000000, + 0x41fffffc,0x4000005d,0x440001f9,0x10000019,0x00000033,0x00000000, + 0x00000000,0x00000000,0x00000000,0x7fc00000,0x00003fff,0x00002000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x7ffffc00,0x00000003,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0xf8000000,0x0003ffff,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x55555500,0x20000000,0x00000999, + 0x00002620,0x33bf6e60,0x5554c002,0x026aaa0a,0x77774c00,0xeb8001ee, + 0x0004eeee,0x001004cc,0x4002a620,0x00aaaaa9,0x2a200000,0x7fe4000a, + 0x00000fff,0xfffed980,0xeeeeefff,0xb7005eee,0x07dfffff,0xffff7000, + 0x1001bfff,0x7c4dffff,0x2cefffff,0x3ffffa00,0xffe8005f,0x2a003fff, + 0xfffffedb,0x70ffdbbd,0xea87dddd,0x02deffff,0x0bfffff2,0x7dc00000, + 0x26004fff,0x003fffff,0x3ff62000,0xffffffff,0x6fffffff,0x7ffff4c0, + 0x02efffff,0xfffff900,0x900bffff,0x7c43ffff,0xffffffff,0xfffb802e, + 0x26000fff,0x00ffffff,0xfffffe98,0xffffffff,0xffff90ff,0x3ffff629, + 0x903fffff,0x005fffff,0xfff30000,0x74005fff,0x0007ffff,0xfffff100, + 0xffffffff,0x0dffffff,0x7fffffdc,0x2fffffff,0x7fffc400,0x1fffffef, + 0x0ffffe60,0xfffffff1,0x405dffff,0x2ffffff8,0x3ffff200,0xfffb805f, + 0xffffffff,0x90ffffff,0xff19ffff,0xffffffff,0xfff909ff,0x000005ff, + 0xffffff90,0x7ffd400d,0x800002ff,0xfffffffe,0xfffffffe,0xf306ffff, + 0xffffffff,0x01ffffff,0x8f7ffe40,0x205ffffa,0xf886fffe,0xffffffff, + 0x3602ffff,0x005fffff,0x0bfffffe,0xffffffd0,0xffffffff,0x3f21ffff, + 0xfffedfff,0xffffffff,0x7ffe43ff,0x000002ff,0xffffffd8,0x7fffc007, + 0x6400006f,0x41efffff,0xcffffffa,0xfffd03cc,0xff957dff,0x400bffff, + 0x7e44fffe,0xfff906ff,0xffff103f,0xffffffff,0x3fea03ff,0x9800ffff, + 0x406fffff,0xfffffffb,0xffeccace,0xff90ffff,0xffffffff,0xffffffdf, + 0xffffc8ff,0x8000002f,0x5ffffffc,0x7fffdc00,0x3e00001f,0x2206ffff, + 0x403fffff,0x84fffffa,0x07fffff9,0x70bfffe0,0xff30ffff,0x533009ff, + 0xfffffff9,0x3ffe01ff,0xfc803fff,0x2203ffff,0x1fffffff,0x3fffffa0, + 0xffffff90,0x36217dff,0x22ffffff,0x02fffffc,0xff880000,0x4002ffff, + 0x04fffff8,0xffff1000,0xfffc805f,0x7ffdc07f,0xfff900ff,0xff1001ff, + 0xfff983ff,0x06fffe87,0xffff7100,0x3ee0bfff,0xf806ffff,0x200fffff, + 0x0efffffd,0x7fffff40,0xffffff90,0x7ffec0bf,0x3fff26ff,0x000002ff, + 0x05fffd30,0x3ffff600,0xfa80000f,0x5400ffff,0x200fffff,0x206ffffd, + 0x01fffffa,0x42ffff88,0x7e47fffb,0x40001fff,0x7ffffffa,0xffffff10, + 0x7fffd403,0x3ffe605f,0xfe802fff,0xff90ffff,0x401dffff,0x0ffffffa, + 0x05fffff9,0x18800000,0x7ffcc000,0xb80003ff,0xa807ffff,0x200fffff, + 0x206ffffe,0x00fffffb,0xc89ffff0,0x3fe65fff,0x900004ff,0x01ffffff, + 0x13fffff6,0x2fffffd8,0x3ffffee0,0xffffd006,0x3ffff21f,0xfff800ef, + 0xfff91fff,0x026203ff,0x00000000,0x037ffff4,0x7fffd400,0x7ffdc00f, + 0x7ffe407f,0xfffb00ff,0x7ff400df,0xffff51ef,0x037fff49,0xffff3000, + 0x3fea05ff,0xff107fff,0xfc80ffff,0xd003ffff,0x321fffff,0x002fffff, + 0x25fffffb,0x21fffffc,0xdefffeca,0x00000002,0x3ffffea0,0x7fc40002, + 0x7f403fff,0x7dc05fff,0xfa82ffff,0x2004ffff,0xfefffffa,0xff70ffff, + 0x800003ff,0x03ffffff,0x0bfffffe,0x13ffffee,0x5fffffb0,0x3ffffa00, + 0xfffff90f,0x3fff6005,0xffff93ff,0x3ffff23f,0x203fffff,0xeeeeeeeb, + 0x002eeeee,0x17ffffe0,0x3fffe000,0xfff901ff,0xff9809ff,0x3ea0ffff, + 0x000fffff,0x7ffffff4,0xfff33fff,0x8800009f,0x02ffffff,0x17fffff2, + 0x03fffffa,0x3fffffd0,0x3ffffa00,0xfffff90f,0x3fff2005,0xffff94ff, + 0xfffffb3f,0x09ffffff,0x3ffffff2,0x03ffffff,0x3ffff200,0x7d40001f, + 0xaacfffff,0xffffffeb,0xffffd800,0xffffc8df,0xd88002ff,0x2fffffff, + 0x003bfffa,0xffff5000,0x7fc401ff,0x3e60ffff,0xf806ffff,0x000fffff, + 0x21fffffd,0x02fffffc,0x9fffff90,0x3bfffff2,0xffffffff,0xc83fffff, + 0xffffffff,0x0003ffff,0x13ffffe2,0x3fff6000,0xffffffff,0x3001ffff, + 0xffffffff,0x007fffff,0xbdfeca80,0x0bfffee0,0xfff10000,0xfb00ffff, + 0x7e45ffff,0x4402ffff,0x00ffffff,0x1fffffd0,0x0bfffff2,0x7ffffec0, + 0xffffff93,0xffdfffff,0x90ffffff,0xffffffff,0x0007ffff,0x0fffffd8, + 0x3ffe2000,0xffffffff,0x4003ffff,0xfffffffc,0x0001ffff,0xffff8800, + 0x73100004,0x7fffffff,0xfffff500,0x3fffffcb,0xffffff80,0xffffd001, + 0x3ffff21f,0xfffb002f,0x3fff25ff,0x0befffff,0xffffffb1,0xeeeeeb85, + 0x3ffffffe,0x7ffcc000,0x360003ff,0xffffffff,0x00cfffff,0xfffffd00, + 0x00019fff,0x3fffa000,0x3fe0000f,0xffffffff,0x3fe006ff,0xff98ffff, + 0xfd004fff,0x2003ffff,0x90fffffe,0x005fffff,0x43fffffe,0xfffffffc, + 0x3ffff605,0x3ff2006f,0x80003fff,0x006ffffe,0x2dffff50,0x0abcdcca, + 0x3ffe6000,0x001fffff,0x3fee0000,0x7c0002ff,0xffffffff,0x32001fff, + 0xfcbfffff,0xb001ffff,0x007fffff,0x1ffffff5,0x0bfffff2,0x3ffffe60, + 0x3fffff27,0x3fea00ef,0x9000ffff,0x007fffff,0xfffff700,0xfffb0005, + 0x4000005f,0xfffffffb,0x999904ff,0x7c400039,0x80005fff,0xffffffff, + 0x4c000dff,0xffefffff,0x32006fff,0x405fffff,0xfffffff9,0x5fffff90, + 0xfffffb00,0x7ffffe4d,0xffff800e,0xff9001ff,0x00007fff,0x017ffffe, + 0x0fffffe0,0x7fdc0000,0xffffffff,0x7fffc43f,0x3f60002f,0x80000fff, + 0xffffffff,0x3fa0002d,0xffffffff,0x3fea003f,0xf100ffff,0x1fffffff, + 0x0bfffff2,0xffffff50,0x7ffffe47,0xffffb002,0x3ff2005f,0x00003fff, + 0x01fffff9,0xffffff80,0x7d400002,0xffefffff,0x3e21ffff,0x0001ffff, + 0x885ffff5,0xfd0009aa,0x0003dfff,0x3ffffea0,0x000fffff,0x77fffffc, + 0x7ffff5c0,0xff90ffff,0x7dc05fff,0x645fffff,0x002fffff,0x07fffffb, + 0x3fffff20,0xff100003,0xd8009fff,0xefffffff,0x9accdeee,0xffffe800, + 0xfffffd3f,0x3fffe21f,0xff88000f,0x3ffea5ff,0xfe804fff,0x00004fff, + 0x7ffffffc,0xfb8004ff,0xcdffffff,0xffffffff,0xfff90fff,0x75559dff, + 0xfffffffb,0xfffffc81,0xffff9002,0x3ff2009f,0x00003fff,0x03fffff6, + 0xfffffa80,0xffffffff,0x501dffff,0x449fffff,0x8effffff,0x007ffffa, + 0x21ffffb0,0xfffffffc,0x3ff600ef,0x400004ff,0xfffffffc,0xff88001f, + 0xffffffff,0xffffffff,0xffff90ff,0xffffffff,0x07ffffff,0x05fffff9, + 0x3fffff20,0xffff9004,0x5400007f,0x003fffff,0x7fffffd4,0xffffffff, + 0xfe84ffff,0x7cc1ffff,0xfbdfffff,0xa8007fff,0xff33ffff,0xffffffff, + 0x7fffec09,0x7cc00003,0x05ffffff,0x3fffea00,0xffffffff,0x0fffffcd, + 0xfffffff9,0xffffffff,0x3ff207ff,0xfb002fff,0x2007ffff,0x03fffffc, + 0x7fff4000,0x7f44006f,0xffffffff,0xffffffff,0x7ffffc3f,0xfffff707, + 0x09ffffff,0x5ffff880,0x2efffffa,0xb00fffff,0x0007ffff,0xfffffd00, + 0xf980003f,0xffffffff,0xfffff94f,0x3fffff21,0xffffffff,0x3f200dff, + 0xb002ffff,0x005fffff,0x0ffffff2,0xfff70000,0x3a6003ff,0xeeefffff, + 0xfffffeee,0xff10ffff,0x7e40bfff,0xffffffff,0x7fec001f,0xffff30ff, + 0x17fffc43,0x20000000,0x05fffffe,0xfffb3000,0x7ec5dfff,0xff90ffff, + 0xffffffff,0x9005bdff,0x005fffff,0x03fffffe,0x7ffffe40,0x7c400003, + 0x8805ffff,0x01fffffe,0x7ffffe44,0xfffff12f,0xffffd80b,0x4006ffff, + 0x2a3ffffa,0xfff87fff,0x0000003f,0x3ffffea0,0x9800002f,0xffd81abb, + 0xfff90fff,0x355535ff,0xffff9000,0xfff3005f,0x7e400fff,0x0003ffff, + 0xfffffc80,0x7fffe400,0x3ff2002f,0x3ffe4fff,0x7f4407ff,0x03ffffff, + 0x1bfffe20,0xfb0dfff7,0x008809ff,0xffe88000,0x00006fff,0x3fff6000, + 0xffff90ff,0x3200005f,0x802fffff,0x06fffffd,0x3fffff20,0xf9800003, + 0x7c04ffff,0x4007ffff,0x24fffffb,0x02fffffe,0x7fffffcc,0x3ff2000f, + 0x7ffdc1ff,0x04fffd86,0x003dfff5,0x7fffec00,0x000001ff,0x3ffffa00, + 0xfffff90f,0x3f200005,0x5402ffff,0x03ffffff,0x3fffff20,0xfb000003, + 0x7c40ffff,0x4007ffff,0x22fffffc,0x1ffffffc,0x3ffffea0,0xff5004ff, + 0xfff507ff,0x07ffff0f,0x3ffffff3,0xffe98000,0x0002ffff,0x7ff40000, + 0xfff90fff,0x200005ff,0x02fffffc,0x3fffffee,0x7ffe4005,0x000003ff, + 0x05fffff5,0x17fffffc,0xfffffa80,0x3fffe60f,0xba9bdfff,0xfffffffd, + 0x7f4403ff,0xfff306ff,0x7fffc43f,0xfffffd82,0x3bb2005f,0xfffffffe, + 0x0000004f,0xfffffe80,0x5fffff90,0x3ff20000,0xaaacefff,0xffffffdb, + 0x7fe4000f,0x00003fff,0x1bffffa0,0xffffffd8,0x7ecc41ac,0xc84fffff, + 0xffffffff,0xffffffff,0x02ffffff,0x407ffff2,0xbcfffff8,0xff06ffff, + 0x00dfffff,0x7fffffe4,0x0006ffff,0xffd00000,0x3ff21fff,0x00002fff, + 0xfffffff9,0xffffffff,0x99307fff,0xffd99999,0x9999dfff,0xb8000599, + 0x501fffff,0xffffffff,0xffffffff,0x740bffff,0xffffffff,0xffffffff, + 0x80ffffff,0x403ffff9,0xfffffffb,0xffd02fff,0x400bffff,0xfffffffc, + 0x00000dff,0xfffd0000,0x3fff21ff,0x900002ff,0xffffffff,0xffffffff, + 0x3ffee07f,0xffffffff,0xffffffff,0x7c40004f,0x2a05ffff,0xffffffff, + 0xffffffff,0x7e4406ff,0xffffffff,0xff8aefff,0x740effff,0xfd006fff, + 0x9fffffff,0x7ffffdc0,0x3ff2002f,0x02efffff,0x40000000,0x90fffffe, + 0x005fffff,0x3ffff200,0xffffffff,0x2e00dfff,0xffffffff,0xffffffff, + 0x0004ffff,0x0fffffc8,0x3ffffaa0,0xffffffff,0x22002dff,0xfffffffd, + 0x7ffcc3ff,0x3ff25fff,0x3ee001ff,0x802fffff,0x004ffffc,0x677fffe4, + 0x00000003,0xfffffd00,0x3fffff21,0x2e600002,0xfffffffd,0xb802deff, + 0xffffffff,0xffffffff,0x0004ffff,0x4fffff98,0xfffec980,0x1cdeffff, + 0x654c4000,0x0000009a,0x01553000,0x001bb980,0x00003330,0x2e000000, + 0x950ccccc,0x00039999,0x554cc400,0xffb8001a,0xffffffff,0xffffffff, + 0xd00004ff,0x000fffff,0x00002662,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0xf5000000,0x0005ffff,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xfffff000,0x555554cd,0x00000000,0x77ff65d4,0x55511bce,0x80000355, + 0xaaaaaaa9,0x001aaaaa,0x26000000,0x2000000b,0x00000aa8,0x13555100, + 0x2a660000,0x000099aa,0xf7000000,0x3f23ffff,0x0002ffff,0xffd50000, + 0xffffffff,0x3ffffea9,0x7e400004,0xffffffff,0x20003fff,0x000cefea, + 0x07fff6e6,0xfdc98000,0x1cdfffff,0xdca88000,0xffffffff,0x36a000bd, + 0xffffffff,0xea81bdff,0x00000cef,0x09999980,0x05fffff9,0xe8800000, + 0xffffffff,0xff54ffff,0x00009fff,0xffffffc8,0x03ffffff,0xfffff700, + 0x3ffa001d,0x00001fff,0xfffffff7,0x009fffff,0x7ffffdc0,0xffffffff, + 0xffe9803f,0xffffffff,0x2e0fffff,0x00efffff,0x32000000,0x002fffff, + 0x7fec0000,0xffffffff,0xfff54fff,0x800009ff,0xfffffffc,0x003fffff, + 0xffffff98,0xfffd004f,0x880003ff,0xfffffffd,0xdfffffff,0x3ff62000, + 0xffffffff,0x403fffff,0xfffffffb,0xffffffff,0xffff30ff,0x00009fff, + 0x15555540,0x05fffff9,0x7d400000,0xefffffff,0xf54fffee,0x0009ffff, + 0xfffffc80,0x3fffffff,0xffffb800,0xfd007fff,0x0003ffff,0x7fffffcc, + 0xffffffff,0x9801efff,0xfffffffe,0xffffffff,0xfffd103f,0xffffffff, + 0x1fffffff,0x3fffffee,0x2000007f,0x90fffffe,0x005fffff,0x3fe20000, + 0x102fffff,0x3fffea53,0x4400004f,0xfd999999,0x8003ffff,0xfffffffc, + 0xfffe800f,0x3a0001ff,0xffffffff,0xffffffff,0x7fcc05ff,0xffffffff, + 0xffffffff,0xfffff883,0xffffffff,0x0fffffff,0xfffffff9,0x2000001f, + 0x90fffffe,0x005fffff,0x3fe60000,0x2001ffff,0x04fffffa,0x3f200000, + 0x8003ffff,0xfffffffa,0xffffd006,0x3ea0003f,0x1befffff,0xfffff951, + 0x7ff403ff,0x9bdfffff,0x7ffb5310,0xffffff90,0x4c4159df,0xf50fffca, + 0x0dffffff,0x7ff40000,0xfff90fff,0x000005ff,0x3ffffea0,0x7ffd4004, + 0x000004ff,0x3fffff20,0xfff88003,0xd003ffff,0x003fffff,0x3fffffa0, + 0x3ffee00e,0xff505fff,0x005fffff,0xfff30aa2,0x800bffff,0xffff10c9, + 0x00007fff,0x7fffff40,0x5fffff90,0x32000000,0x002fffff,0x27ffffd4, + 0xf9000000,0x0007ffff,0x17ffffe6,0xfdddddd7,0xdddfffff,0x8bdddddd, + 0x0ffffffb,0xfffffb80,0xffffe80f,0xd80001ff,0x03ffffff,0xffff3000, + 0x800000bf,0x90fffffe,0x105fffff,0x20000153,0x01fffffd,0x7ffffd40, + 0x20000004,0x03fffffc,0x0b36e200,0x3ffffff2,0xffffffff,0x6fffffff, + 0x1ffffffc,0xffffff00,0xfffffb89,0xfa80002f,0x004fffff,0x166dc400, + 0x7f400000,0xff90ffff,0x7f543fff,0x001dffff,0x3fffffa0,0x7ffd4000, + 0x76c404ff,0x001eeeee,0x0ffffff2,0xff900000,0xffffffff,0xffffffff, + 0x7fccdfff,0x2001ffff,0x46fffffd,0x07ffffff,0xffffd000,0x000001ff, + 0xd0000000,0x321fffff,0xd89fffff,0xffffffff,0xffd0003f,0xa8001fff, + 0x404fffff,0x3ffffffd,0x7fffe400,0x4000003f,0xfffffffc,0xffffffff, + 0x26ffffff,0x06fffffb,0x7ffffd40,0x3ffffe27,0xff00003f,0x0009ffff, + 0x00000000,0x3fffffa0,0x3fffff90,0xfffffffd,0x0007ffff,0x01fffffd, + 0xfffffa80,0x3ffff204,0xfc8004ff,0x0003ffff,0x77775c00,0xffffffee, + 0xeeeeeeee,0x3ffff65e,0x7fc4004f,0xff30ffff,0x0001ffff,0xffffff10, + 0x00000001,0x42660000,0x90fffffe,0xffdfffff,0xffffffff,0x26660fff, + 0xfffe9999,0x99999aff,0x3fea0999,0xff704fff,0x000bffff,0x0ffffff2, + 0xe8000000,0x001fffff,0x1ffffff4,0x7ffffc00,0xfffff51f,0x3e60000f, + 0x0007ffff,0x50000000,0xfffffdb9,0x21ffffff,0xfffffffc,0xfffeffff, + 0xff83ffff,0xffffffff,0xffffffff,0x3ea6ffff,0xf984ffff,0x006fffff, + 0x3fffff20,0x00000003,0x07fffffa,0xffffff00,0xffff0007,0x3ffee3ff, + 0x500006ff,0x40dfffff,0xaaaaaaaa,0x00000aaa,0xfffffd30,0xffffffff, + 0x3fff21ff,0x0befffff,0xbfffffd5,0xfffffff0,0xffffffff,0xdfffffff, + 0x27ffffd4,0x3fffffe2,0x3f20000e,0x0003ffff,0x3ffa0000,0x7c001fff, + 0x002fffff,0x2fffffe8,0x0bfffffb,0x3ffee000,0xfff105ff,0xffffffff, + 0xc8800003,0xffffffff,0xffffffff,0xfffff90f,0x3fea0bff,0xfff86fff, + 0xffffffff,0xffffffff,0x3fea6fff,0x3fa24fff,0x000fffff,0x7ffffe40, + 0x00000003,0x07fffffa,0xffffff00,0xfffd0003,0x3fffa7ff,0xb00004ff, + 0x209fffff,0xfffffff8,0x0001ffff,0x7fffff40,0xffffffff,0xf90fffff, + 0x01dfffff,0x1fffffe2,0x3ffffffe,0xffffffff,0x6fffffff,0x93ffffea, + 0x1ffffffd,0xfffc8000,0x2e0003ff,0x74004efe,0x001fffff,0x0ffffffc, + 0x7fffec00,0xffffff3f,0x3fa00009,0xf104ffff,0xffffffff,0x002203ff, + 0xffffff70,0xfd9959df,0x321fffff,0x00efffff,0x07fffff4,0x2aaaaaaa, + 0xabfffffe,0x2aaaaaaa,0x53ffffea,0x2ffffffc,0xfff90000,0x320007ff, + 0x00dfffff,0x3fffffd0,0xfffff800,0xffe8002f,0xfffd3fff,0x20000bff, + 0x04fffffd,0xfffffff1,0xfb83ffff,0xf8801eff,0x01ffffff,0x43fffffa, + 0x02fffffc,0x0fffffe8,0x3ffffa00,0x7fd4000f,0xfffacfff,0x00003fff, + 0x0ffffff2,0x3fffe200,0xfd004fff,0x8003ffff,0x03fffffe,0xffffff80, + 0xdfffffb2,0x3ff20000,0x2aa05fff,0xffffeaaa,0x3ffff61f,0x7fec01ff, + 0x7400efff,0xf90fffff,0xd005ffff,0x001fffff,0x07fffff4,0x3fffea00, + 0xffffffef,0x7e400003,0x8003ffff,0xfffffffa,0xfffe800f,0x7ec001ff, + 0x8003ffff,0x92ffffff,0x00ffffff,0x3fffee00,0x7fec006f,0xfff31fff, + 0x4c0bffff,0x02ffffff,0x0fffffe8,0x05fffff9,0x1fffffd0,0x7ffff400, + 0x7fd4000f,0xffffffff,0xc800006f,0x003fffff,0xffffffa8,0xffe802ff, + 0x64001fff,0x004fffff,0x7fffffc4,0xffffff71,0x3fe60000,0x6c007fff, + 0xf71fffff,0x0fffffff,0x37ffffd4,0xfffffe80,0x5fffff90,0xfffffd00, + 0x7fff4001,0x7d4000ff,0xffffffff,0x00003fff,0x1fffffe4,0x7fffc400, + 0xe803ffff,0x001fffff,0x37ffffdc,0x3fffea00,0x3fffea7f,0x880003ff, + 0x01ffffff,0x3fffff60,0xffffff91,0x7ffe40ff,0xffd003ff,0x3ff21fff, + 0xfe802fff,0x2000ffff,0x00fffffe,0x7ffffd40,0xffffffdc,0x3f200001, + 0x0003ffff,0xfffffff5,0xffffd009,0xffa8003f,0x2000ffff,0x25fffffc, + 0x6ffffff9,0xffff0000,0x7ec00bff,0xff51ffff,0x40dfffff,0x02fffffd, + 0x1fffffd0,0x0bfffff2,0x3fffffa0,0x3fffa000,0x7d4000ff,0xfe8cffff, + 0x000fffff,0xfffff900,0x7fe40007,0xe803ffff,0x001fffff,0x7fffffc4, + 0x3fffe003,0x7fffc3ff,0x80002fff,0x0ffffffe,0xfffffb00,0x7fffff43, + 0x3fffa02f,0xffd001ff,0x3ff21fff,0xfe802fff,0x2000ffff,0x00fffffe, + 0x7ffffd40,0xffffff34,0x3f20000d,0x0003ffff,0x17fffff4,0x7fffff40, + 0xfffd8002,0xfb800eff,0xfb87ffff,0x01efffff,0x7fffcc00,0xffb005ff, + 0x7f443fff,0x7fc03fff,0xd000ffff,0x321fffff,0x802fffff,0x00fffffe, + 0x3fffffa0,0x7ffd4000,0x3ffee4ff,0x80005fff,0x03fffffc,0x7fffe400, + 0xfffd800f,0xf98003ff,0x406fffff,0x3ffffffa,0xffffffd0,0x0ae2005f, + 0xdffffffb,0xffffd801,0x00aba81f,0x7fffffc4,0xffffd000,0x3ffff21f, + 0xfffe802f,0x3fa000ff,0x4000ffff,0x44fffffa,0x3ffffffd,0x7ffe4000, + 0x6c0003ff,0x7007ffff,0x01ffffff,0xfffffd00,0x7dcc15df,0x206fffff, + 0xfffffffa,0x2e609bdf,0x7fc43ffd,0xabffffff,0x7fffec40,0xff80001f, + 0xd001ffff,0x321fffff,0x802fffff,0x00fffffe,0x3fffffa0,0x7ffd4000, + 0x7ffc44ff,0x0001ffff,0x0ffffff2,0xffff8800,0xfff5002f,0x3357ffff, + 0xff50bb75,0xffffffff,0xffffffff,0xfffe805f,0xffffffff,0x3fffffff, + 0xffffffc8,0xfeefffff,0x01ffffff,0xffffe800,0xfffd001f,0x3fff21ff, + 0xffe802ff,0x3a000fff,0x000fffff,0x27ffffd4,0x7fffffd4,0xff90000f, + 0x20007fff,0x05fffff9,0x7fffff40,0xffffffff,0xfffffb06,0xffffffff, + 0x300bffff,0xfffffffd,0xffffffff,0xffd107ff,0xffffffff,0xffffffff, + 0xfb00003f,0x5007ffff,0x21ffffff,0x02fffffc,0x0fffffe8,0x3ffffa00, + 0x7fd4000f,0xff904fff,0x260dffff,0xeccccccc,0xccefffff,0x5512cccc, + 0xdfffffd7,0xfff98001,0xffffffff,0x3fee06ff,0xffffffff,0x003fffff, + 0x7fffffe4,0xffffffff,0x3fee03ff,0xffffffff,0xffffffff,0xffc80001, + 0x7cc05fff,0x90ffffff,0x005fffff,0x01fffffd,0x7fffff40,0x7ffd4000, + 0x3ffa04ff,0xfb85ffff,0xffffffff,0xffffffff,0xfff94fff,0x03dfffff, + 0x3fffee00,0xffffffff,0x7fffcc06,0xffffffff,0xfd50001e,0xffffffff, + 0x805fffff,0xffffffe9,0xffffffff,0xa80000ef,0x00ffffff,0xfffffff1, + 0x3ffff21f,0xfffe802f,0x3fa000ff,0x4000ffff,0x04fffffa,0x3fffffe2, + 0x7fffdc3f,0xffffffff,0xffffffff,0xffffff94,0x9100007f,0xffffffff, + 0xd9100bff,0xdfffffff,0xb8800019,0xffffffec,0x2000adff,0xfffffedb, + 0x00beffff,0x7fffc000,0x7f5c0eff,0x0fffffff,0x05fffff9,0x1fffffd0, + 0x7ffff400,0x7fd4000f,0x7d404fff,0x22ffffff,0xfffffffb,0xffffffff, + 0xf94fffff,0x0019dfff,0x79553000,0x44000355,0x00001aba,0x09aaa880, + 0x32a60000,0x000099aa,0x3fffee00,0xfffcdfff,0xffffffff,0x5fffff90, + 0xfffffd00,0x7fff4001,0x7d4000ff,0xc804ffff,0x0fffffff,0xfffffff7, + 0xffffffff,0x2a9fffff,0x0000009a,0x00000000,0x00000000,0x00000000, + 0xffff1000,0xffffffff,0xfffffbff,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x3ffea000,0xffffffff, + 0xfffff8df,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x3ffe6000,0x4fffffff,0x003ffffe,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xfffffb30,0xffff85df,0x0000000f,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x2e600000,0x000001ab,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x0006aa20,0x55554c40,0x44000009,0x00009aa9, + 0x4d554c40,0xffffc801,0xffffffff,0x005fffff,0x3b72ea60,0x20007fff, + 0x00009a98,0x0026a620,0x0fffffe8,0x3ffff200,0x9998002f,0xaaa98019, + 0x5c4002aa,0xefffffed,0xfb71000c,0xffffffff,0x2a0003bf,0xfffffffe, + 0xd98002ef,0xfffffffe,0xfc81ceff,0xffffffff,0xffffffff,0x7fdc4005, + 0xffffffff,0x7ff5c007,0x02efffff,0x7ff65c40,0x402dffff,0x00fffffe, + 0x3fffff20,0x3ffaa002,0xffb807ff,0x2a007fff,0xffffffff,0xd802ffff, + 0xffffffff,0x1dffffff,0xffffd500,0xffffffff,0xffb3005d,0xffffffff, + 0xf909ffff,0xffffffff,0xffffffff,0x3ff6600b,0xffffffff,0xfd5007ff, + 0xffffffff,0xf7001bff,0xffffffff,0x3a03bfff,0x000fffff,0x0bfffff2, + 0x3ffffa60,0xffb807ff,0xf7007fff,0xffffffff,0x809fffff,0xfffffffd, + 0xffffffff,0x7ffdc00f,0xffffffff,0x202fffff,0xfffffffb,0xffffffff, + 0xffffc84f,0xffffffff,0x805fffff,0xfffffff9,0x7fffffff,0x7fffec40, + 0xffffffff,0xfd302fff,0xffffffff,0x03ffffff,0x01fffffd,0x7ffffe40, + 0x3fff6602,0x807fffff,0x06fffffa,0xffffffd8,0xffffffff,0x3ff605ff, + 0xffffffff,0x06ffffff,0x3fffffe6,0xffffffff,0xfa81ffff,0xffffffff, + 0xffffffff,0xfffffc84,0xffffffff,0x5405ffff,0xffffffff,0x7fffffff, + 0x7ffffec0,0xffffffff,0x7dc0ffff,0xffffffff,0xffffffff,0xfffffe86, + 0x3fff2000,0xffd882ff,0xffffffff,0xffffa807,0x7ffe406f,0xfdbdffff, + 0x2fffffff,0xbddfffb0,0xfffffb99,0xff107fff,0x37bfffff,0xfffffb75, + 0xffff88bf,0xeeefffff,0x84ffffee,0xeefffffc,0xeeeeeeee,0x3fea04ee, + 0xccffffff,0x0199999a,0x3fffffea,0xfffeccef,0x7dc4ffff,0xefffffff, + 0xffffffff,0x7ffff44f,0x3ff2000f,0x3f222fff,0xffffffff,0xf9807fff, + 0x2205ffff,0x85ffffff,0xffffffa8,0x80159906,0x5ffffffb,0x5fffffa8, + 0x7ffffcc0,0x7ffffe47,0x6dcc01df,0x7ffffc83,0x7ff40000,0x000cffff, + 0x3ffffe20,0xffe881ef,0x7e40ffff,0x260acfff,0x7ffffffd,0x07fffff4, + 0xfffff900,0x7fffffc5,0xffffffff,0xffff9807,0x3fff205f,0x3ea00eff, + 0x001fffff,0xfffffb80,0xfffffc87,0xffffc800,0x3ffffa1f,0xf900005f, + 0x0000ffff,0x7fffffdc,0xffb80001,0x2200ffff,0x85fffffe,0x7ec01efe, + 0x3a1fffff,0x000fffff,0x8bfffff2,0xeffffffd,0x07fffffb,0x4fffff88, + 0xffffff10,0xffffb001,0xf10000df,0xd81fffff,0x7007ffff,0x7c3fffff, + 0x002fffff,0xfffff900,0x3fe20000,0x0003ffff,0x7fffffb0,0xfffff500, + 0x1004881f,0x45ffffff,0x00fffffe,0x3fffff20,0x3ffffe62,0xffffff13, + 0xfffff100,0x3fffee09,0xfff1005f,0x00003fff,0x81ffffff,0x00fffffd, + 0x0fffffc8,0x5ffffff3,0x3ff20000,0x500007ff,0x00dfffff,0x7ffff400, + 0xfff8801f,0x40002fff,0x24ffffff,0x00fffffe,0x3fffff20,0x1067ff42, + 0x00ffffff,0x40fffffe,0x01fffffe,0xffffff30,0xff880007,0xffc87fff, + 0x7c404fff,0x3e27ffff,0x004fffff,0xfffff900,0x3ff20000,0x00003fff, + 0x0ffffff1,0x7ffffec0,0x7ff40003,0x3ffa4fff,0x32000fff,0x5c2fffff, + 0xffff880d,0xffff007f,0x3fffe07f,0xfff7006f,0x000bffff,0x5fffffa8, + 0xffffffa8,0x3ffff203,0x7ffffc3f,0xc80003ff,0x0007ffff,0x3fffffd0, + 0x3fe20000,0x32007fff,0x005fffff,0x7fffff40,0x3fffffa2,0x3fff2000, + 0x3e2002ff,0xd007ffff,0xf105ffff,0x880bffff,0xfffffffd,0x3e20006f, + 0xd01fffff,0x1bffffff,0x7fffffc8,0xffffffd8,0x320002ef,0xeeefffff, + 0x8800abcc,0x517fffff,0x359bddb9,0xffffff00,0x3ffee001,0x220005ff, + 0x21ffffff,0x00fffffe,0x3fffff20,0x3ffe2002,0x997007ff,0xfff30399, + 0x7fd409ff,0xffffffff,0xffc88007,0x2a03ffff,0xffffffff,0xfffffeac, + 0xffffb81f,0x0bffffff,0x7fffe400,0xffffffff,0x3fe602df,0xfffdffff, + 0xdfffffff,0x3ffffa00,0xfff7003f,0x5c000dff,0x20ffffff,0x00fffffe, + 0x3fffff20,0x3ffe2002,0x400007ff,0x03fffffa,0xfffffff9,0x640fffff, + 0xffffeeee,0xb801efff,0xffffffff,0x1fffffff,0x3fffff60,0x2dffffff, + 0xfffff900,0xffffffff,0xff501dff,0xffffffff,0xffffffff,0x3fff609f, + 0xfc800fff,0x0006ffff,0x13fffffa,0x01fffffd,0x7ffffe40,0x3ffe2002, + 0x400007ff,0x43fffffb,0xffffffe9,0x0ffffffe,0xffffffb0,0x001bffff, + 0x7fffffdc,0x0dffffff,0x7ffffc40,0xffffffff,0x7ffe403e,0xffffffff, + 0x40efffff,0xfffffffa,0xffffffff,0xb83fffff,0xbfffffff,0x3fff2621, + 0x0006ffff,0x3ffffff7,0x0fffffe8,0x3ffff200,0x3fe2002f,0x54007fff, + 0x7fe43efd,0x3fee2fff,0xfd4fffff,0x3601ffff,0xffffffff,0x2001ceff, + 0xffffffe8,0x1004ffff,0xfffffffb,0x1dffffff,0x3fffff20,0xffffffff, + 0x2e0effff,0xffffffff,0xffffffff,0xe80fffff,0xffffffff,0xffffffff, + 0x8006ffff,0x5ffffff9,0x0fffffe8,0x3ffff200,0x3fe2002f,0x36007fff, + 0xb0efffff,0xb13fffff,0x5fffffff,0x07fffff4,0xffffffd8,0xdfffffff, + 0xffffb800,0xffffffff,0xfff7001e,0xffffffff,0x88005fff,0xfffffba9, + 0x3fee4fff,0x9befffff,0xffffb988,0xff985fff,0xffffffff,0xffffffff, + 0x744005ff,0x80efffff,0x00fffffe,0x3fffff20,0x3ffe2002,0xff7007ff, + 0x32bfffff,0xffcfffff,0x40dfffff,0x207fffff,0xfffeeeec,0xefffffff, + 0xffffd100,0xffffffff,0x54003fff,0xfffffffe,0x000fffff,0x7ffffdc0, + 0xffff90ff,0xfe8803df,0xf707ffff,0xffffffff,0xffffffff,0x744009ff, + 0x01ffffff,0x01fffffd,0x7ffffe40,0x3ffe2002,0xffd007ff,0x91ffffff, + 0xffffffff,0x3e07ffff,0x0006ffff,0xffffff93,0xfffd10bf,0xffd59fff, + 0x03ffffff,0xffffc980,0x06ffffff,0xffffc800,0xffff72ff,0x3fe600df, + 0xb301ffff,0xffffffff,0xffffddff,0x7ff4007f,0x3a03ffff,0x000fffff, + 0x0bfffff2,0xfffff880,0xfffff007,0xff75ffff,0xffffffff,0x3ffe203d, + 0xd80005ff,0x42ffffff,0x1efffffe,0x7fffffdc,0x3aa0006f,0xffffffff, + 0x7fc40002,0xff52ffff,0x7400dfff,0x402fffff,0xdefeecb9,0xfffff91c, + 0x3fff6007,0x7f403fff,0x2000ffff,0x02fffffc,0x3ffffe20,0xfffff007, + 0xff53ffff,0xbfffffff,0x7fffcc01,0xe880004f,0x2a4fffff,0x00efffff, + 0xffffffd3,0xffb80005,0x003fffff,0xffffff80,0xffffff33,0x7fffec00, + 0x3a00003f,0x802fffff,0x4ffffffd,0xfffffe80,0x3fff6000,0x3e2000ff, + 0xb007ffff,0xffffffff,0x3fffffe6,0xffa802ff,0x00003fff,0x4bfffff9, + 0x01ffffff,0x7fffffc4,0xffa80004,0x0005ffff,0x2fffffe8,0x0ffffff1, + 0x7ffffe40,0xff100003,0xfb00ffff,0x009fffff,0x07fffff6,0x7ffffe80, + 0x7fffc400,0xfff1007f,0x7fc7ffff,0x000effff,0x05fffffb,0x3ffee000, + 0xffff16ff,0x3fea00bf,0x00005fff,0x0dffffff,0xffff8800,0x3fffe0ff, + 0xffd002ff,0x00003fff,0x13ffffea,0xffffffb0,0x7ffe4009,0x3fe002ff, + 0x44006fff,0x007fffff,0x0fffffea,0x07fffffd,0x3ffffe20,0xf900000f, + 0x3ea9ffff,0x1004ffff,0x00ffffff,0x3ffff600,0x7dc0004f,0x7f47ffff, + 0x8805ffff,0x00ffffff,0xffff8800,0x3ff601ff,0x4003ffff,0x05fffffb, + 0xbfffff30,0xffff8800,0x5d44007f,0xffffa80a,0xffb800ff,0x00004fff, + 0x4ffffffa,0x04fffffb,0xdfffff10,0x3ffe0000,0x20003fff,0x5ffffff9, + 0x7fffffd4,0x7fffe400,0xfb00006f,0x6c0dffff,0x03ffffff,0xfffffa80, + 0xfffd801f,0x7c4003ff,0x0007ffff,0xfffffd00,0xffff980b,0x900000ff, + 0x23ffffff,0x06fffff9,0x9fffff50,0x7dc0006a,0x061fffff,0x7fffe440, + 0xffe82fff,0xf901ffff,0x009fffff,0xffffea80,0xfffb03ff,0x40005fff, + 0x1ffffffe,0x3fffff20,0x7fc4000f,0x00007fff,0xffffff50,0xffff3017, + 0x800109ff,0xffffffda,0x3ffffe27,0x7ffcc04f,0xbff92fff,0x7ecc0137, + 0x227fffff,0xccccdeff,0xffffffed,0xfff503ff,0x979bffff,0xdffffffd, + 0x26666620,0xfffecaa9,0xfb04ffff,0x55bfffff,0x55555555,0x7ffd4555, + 0xbaceffff,0xffffffec,0x33333302,0xffffff53,0x03333333,0xffffe800, + 0xfdbadfff,0x80ffffff,0xccccdefc,0xffffeecc,0x7f41ffff,0xbdffffff, + 0xffffca99,0xfff90fff,0xfdddffff,0xffffffff,0x7fffc45f,0xffffffff, + 0x404fffff,0xfffffffe,0xffffffff,0xfff500ff,0xffffffff,0x20bfffff, + 0xfffffffc,0xffffffff,0x746fffff,0xffffffff,0xffffffff,0xffff305f, + 0xffffffff,0xffffffff,0xffa8000f,0xffffffff,0x3fffffff,0xffffff90, + 0xffffffff,0xf305ffff,0xffffffff,0xffffffff,0x7ffe43ff,0xffffffff, + 0xffffffff,0x7ffffc44,0xffffffff,0xe8804fff,0xffffffff,0x2fffffff, + 0x3ffffea0,0xffffffff,0xffd00eff,0xffffffff,0xffffffff,0xfff98dff, + 0xffffffff,0x00efffff,0xfffffff3,0xffffffff,0x00ffffff,0xfffff500, + 0xffffffff,0x7fe403ff,0xffffffff,0x3fffffff,0x3ffffea0,0xffffffff, + 0x7e42ffff,0xffffffff,0xffffffff,0xffff885f,0xffffffff,0x64000cff, + 0xffffffff,0x400dffff,0xfffffffa,0x2fffffff,0x7fffff40,0xffffffff, + 0x6fffffff,0xfffffc88,0xffffffff,0x7fffcc03,0xffffffff,0xffffffff, + 0xfd100007,0xffffffff,0xfc801dff,0xffffffff,0x0cffffff,0xffffea80, + 0xffffffff,0xfffc82ef,0xffffffff,0x02efffff,0xfffffff1,0x019dffff, + 0x7ffed400,0x01dfffff,0xffffff50,0x07dfffff,0x3fffffa0,0xffffffff, + 0x6fffffff,0x3ffff660,0x00dfffff,0xffffff98,0xffffffff,0x07ffffff, + 0x7ff5c000,0x03dfffff,0xffffff90,0x7bffffff,0x3ffaa000,0xdfffffff, + 0x3ff6e602,0xffffffff,0x33002dff,0x01355555,0x2ea20000,0xfa80009b, + 0xceeeffff,0x7ff4000a,0xffffffff,0xffffffff,0x531006ff,0x98001359, + 0xffffffff,0xffffffff,0x0007ffff,0x02aea600,0x5554c400,0x00009aaa, + 0x56554c40,0x5310001a,0x01357955,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0xfffffff9,0xffffffff, + 0x3ffe21ff,0x2a0000ff,0xffd5ffff,0xddffffff,0xe800579b,0x00ffffff, + 0x3fffffe0,0x7ffffc0f,0xffffffff,0xffffffff,0xffffb4ff,0x7fc00dff, + 0x3fea2fff,0x4c04ffff,0x46ffffff,0x07fffffe,0x3ffffe00,0xfffffd2f, + 0xffff7003,0x7ffdcbff,0xffffffff,0xafffffff,0xfffffffc,0xffffffff, + 0xffff10ff,0x7dc0001f,0xfffd4fff,0xffffffff,0x0017ffff,0x9ffffff5, + 0x3fffee00,0xffff83ff,0xffffffff,0xffffffff,0xfffb4fff,0x2003ffff, + 0x2a2fffff,0x06ffffff,0x7fffffdc,0x7ffffe46,0xff98001f,0xffd0ffff, + 0xf8803fff,0x20ffffff,0xfffffffb,0xffffffff,0xfffcafff,0xffffffff, + 0x20ffffff,0x000fffff,0x53fffee0,0xfffffffe,0xffffffff,0xffe801ff, + 0xf800ffff,0xf07fffff,0xffffffff,0xffffffff,0x29ffffff,0xfffffffd, + 0xfffff005,0x7ffffdc5,0x3ffa00ff,0x7cc7ffff,0x003fffff,0x5fffffc8, + 0x07fffffa,0xffffffb0,0xfffffb85,0xffffffff,0xfcafffff,0xffffffff, + 0xffffffff,0x07ffffe0,0xffffb800,0xffffffd3,0xffffffff,0x9801ffff, + 0x04ffffff,0x7fffffdc,0xffffff02,0xffffffff,0xffffffff,0x3ffff69f, + 0xf801ffff,0x3ee2ffff,0x03ffffff,0xfffffff1,0xffffff0f,0xfffd000b, + 0x7fff47ff,0x3fea01ff,0xfb84ffff,0xffffffff,0xffffffff,0xfffffcaf, + 0xffffffff,0x3fe0ffff,0x20001fff,0xfd3ffffb,0xffffffff,0xffffffff, + 0xffd801df,0x3e00ffff,0x206fffff,0xffffffff,0xffffffff,0x4fffffff, + 0xfffffffb,0xffff009f,0x7fffdc5f,0xff706fff,0x90ffffff,0x00ffffff, + 0xffffff88,0x3fffffa0,0xfffff101,0x3ffee0df,0xffffffff,0x2fffffff, + 0xfffff800,0x3ffffa0f,0x3ff20001,0xffffd2ff,0x7f5ccc1f,0x02ffffff, + 0x7fffffcc,0xfffff704,0x7d40005f,0x2006ffff,0xfffffffd,0x7ffc00ff, + 0x3fff22ff,0xd80fffff,0x7fffffff,0xffffffa8,0x3ffee002,0x7fff46ff, + 0xfffb01ff,0x3ee03fff,0x999dffff,0x99999999,0xfff80009,0x3ffa0fff, + 0x320002ff,0xffd2ffff,0x7dc01fff,0x804fffff,0x0ffffffc,0x5ffffff8, + 0x7ffd4000,0x3f6006ff,0xffffffff,0x7ffffc04,0x3fffff22,0x7fc42fff, + 0x0fffffff,0x7fffffc4,0x3fff6004,0x7fff43ff,0xfffa81ff,0x3ee03fff, + 0x0004ffff,0xfffff000,0x7fffec1f,0x3ff20002,0xffffd1ff,0xfffd801f, + 0xff8805ff,0x7dc5ffff,0x001fffff,0x7ffffd40,0x3fff6006,0x0fffffff, + 0x8bffffe0,0xffeefffd,0x7fffd45f,0xd80ffffd,0x006fffff,0x07fffffe, + 0x83fffffd,0x5ffffff8,0x7ffffdc0,0xf0000004,0x6c1fffff,0x0002ffff, + 0x747ffff6,0x400fffff,0x07fffffb,0xffffff70,0x7fffffc3,0xffa80005, + 0x36006fff,0xffffffff,0x3ffe03ff,0x3fff62ff,0x6c7fffce,0xfffcdfff, + 0xffffb81f,0xff9800ff,0xffe87fff,0x7fec1fff,0x5c00ffff,0x004fffff, + 0xffff0000,0x7ffec1ff,0x0133302f,0x747ffff6,0x400fffff,0x07fffff9, + 0xffffff10,0x3ffffeeb,0xfa80000f,0x2006ffff,0xffdffffd,0x3fe06fff, + 0x3ff62fff,0x2ffffaef,0xf95ffff1,0xff103fff,0x9005ffff,0xd09fffff, + 0x543fffff,0x02ffffff,0x4fffffb8,0xff000000,0x7e41ffff,0xff983fff, + 0xffffb07f,0x3fffffa1,0x7fffdc00,0x3fee005f,0xfff9ffff,0x00004fff, + 0x0dfffff5,0x6ffffec0,0x02fffffb,0x745fffff,0xfff8efff,0x1ffff54f, + 0x203ffff9,0x05fffffe,0x2fffffe8,0x1fffffe8,0xbffffff1,0x3fffee00, + 0x0000004f,0x41ffffff,0xb83ffffc,0xfd82ffff,0xfffd0fff,0xffd801ff, + 0x74004fff,0xffffffff,0x0000ffff,0xdfffff50,0x7fffec00,0x6fffff8d, + 0x45fffff0,0xffb6fffe,0x5bfff2df,0x702ffffc,0x80ffffff,0x07fffff8, + 0x23fffffd,0x0efffffc,0xfffff700,0x20000009,0x20ffffff,0xe83ffffb, + 0xfe84ffff,0x3fffa7ff,0x3ff200ff,0x4001ffff,0xfffffffa,0x0003ffff, + 0x3ffffea0,0x3fff6006,0xfffffb5f,0x5fffff03,0xfbaffffc,0xfffe8fff, + 0x05ffff73,0x3fffffe6,0x3fffea01,0xffffd05f,0xfffff53f,0x7fdc003f, + 0x00004fff,0xffffff00,0x27fffdc1,0x1fffffe2,0xfe9ffffa,0x5440ffff, + 0x4ffffffe,0xffffb000,0x00dfffff,0xffffa800,0x3ff6006f,0xffff35ff, + 0xfffff0bf,0x9affffc5,0xfffcffff,0x7ffff70f,0x7fffffc0,0x3ffff603, + 0xffffd02f,0xfffffd3f,0xfffb8007,0x000004ff,0x1ffffff0,0x227fffd4, + 0x1ffffffa,0xfd3ffff4,0xfdddffff,0xffffffff,0x3e60001d,0xffffffff, + 0x7d400002,0x2006ffff,0x365ffffd,0x7c1fffff,0x3fe2ffff,0x3fffa5ff, + 0x3ee6ffff,0x3f203fff,0x3e06ffff,0xd00fffff,0xffdfffff,0x7000dfff, + 0xffffffff,0xffffffff,0x3fe0009f,0x3ea0ffff,0x7fec4fff,0x7f43ffff, + 0x3fffa6ff,0xffffffff,0x003fffff,0xfffffd80,0x800006ff,0x06fffffa, + 0x97ffff60,0x44fffffa,0xf12fffff,0x7fe4bfff,0x2e3fffff,0x2a03ffff, + 0x80ffffff,0x06fffff9,0x3ffffffa,0x002fffff,0xffffffb8,0xffffffff, + 0xf0004fff,0x4c1fffff,0x7fc4ffff,0x7c6fffff,0x3ffa6fff,0xffffffff, + 0x000adfff,0xfffff880,0x0001ffff,0x7ffffd40,0x3fff6006,0x7ffff45f, + 0x3ffffe0f,0x49ffff12,0xfffffffa,0x13fffea0,0x5ffffff0,0x7fffff90, + 0x7fffff40,0x0fffffff,0x7fffdc00,0xffffffff,0x004fffff,0x1ffffff0, + 0x52ffffcc,0xffffffff,0xd2ffffc1,0xffffffff,0x03dfffff,0x3fff2000, + 0x06ffffff,0x7ffd4000,0x3f6006ff,0x7fdc5fff,0x3ffe4fff,0xffff12ff, + 0xffffff89,0x27fffd46,0x3fffff60,0xfffffe84,0x3ffffa01,0xffffffaf, + 0x7ffdc005,0xffffffff,0x04ffffff,0xffffff00,0x2ffffcc1,0xfffdfff9, + 0x2ffffc7f,0xddfffffd,0xffffffff,0xff980005,0xffffffff,0x2a00002f, + 0x006fffff,0x217ffff6,0xf0ffffff,0x3e65ffff,0x7fec4fff,0x7fd43fff, + 0x7fd405ff,0x7fc47fff,0x7f406fff,0xffb9ffff,0x2002ffff,0xfffffffb, + 0xffffffff,0xff0004ff,0x7c41ffff,0x3ffe5fff,0x25ffff9f,0x3fa4ffff, + 0xf510ffff,0x01ffffff,0x7fffec00,0xffffffff,0xff500000,0x6c00dfff, + 0xfc85ffff,0xfff3ffff,0x3ffe65ff,0x7fffdc4f,0x7fffd41f,0x7fffc405, + 0x3ffea1ff,0x7ff404ff,0xfffd1fff,0x2e001fff,0x004fffff,0xffff0000, + 0x7ffc41ff,0x2ffff36f,0xf88ffffd,0x3ffa4fff,0x7fcc0fff,0x0005ffff, + 0xbffffff5,0x09ffffff,0x3ffea000,0x3f6006ff,0xff885fff,0xfff8efff, + 0xffff52ff,0x6ffff887,0x05ffff98,0x3fffffe8,0x07fffff2,0x3fffffd0, + 0x3fffffe6,0xffff7005,0x0000009f,0x03fffffe,0x3f2dffff,0xffff74ff, + 0x49ffff15,0x80fffffe,0x1ffffffb,0xffffe800,0xfffffd6f,0xf500001f, + 0x400dffff,0xb05ffffd,0xff5fffff,0x3fea5fff,0xfffe83ff,0x6ffff984, + 0xfffffb80,0x1fffffe6,0x3fffffa0,0x3fffff61,0xfffb802f,0x000004ff, + 0x7fffff88,0xfd7ffff8,0x3ffe65ff,0x3ffff9df,0x03fffffa,0x2ffffff4, + 0x3fffee00,0xffff52ff,0x50000bff,0x00dfffff,0x82ffffec,0xfdfffff9, + 0xff72ffff,0x999507ff,0xdffff301,0xfffff300,0xfffff31f,0xffffd00b, + 0x7fffc43f,0x7dc00fff,0x0004ffff,0xffff9800,0xfffff86f,0x3a0ffff8, + 0xfff9ffff,0x3ffffa3f,0xffff700f,0x3e2003ff,0x746fffff,0x02ffffff, + 0x7fffd400,0x3ff6006f,0x3ff605ff,0xffffffff,0x07ffff72,0x3fffe600, + 0xffffd007,0xfffff75f,0xffffd005,0xffffb83f,0x7fdc05ff,0x00004fff, + 0xfffffb80,0xbffffe85,0x7fe45fff,0x2ffffbff,0x03fffffa,0x7fffffc4, + 0xffff9005,0xfff985ff,0x40006fff,0x06fffffa,0x17ffff60,0xffffffa8, + 0xff72ffff,0x220005ff,0x9007ffff,0xfb9fffff,0xd001ffff,0xd03fffff, + 0x07ffffff,0x27ffffdc,0x8800b800,0x84ffffff,0xffdffffe,0x7fffcc2f, + 0x3a2ffffd,0x200fffff,0x0ffffffc,0x7ffffc40,0xffffb06f,0x540007ff, + 0x006fffff,0x017ffff6,0xfffffffd,0x3fff25ff,0xff10002f,0x3e600fff, + 0xfffeffff,0xffd005ff,0xff303fff,0x201fffff,0x04fffffb,0x2039fb00, + 0xffffffe9,0xfffffd82,0xffe80fff,0x21ffffff,0x00fffffe,0x3fffffe2, + 0x7fffec04,0xfff301ff,0x0001ffff,0x1bffffea,0x5ffffd80,0x7ffffdc0, + 0xff92ffff,0x220005ff,0x000fffff,0xffffffff,0x3a007fff,0x901fffff, + 0x0bffffff,0x13ffffee,0x7fffec00,0xffffdccd,0xffb05fff,0x20bfffff, + 0xfffffffc,0x3ffffa1f,0x7ffec00f,0xff300fff,0xd80bffff,0x04ffffff, + 0xfffff500,0x7ffec00d,0xffff805f,0xfb2fffff,0x20005fff,0x00fffff8, + 0xffffffb0,0x2001ffff,0x01fffffe,0x3ffffffa,0xfffffb83,0xfffb0004, + 0xffffffff,0x3201ffff,0x3fffffff,0xffffff30,0x7fff41ff,0x7fd400ff, + 0xfd04ffff,0x803fffff,0xfffffff9,0xfffa8001,0x3f6006ff,0xfc805fff, + 0x2fffffff,0x003ffffb,0x07ffffc0,0xfffffa80,0x2006ffff,0x01fffffe, + 0x3fffffea,0x7fffdc0f,0xffb0004f,0xffffffff,0x6407ffff,0x0fffffff, + 0x3fffffe0,0x3fffa0ff,0xffe800ff,0x7d40ffff,0x005fffff,0xbffffff9, + 0xffff5000,0x7fec00df,0xff8805ff,0xb2ffffff,0x0003ffff,0x00fffffc, + 0xffffff88,0x3a004fff,0x401fffff,0x6ffffffd,0x27ffffdc,0xffffd800, + 0xffffffff,0x7ffe401e,0x7e406fff,0x20ffffff,0x00fffffe,0xffffffb8, + 0x7fffff43,0xfff1001f,0x8005ffff,0x06fffffa,0x17ffff60,0x7ffffec0, + 0xffffd2ff,0x7ffc0003,0x3f6001ff,0x1fffffff,0x3ffffa00,0x7ffc401f, + 0x3ee3ffff,0x0004ffff,0x3fffff6a,0x7002efff,0x07ffffff,0xffffffa8, + 0x7fffff47,0xfffff000,0x7fffdcff,0x7e4005ff,0x006fffff,0x37ffffd4, + 0xbffffb00,0x3fffe600,0xfffd2fff,0x7fc0003f,0x2e002fff,0x7fffffff, + 0x7ffff400,0xfffb801f,0xff71ffff,0x00009fff,0x0026aa66,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0xffffc800,0xfa8000ff,0x7fc7ffff,0xffffffff, + 0xffffffff,0xfff95fff,0x7f4005ff,0x5400ffff,0xff02ffff,0x3fee0dff, + 0xffffffff,0xffffffff,0xffffffd5,0x3579dfff,0xffff8800,0x7f40006f, + 0xffffffff,0x001bcdee,0xfffff900,0x6c001fff,0xffffffff,0x009accef, + 0x7ffffc40,0xffe8004f,0x7ffc3fff,0xffffffff,0xffffffff,0xffff95ff, + 0x7ff4005f,0x7dc00fff,0xfff01fff,0x3ffee0bf,0xffffffff,0x5fffffff, + 0xfffffffd,0xffffffff,0xfff10019,0xe8000dff,0xffffffff,0xefffffff, + 0x3fa0000b,0x2fffffff,0x3ffff600,0xffffffff,0x2000cfff,0x0ffffffc, + 0x3fffea00,0xfffff87f,0xffffffff,0xffffffff,0x5fffff95,0x7ffff400, + 0x7ffe400f,0xffff881f,0xfffff704,0xffffffff,0x3abfffff,0xffffffff, + 0xffffffff,0x7ffc402f,0x740006ff,0xffffffff,0xffffffff,0xf88000ef, + 0xffffffff,0x3fff6004,0xffffffff,0x04ffffff,0xffffff10,0x7fff4007, + 0xffff83ff,0xffffffff,0xffffffff,0xfffff95f,0x7fff4005,0x7fe400ff, + 0xfff980ff,0xffff703f,0xffffffff,0x2bffffff,0xfffffffe,0xffffffff, + 0xf100efff,0x000dffff,0xffffffe8,0xffffffff,0x8006ffff,0xfffffffb, + 0x3f6007ff,0xffffffff,0xffffffff,0xfff9005f,0x3ea00fff,0xff06ffff, + 0xffffffff,0xffffffff,0x3ff2bfff,0x3a002fff,0x400fffff,0xf507fffd, + 0x3ee07fff,0xffffffff,0xffffffff,0xfffffd5f,0xffffffff,0x0dffffff, + 0x1bffffe2,0xffffd000,0xfffddddf,0x9fffffff,0xffffd800,0x01ffffff, + 0xffffffb0,0xffffffff,0x007fffff,0x7ffffff1,0xfffffd00,0x33333207, + 0xcccccccc,0xfffffffc,0x5fffff92,0x7ffff400,0x7fff400f,0x5ffff707, + 0x3ffffee0,0x9999999d,0xfd099999,0x3333ffff,0xfffffb75,0xff107fff, + 0x8000dfff,0x00fffffe,0xffffffb5,0xffff800d,0x3fffffff,0xfffffb00, + 0xfffba985,0x801fffff,0x06fffffc,0x37ffffd4,0x3fee0000,0x3f25ffff, + 0x2002ffff,0x00fffffe,0xb837fffc,0xf701ffff,0x0009ffff,0x07fffff4, + 0xfffffd10,0xfff881ff,0x740006ff,0x400fffff,0x0ffffffd,0xfffff500, + 0x0dfffffb,0x3fffff60,0x3fff2202,0xf8805fff,0x202fffff,0x02fffffe, + 0x3ffe2000,0x3f20ffff,0x2002ffff,0x20fffffe,0xfff99998,0xd99999df, + 0x999affff,0x9fffff70,0x7fff4000,0xffc800ff,0x7c44ffff,0x0006ffff, + 0x07fffff4,0x3ffffe20,0xfff9001f,0xfffff1ff,0xfffb001f,0xffd005ff, + 0x3200dfff,0x506fffff,0x00dfffff,0xffffe800,0x7ffe42ff,0x3fa002ff, + 0x3f60ffff,0xffffffff,0xffffffff,0x73ffffff,0x009fffff,0x7fffff40, + 0xffffd000,0x7ffc41ff,0x740006ff,0x800fffff,0x01ffffff,0x2bffffd0, + 0x02fffffd,0x2fffffd8,0xfffff980,0xfff8800f,0xffe82fff,0x00002fff, + 0x3fffffee,0xfffffc84,0x3fffa002,0x3fff60ff,0xffffffff,0xffffffff, + 0xff73ffff,0x40009fff,0x00fffffe,0xffffff70,0x7ffffc47,0x7ff40006, + 0xff800fff,0x9800ffff,0xf73fffff,0xb00bffff,0x005fffff,0x3ffffff1, + 0x3ffff200,0x7fffd46f,0x2200006f,0x0fffffff,0x2fffffc8,0x3ffffa00, + 0x3ffff60f,0xffffffff,0xffffffff,0xfff73fff,0x740009ff,0x000fffff, + 0x9ffffff1,0x37ffffc4,0x3fffa000,0x7fcc00ff,0xf7006fff,0x3e63ffff, + 0xd807ffff,0x002fffff,0x05fffffd,0x3ffffe20,0x3ffffa1f,0x3a00002f, + 0x02ffffff,0x05fffff9,0x7fffff40,0x3fffff60,0xffffffff,0xffffffff, + 0xffff73ff,0x7f40009f,0x2000ffff,0x26fffffd,0x06fffff8,0x7ffff400, + 0x7fff400f,0xffb003ff,0xffff8fff,0x7fec01ff,0xff002fff,0x4003ffff, + 0x35fffffc,0x00dfffff,0x7fffdc00,0x3ff204ff,0x3a002fff,0x220fffff, + 0xffffc999,0xffa9999a,0x09999dff,0x09fffff7,0x7ffff400,0x3ff2000f, + 0x3fe27fff,0x40006fff,0x00fffffe,0xdfffffd3,0x3fffe200,0x7fffe44f, + 0x7ffec04f,0xff8802ff,0x44007fff,0xd8ffffff,0x002fffff,0xfffff100, + 0x7fe401df,0xffffffff,0xffffffff,0x3200ffff,0xf980ffff,0x3ee03fff, + 0xeeefffff,0xeeeeeeee,0xfffffd0e,0x7ffdc001,0x3ffe27ff,0x740006ff, + 0xeeefffff,0xffffffee,0xff5000ef,0xffa85fff,0x7ec06fff,0xb802ffff, + 0x006fffff,0xdfffffc8,0x006fffff,0x3ffffa00,0x7fe401ff,0xffffffff, + 0xffffffff,0x3600ffff,0xff507fff,0x7fdc07ff,0xffffffff,0xffffffff, + 0x1fffffd0,0x7fffd400,0xffff10ff,0xfe8000df,0xffffffff,0x3fffffff, + 0x7fffe400,0x7fffc40f,0x3ff600ff,0x7c402fff,0x005fffff,0xffffff88, + 0x002fffff,0xfffff700,0xfff9009f,0xffffffff,0xffffffff,0x7f401fff, + 0xfff706ff,0x7ffdc05f,0xffffffff,0x0fffffff,0x01fffffd,0x7ffffcc0, + 0xfffff10f,0xffe8000d,0xffffffff,0x2dffffff,0x3ffffe00,0xfffffd06, + 0x7fffec07,0x3ffa602f,0x0001ffff,0xfffffff9,0x20000dff,0x6ffffff8, + 0xfffff900,0xffffffff,0xffffffff,0x7fffc01f,0x3ffff706,0x7ffffdc0, + 0xffffffff,0xfd0fffff,0x4001ffff,0x0ffffff9,0x0dfffff1,0xffffe800, + 0xffffffff,0x0dffffff,0x7ffffcc0,0xfffff904,0x7fffec0b,0xdba999bf, + 0x3fffffff,0x3ffe2000,0x02ffffff,0xffffb000,0x3f2003ff,0xffffffff, + 0xffffffff,0x200fffff,0xf905ffff,0x7dc01fff,0xffffffff,0xffffffff, + 0xfffffd0f,0x7ffd4001,0x3ffe27ff,0x740006ff,0xeeefffff,0xfffffffe, + 0x7e406fff,0xf301ffff,0x6c0fffff,0xffffffff,0xffffffff,0xc80006ff, + 0x6fffffff,0xfff70000,0x64009fff,0x99bfffff,0x99999999,0x00fffffe, + 0x209ffff1,0x5c07fffd,0x004fffff,0x3fffffa0,0x3ffee000,0x3ffe26ff, + 0x740006ff,0x300fffff,0xfffffff9,0x7ffff409,0x7ffffc07,0xffffb02f, + 0xffffffff,0x01dfffff,0xffff1000,0x00005fff,0xdffffff1,0xffffc800, + 0x3ffa002f,0xdddb0fff,0xdddffffd,0xfffffddd,0x7dc1dddd,0x0004ffff, + 0x03fffffa,0xfffffc80,0x3ffffe24,0x7ff40006,0x7c400fff,0x80ffffff, + 0x05fffff8,0x27ffffec,0xffffffd8,0xffffffff,0x400003ff,0x06fffffc, + 0xffffb000,0xfc8003ff,0x2002ffff,0xf0fffffe,0xffffffff,0xffffffff, + 0x1fffffff,0x27ffffdc,0xffffd000,0x7fec001f,0x3fe23fff,0x40006fff, + 0x00fffffe,0xffffff98,0xfffffb81,0x9999999c,0x07fffffc,0xfffffffb, + 0x9fffffff,0xf5000001,0x000bffff,0xffffff70,0xfff90007,0x7f4005ff, + 0xfff0ffff,0xffffffff,0xffffffff,0x5c1fffff,0x004fffff,0x3fffffa0, + 0xffff1000,0x7ffc45ff,0x740006ff,0x000fffff,0x07ffffff,0xfffffffb, + 0xffffffff,0xb03fffff,0xdddfffff,0x0001359b,0xffffa800,0x7c40005f, + 0x006fffff,0x5fffff90,0x7ffff400,0xffffff0f,0xffffffff,0xffffffff, + 0x7ffdc1ff,0x3a0004ff,0x000fffff,0x1ffffff9,0x37ffffc4,0x3fffa000, + 0xffd000ff,0xfff07fff,0xffffffff,0xffffffff,0xfffb07ff,0x000005ff, + 0x7fffd400,0x7ec0005f,0x001fffff,0x5fffff90,0x7ffff400,0xfd99990f, + 0x99999fff,0x99bffffb,0x7ffdc199,0x3a0004ff,0x800fffff,0x4ffffff8, + 0x37ffffc4,0x3fffa000,0xff8800ff,0x7cc2ffff,0xffffffff,0xffffffff, + 0xfd85ffff,0x0002ffff,0x3fea0000,0x20005fff,0x3ffffffb,0x3fff2000, + 0x3fa002ff,0xfb00ffff,0x3fea0fff,0x7fdc02ff,0x20004fff,0x00fffffe, + 0x7ffffec4,0x7fffc40f,0x7f40006f,0xb800ffff,0x40ffffff,0xfffffffc, + 0xffffffff,0x0fffffff,0x17ffffec,0x50000000,0x00bfffff,0x3ffffe20, + 0x7e40006f,0x2002ffff,0x00fffffe,0x2e0dfffd,0x5c01ffff,0x004fffff, + 0x3fffffa0,0x3fffa600,0xff883fff,0x40006fff,0x00fffffe,0x7fffffcc, + 0xfffffe87,0xeeeeeeee,0xfffffeee,0x7fffec2f,0x0000002f,0x3ffffea0, + 0xfffb0005,0x55559fff,0x55555555,0x3ffff255,0x3ffa002f,0xfff00fff, + 0x3fff20bf,0x7ffdc01f,0x3a0004ff,0x220fffff,0xfffffdba,0xff880fff, + 0x9999ffff,0x99999999,0xfffffd09,0xfff93101,0xf88bffff,0x4004ffff, + 0x44fffffd,0x02fffffd,0x2a000000,0x005fffff,0xffffffa8,0xffffffff, + 0x7fffffff,0x05fffff9,0x7fffff40,0x5ffff880,0x01ffff90,0xffffffb8, + 0xffffffff,0xffd5ffff,0xffffffff,0xffffffff,0x3ffe205f,0xffffffff, + 0xffffffff,0xffffffd2,0xffffffff,0x81dfffff,0x02fffffb,0x7ffffdc0, + 0x7ffffec7,0x00000002,0x17ffffea,0x3fffee00,0xffffffff,0xffffffff, + 0xfffff97f,0x7fff4005,0xfff980ff,0xffffb04f,0xfffff700,0xffffffff, + 0x3abfffff,0xffffffff,0xffffffff,0x3fe202ff,0xffffffff,0xffffffff, + 0xfffffd2f,0xffffffff,0x03ffffff,0x01fffffb,0xfffff980,0x3ffff61f, + 0x0000002f,0x3ffffea0,0xfffb8005,0xffffffff,0xffffffff,0xffff97ff, + 0x7ff4005f,0xff980fff,0xfffd03ff,0xffff700d,0xffffffff,0x2bffffff, + 0xfffffffe,0xffffffff,0x7fc401ef,0xffffffff,0xffffffff,0xfffffd2f, + 0xffffffff,0x105fffff,0x00bfffff,0x3fffffe0,0x3fffff64,0x00000002, + 0x17ffffea,0x3fffee00,0xffffffff,0xffffffff,0xfffff97f,0x7fff4005, + 0xfffa80ff,0xdffff02f,0xfffff700,0xffffffff,0x3abfffff,0xffffffff, + 0x2effffff,0xfffff100,0xffffffff,0x25ffffff,0xfffffffe,0xffffffff, + 0x3ffea02e,0xf90003ff,0x7ecdffff,0x0002ffff,0x3fea0000,0xb8005fff, + 0xffffffff,0xffffffff,0xf97fffff,0x4005ffff,0x80fffffe,0x881ffffb, + 0xb805ffff,0xffffffff,0xffffffff,0xffffd5ff,0x9ddfffff,0xff880015, + 0xffffffff,0xffffffff,0xfffffd2f,0x9bdfffff,0xfff90037,0x2a0003ff, + 0xb0ffffff,0x005fffff,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x7fffd400,0xffffffff, + 0x6fffffff,0xfffffff5,0xffffffff,0x0bffffff,0x7ffff400,0x00004fff, + 0x00000000,0x00266000,0x00260000,0x00099800,0x999a9800,0x54cc0000, + 0x00000009,0xffffffa8,0xffffffff,0xf56fffff,0xffffffff,0xffffffff, + 0x000bffff,0x3fffffee,0x5d1004ff,0x80000000,0x5c4004d8,0xdfffffed, + 0x2a20000c,0xfffffedb,0xca800bde,0xcdfffffe,0x7f644000,0xffffffff, + 0x7f5cc04e,0xefffffff,0x7e44001d,0x7fd402df,0xffffffff,0xffffffff, + 0xfffff56f,0xffffffff,0xffffffff,0xfff1000b,0x09ffffff,0x007ffd10, + 0x3a200000,0xff7004ff,0xffffffff,0xf50007ff,0xffffffff,0x4405ffff, + 0xfffffffd,0x8802ffff,0xfffffffc,0x07ffffff,0xfffffff5,0xffffffff, + 0x3ffa003b,0x3ea04fff,0xffffffff,0xffffffff,0xffff56ff,0xffffffff, + 0xffffffff,0xffb000bf,0x9fffffff,0xffffe880,0x40000004,0x04fffff9, + 0x3fffff62,0xffffffff,0xfd8801ef,0xffffffff,0x302fffff,0xfffffffd, + 0x1bffffff,0x3ffffa20,0xffffffff,0xfff507ff,0xffffffff,0x01ffffff, + 0xffffffa8,0xffff502f,0xffffffff,0xdfffffff,0x3fffffea,0xffffffff, + 0x5fffffff,0x7fffcc00,0x04ffffff,0x7ffffff4,0x8000000d,0xfffffffa, + 0xfffff883,0xffffffff,0x4c06ffff,0xffffffff,0xffffffff,0xfffffa82, + 0xffffffff,0xffd04fff,0xffffffff,0x20ffffff,0xfffffffa,0xffffffff, + 0x7fe405ff,0x005fffff,0x5fffff98,0xeeeeea80,0xeeeeeeee,0xffffffee, + 0x7fff4004,0x4fffffff,0x7ffffd40,0x00000eff,0x3fffff20,0xfffb05ff, + 0xffdfffff,0x7fffffff,0x7fffff40,0xffffffff,0xffe82fff,0xa99aefff, + 0x1ffffffe,0x7fffffe4,0xb75331bd,0x3ffea0ff,0xba99aacd,0x2fffffff, + 0x3fffff20,0x4c000fff,0x005fffff,0x7ffd4000,0x2e000fff,0xffcfffff, + 0xe9804fff,0x1fffffff,0xffd80000,0x304fffff,0x5dffffff,0x7fffdc41, + 0xffb80fff,0x0acfffff,0x70bfae62,0x409fffff,0x46fffffc,0x06fffffe, + 0x056d4020,0x7ffff440,0x3ffea04f,0x001fffff,0x2fffffcc,0x3fa00000, + 0x2005ffff,0x8efffff8,0x004fffff,0xffffffb1,0x2200007f,0xfffffffe, + 0x3ffffa02,0x3fe600ef,0x7cc5ffff,0x02ffffff,0x7ffc4130,0xffe805ff, + 0x3ffe2fff,0x00002fff,0xffff3000,0xfffd80bf,0x4002ffff,0x05fffff9, + 0x3fea0000,0x2001ffff,0x89fffffd,0x004fffff,0x7fffffe4,0x74c0004f, + 0x1effffff,0x3ffffea0,0xfffc800f,0x7ffec7ff,0x20001fff,0x01fffffc, + 0x3fffffa8,0x7ffffff1,0x40000000,0x807fffff,0x1ffffffe,0x7fffcc00, + 0x2000005f,0x05fffffe,0x3ffffea0,0x9fffff14,0xffff7000,0x0001bfff, + 0xfffffff5,0xfffc801d,0xff1005ff,0x7fc1ffff,0x0004ffff,0x03fffff4, + 0x4fffff98,0x3ffffffe,0x0000000b,0x07ffffe8,0x7fffff98,0xffff9800, + 0x5000005f,0x03ffffff,0x37ffff40,0x09fffff1,0x3fffea00,0x2000efff, + 0xfffffffb,0xffffb004,0x7ff4005f,0xfff11fff,0x80001fff,0x99efffff, + 0x99999999,0x365fffff,0xffffffff,0x2000001c,0xffff9999,0xffff007f, + 0xff3000df,0x0000bfff,0x3fffffa0,0x3fff2005,0x3ffe21ff,0x260004ff, + 0xfffffffe,0xffffc801,0x3a003fff,0x000fffff,0x4ffffff6,0x07fffffa, + 0x7fffc400,0xffffffff,0xffffffff,0x3fffe67f,0xcfffffff,0xdb910001, + 0xffffffff,0xf100ffff,0x0009ffff,0x0bfffff3,0xfff50000,0x22003fff, + 0x445fffff,0x004fffff,0x7fffec40,0xfb102fff,0x05ffffff,0xffffff80, + 0x3fff2000,0xffff74ff,0xf98000df,0xffffffff,0xffffffff,0x7e47ffff, + 0xffffffff,0x800befff,0xffffffd9,0xffffffff,0xfffb807f,0xf98000ff, + 0x0005ffff,0xfffffd80,0x3fff6006,0x7ffc40ff,0x900004ff,0x7fffffff, + 0xfffffe88,0x7c4000ef,0x4007ffff,0xb5fffffb,0x00bfffff,0xfffffa80, + 0xffffffff,0xffffffff,0xfffffa87,0xffffffff,0x3fff601e,0xffffffff, + 0x07ffffff,0x17ffffdc,0xffff9800,0x4c00005f,0x02ffffff,0x5fffff50, + 0x9fffff10,0x7fdc0000,0xf34fffff,0x1dffffff,0xffff1000,0xffc800ff, + 0xfff94fff,0xb8000bff,0xffffffff,0xffffffff,0x106fffff,0xfffffff9, + 0x05ffffff,0xfffffff9,0xffffffff,0x554cffff,0x5ffffffc,0x3ffe6000, + 0x400005ff,0x06fffffd,0xbfffff10,0x3ffffe20,0xfd100004,0x41dfffff, + 0xfffffffb,0xffff0004,0x7e4001ff,0xff72ffff,0x8000ffff,0x9dfffff9, + 0x99999999,0x00999999,0xfffffc98,0x20ffffff,0xfffffffa,0xfffe809b, + 0x3ffffa7f,0x000dffff,0x3ffffe60,0x3e600005,0x002fffff,0x01fffff9, + 0x13ffffe2,0x3ffea000,0xa80dffff,0xdfffffff,0x7fff4000,0x3fa001ff, + 0xff51ffff,0x0001ffff,0x2fffffc4,0x26000000,0xfffffffc,0x3ffff63f, + 0xfffe806f,0x3ffffa7f,0x80001eff,0x05fffff9,0x3fff6000,0xff3006ff, + 0x7c407fff,0x0004ffff,0x7fffffdc,0x7ffcc04f,0x000effff,0x13fffff6, + 0x7ffffc40,0xfffff10f,0xff80009f,0x00007fff,0xfffb1000,0x7ffc9fff, + 0xfe801fff,0x3ffa7fff,0x00002eff,0x17ffffe6,0x7ffcc000,0xfd003fff, + 0xf880dfff,0x0004ffff,0x3ffffff2,0xffd1003f,0x005fffff,0x3ffffff2, + 0xffffc800,0x7ffffc7f,0x3a0000ff,0x002fffff,0x3fa00000,0xff36ffff, + 0xf100ffff,0x55cfffff,0x30000009,0x00bfffff,0x3ffff600,0xfff7006f, + 0xff8803ff,0x88004fff,0xfffffffe,0x7fec4002,0x803fffff,0x4ffffffa, + 0x7ffffcc0,0x7fffec3f,0x82001eff,0x0ffffffc,0xb0000000,0x269fffff, + 0x01ffffff,0x3fffffe6,0x40000007,0x05fffff9,0xffff8800,0xfff003ff, + 0xdddddfff,0xffffdddd,0x05ddddff,0x7fffff4c,0x320001ef,0x4fffffff, + 0xfffffd80,0xfffa80df,0xff886fff,0x0bffffff,0x7c47d730,0x01efffff, + 0x01c88620,0x3ffffea0,0xfffff12f,0x3ffea09f,0x3f67ffff,0xffffffff, + 0x001fffff,0x0bfffff3,0xffff9000,0x7ffc00ff,0xffffffff,0xffffffff, + 0x03ffffff,0xfffffff5,0xf700001d,0x1bffffff,0x7ffffcc0,0xffdcefff, + 0x02ffffff,0xfffffff7,0xffdddfff,0xfffb87ff,0x9abdffff,0x4ffdbaa9, + 0x2ab7ffe2,0x3ffee609,0x3fe0ffff,0x9bdfffff,0xffffffeb,0x3fffa7ff, + 0xffffffff,0xf3001fff,0x000bffff,0xffffff88,0x3fffe003,0xffffffff, + 0xffffffff,0xb83fffff,0x5fffffff,0x7fcc0000,0x01efffff,0x3ffffff2, + 0xffffffff,0x7f405fff,0xffffffff,0x3fffffff,0xffffffe8,0xffffffff, + 0x3fe24fff,0xffffffff,0xffffffff,0x7ffffdc5,0xffffffff,0x27ffffff, + 0xfffffffe,0x1fffffff,0xfffff300,0xffc8000b,0x2000ffff,0xffffffff, + 0xffffffff,0xffffffff,0x7fffec3f,0x00003fff,0xfffffd10,0x3f6205ff, + 0xffffffff,0x04ffffff,0xfffffd88,0xffffffff,0xffe883ff,0xffffffff, + 0x24ffffff,0xfffffff8,0xffffffff,0xfffd05ff,0xffffffff,0xfffff3df, + 0x7ffffff4,0xffffffff,0xffff3001,0x7c4000bf,0x004fffff,0x7ffffffc, + 0xffffffff,0xffffffff,0x3fffa3ff,0x0002ffff,0x7ffec400,0x2a02ffff, + 0xffffffff,0x002fffff,0x7fffffd4,0xffffffff,0x3fffee03,0xffffffff, + 0x3fe24fff,0xffffffff,0x04ffffff,0x3fffffe6,0x88dfffff,0x3fa7ffff, + 0xffffffff,0x001fffff,0x0bfffff3,0x7fffe400,0x664000ff,0xcccccccc, + 0xfffdcccc,0x1cccceff,0x3fffffee,0x20000001,0x0efffffc,0x7fff6440, + 0x00ceffff,0x3fffae00,0x2cefffff,0xffffd880,0xefffffff,0x3ffb621c, + 0xffffffff,0xc8800bef,0xdfffffff,0x9ffffe22,0xaaaaaaa9,0x0aaaaaaa, + 0xfffff300,0x3fe2000b,0x0004ffff,0x3ffe6000,0xffb804ff,0x000000ef, + 0x0efffb80,0x55d4c400,0x31000001,0x00013355,0xaabcca98,0x2aaa6001, + 0x0019abcb,0x15595310,0x40000000,0xfffffffa,0xffffffff,0x3206ffff, + 0x00ffffff,0x3e600000,0x7004ffff,0x000001bf,0x0077d400,0x00000000, + 0x00000000,0x00000000,0x00000000,0x3ffffea0,0xffffffff,0x06ffffff, + 0x9ffffff1,0x98000000,0x004fffff,0x0000000a,0x000004c0,0x00000000, + 0x00000000,0x00000000,0x54000000,0xffffffff,0xffffffff,0xff706fff, + 0x0001ffff,0xfff98000,0x000004ff,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x3ffffea0,0xffffffff,0x06ffffff,0x0bffffff, + 0xf3000000,0x0009ffff,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x7ffd4000,0xffffffff,0xffffffff,0xfffffb86,0x0000001f, + 0x4fffff98,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x000054c4,0x31004cc4,0x26200001, + 0xeeeb800a,0xeed801ee,0xddd30eee,0x70003ddd,0x009ddddd,0x01333330, + 0xeeeeea80,0x3bae004e,0x3bb25eee,0x440005ee,0x3a0eeeee,0xeeeeeeee, + 0xeeeeeeee,0x553003ee,0x75c00155,0x7ed44eee,0x701dffff,0x7fdcbddd, + 0x7fec44ff,0xeeeb83ff,0x7fff543e,0xff901dff,0xfd003fff,0x7f41ffff, + 0x8005ffff,0x03fffffe,0x3fffff80,0xffffd800,0xff9802ff,0x3f22ffff, + 0x40007fff,0x7c7ffff9,0xffffffff,0xffffffff,0xffb004ff,0x7e4003ff, + 0xffb16fff,0x7fffffff,0x32dfff90,0x13ffffff,0x9ffffffd,0x14ffffc8, + 0xfffffffb,0xfff907ff,0xffd003ff,0x7fdc1fff,0x2000ffff,0x0ffffff9, + 0xfffff800,0xfff88003,0x7400ffff,0x5c5fffff,0x000fffff,0x1ffffea0, + 0xffffffff,0xffffffff,0x32009fff,0x2000ffff,0xe8fffffc,0xffffffff, + 0x7fe44fff,0xfffff9ef,0xffffb6ff,0x7e41ffff,0xfff8cfff,0xffffffff, + 0x7fffe43f,0xfffe801f,0x3ffe20ff,0x32002fff,0x005fffff,0x07fffff0, + 0x3fffea00,0x3ff205ff,0x7d40ffff,0x0001ffff,0xf17fffee,0xffffffff, + 0xffffffff,0xf70089ff,0x64020fff,0xffdfffff,0xffffffff,0x3ff20fff, + 0xfffffeff,0xffffcfff,0x323fffff,0xffedffff,0xffffffff,0x7ffe47ff, + 0xffe801ff,0x7fec0fff,0x3e005fff,0x002fffff,0x07fffff0,0x7fffe400, + 0xfff983ff,0xff981fff,0x20002fff,0x7c4ffffc,0xffffffff,0xffffffff, + 0x2076c3ff,0xfb87fffb,0xfffffc81,0xedffffff,0x23ffffff,0xfffffffc, + 0xffffffdc,0xffffebff,0x3fffff25,0xfeffffff,0x23ffffff,0x01fffffc, + 0x0fffffe8,0x7fffffd4,0xffff9800,0x3fe0006f,0x40003fff,0x0ffffffe, + 0x27fffff4,0x07fffff0,0x7fffec00,0x4cccccc3,0xffb99999,0x7cc5ffff, + 0x3ffea2ff,0x21bff626,0xfffffffc,0x7ffec2ef,0x3fff26ff,0x3ffe2fff, + 0xff50efff,0x7ffe4dff,0x0befffff,0xbfffffd5,0x0fffffe4,0x7fffff40, + 0xffffff80,0xffffc803,0x3fe0003f,0x40003fff,0x6ffffff9,0x1bfffff2, + 0x09ffffd0,0x7fffec00,0xfff10002,0xfe81ffff,0xfff34fff,0x3ffffe6b, + 0x7ffffe42,0xfff105ff,0x7ffe4fff,0x7fff45ff,0x3ffe22ff,0x3ffff27f, + 0xff505fff,0x7fe4dfff,0xfe801fff,0xfb80ffff,0xf806ffff,0x000fffff, + 0x0fffffe0,0x3ffee000,0xfff9bfff,0x7ec01fff,0xffc85fff,0xfffe81ff, + 0xffd0001f,0xfb83ffff,0xfaefffff,0xffffcdff,0x7ffe46ff,0x7f406fff, + 0xff90ffff,0xffe83fff,0x7ffc46ff,0x3ffff27f,0xff100eff,0x7fe4ffff, + 0xfe801fff,0xf880ffff,0x201fffff,0x05fffffa,0x7ffffc00,0xffb00003, + 0xfffdffff,0xff9007ff,0xfffd0dff,0xfffff09f,0xfffb0001,0x3ae07fff, + 0xffffffff,0xffffffff,0x7fffe41d,0x7fec00ff,0xfff91fff,0xffffb0bf, + 0x7ffff887,0x3bfffff2,0x7ffff400,0xfffff90f,0xffffd003,0x3fff601f, + 0x3ff604ff,0x40002fff,0x003fffff,0xfffff100,0x0dffffff,0x1ffffee0, + 0x8ffffff3,0x007ffff8,0xffffffb8,0xfffea805,0xffffffff,0xfff900cf, + 0xdd7007ff,0x3ff23ddd,0xfffd84ff,0x7fffc41f,0x3fffff27,0xffffe802, + 0xfffff90f,0xffffd003,0x3ffea01f,0xfff107ff,0x77440fff,0xfeeeeeee, + 0xeeeeffff,0x003eeeee,0xfffffff5,0x2a001fff,0x320fffff,0x21ffffff, + 0x006ffff9,0x7fffffcc,0x3f66000e,0xbfffffff,0x7fffe400,0xfc80003f, + 0xffd84fff,0x7ffc41ff,0x3ffff27f,0xfffe802f,0xffff90ff,0xfffd003f, + 0x7ffc01ff,0xffb82fff,0x3e204fff,0xffffffff,0xffffffff,0x04ffffff, + 0x3fffff20,0x26003fff,0x3a1fffff,0x24ffffff,0x005ffff9,0x3fffffe2, + 0x7e4c001f,0x2effffff,0xfffffc80,0xffc80003,0xfffd84ff,0x7fffc41f, + 0x3fffff27,0xffffe802,0xfffff90f,0xffffd003,0x7ffe401f,0xfffe85ff, + 0x3fe200ff,0xffffffff,0xffffffff,0x004fffff,0x3fffffe2,0xfff8007f, + 0xffff32ff,0x7fd4ffff,0x3f6004ff,0x002fffff,0x3fffff66,0xbfffffff, + 0xfffff900,0xff900007,0xfffb09ff,0xffff883f,0x3fffff27,0xffffe802, + 0xfffff90f,0xffffd003,0x7ffc401f,0x3fe60fff,0x7c406fff,0xffffffff, + 0xffffffff,0x04ffffff,0x3fffff20,0x74003fff,0xff93ffff,0x25ffffff, + 0x002ffffb,0x9ffffff9,0x3fffaa00,0xffffffff,0x40cfffff,0x03fffffc, + 0xffffc800,0x1ffffd84,0x93ffffc4,0x005fffff,0x21fffffd,0x01fffffc, + 0x0fffffe8,0x7ffffec0,0x3fffff22,0x7fffc402,0xffffffff,0xffffffff, + 0xf5004fff,0xffffffff,0x7fec003f,0xdfffd4ff,0x3f2bffff,0xfa801fff, + 0x006fffff,0xfffffff7,0xffbbfff7,0xfc8fffff,0x0003ffff,0x84ffffc8, + 0x441ffffd,0x3f27ffff,0xe802ffff,0xf90fffff,0xd003ffff,0x801fffff, + 0x25fffffa,0x007fffff,0x33333333,0x39fffff3,0x13333333,0xfffff100, + 0x0dffffff,0x6ffffe40,0xffaffff9,0xfffd8fff,0x7ffc400f,0x2000ffff, + 0x98dffffe,0xfff55fff,0xfffc87ff,0xc80003ff,0xfd84ffff,0x7fc41fff, + 0x3fff27ff,0xffe802ff,0xfff90fff,0xffa805ff,0xf800ffff,0xf98fffff, + 0x0004ffff,0x0fffffe0,0x7fff4000,0xfffffeff,0xfff7004f,0x1ffff7df, + 0xfd5ffffb,0xffd00fff,0x8005ffff,0x3ea3fffa,0x3ffa26ff,0xfffffc86, + 0xffc80003,0xfffd84ff,0x7fffc41f,0x3fffff27,0xffffe802,0xfffff90f, + 0x7fffcc09,0xfc800fff,0xffcbffff,0x00001fff,0x00fffffe,0x3ffff200, + 0xffffd8ff,0xffa802ff,0x5fffdfff,0xffbffff5,0xffc80dff,0x0003ffff, + 0xfffa83db,0xfc81fc86,0x0003ffff,0x84ffffc8,0x441ffffd,0x3f27ffff, + 0xe802ffff,0xf70fffff,0x220dffff,0xffffffff,0xffff9800,0x6fffffef, + 0x7ffc0000,0x540003ff,0x13ffffff,0x1fffffff,0xfffff980,0xff13ffff, + 0xbfffffff,0x7ffffdc0,0x4020005f,0x0307fffb,0x0ffffff2,0x3fff2000, + 0xffffd84f,0x3ffffc41,0x05fffff9,0x1fffffd0,0x3fffffea,0x3fffee22, + 0x000fffff,0xfffffffd,0x00007fff,0x03fffff8,0x3fffe200,0x7ffd45ff, + 0x7c405fff,0xffffffff,0x3fffff60,0xff304fff,0x333fffff,0x33333333, + 0x3fff2001,0x3ff2000f,0x80003fff,0xd84ffffc,0x7c41ffff,0x3ff27fff, + 0xfe802fff,0xff10ffff,0xf9dfffff,0xffffffff,0x3ea001ff,0xffffffff, + 0x7c00000f,0x0003ffff,0x3ffffffa,0xfffffd80,0x7fffc03f,0x7d46ffff, + 0x3fffffff,0xfffffe88,0xffffffff,0x006fffff,0x003ffff9,0x1fffffe4, + 0x7ffe4000,0xffffd84f,0x3ffffc41,0x05fffff9,0x1fffffd0,0x7fffffe4, + 0xdfffffff,0x000fffff,0x3ffffffe,0x800004ff,0x003fffff,0xffffff90, + 0x3fffe205,0x3f601fff,0x43ffffff,0xfffffff8,0xffffa82f,0xffffffff, + 0x6fffffff,0x19999700,0x7fffe400,0xfc80003f,0xffd84fff,0x7ffc41ff, + 0x3ffff27f,0xfffe802f,0x3ffe20ff,0xffffffff,0xfffff8df,0x3fff2000, + 0x001fffff,0xfffff800,0xfffa8003,0x7d405fff,0x00efffff,0xfffffff9, + 0xfffffb01,0xfff503ff,0xffffffff,0xffffffff,0x2000000d,0x03fffffc, + 0xffffc800,0x1ffffd84,0x93ffffc4,0x005fffff,0x81fffffd,0xfffffffa, + 0xfff14fff,0x7cc001ff,0x06ffffff,0xffff0000,0xff88007f,0x800fffff, + 0x4ffffffd,0xffffff70,0x3fffea0d,0xfff507ff,0xffffffff,0xffffffff, + 0x2000000d,0x03fffffc,0xffffc800,0x1ffffd84,0x93ffffc4,0x005fffff, + 0x01fffffd,0xffffffd1,0x7fffc45d,0x7ff4000f,0x0003ffff,0x39999900, + 0xffffd800,0xff1002ff,0x505fffff,0x07ffffff,0x3fffffe2,0xfffff507, + 0xffffffff,0x0dffffff,0x3f200000,0x0003ffff,0x84ffffc8,0x441ffffd, + 0x3f27ffff,0xe802ffff,0x200fffff,0x001abb98,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x1ffffd00, + 0x66665c00,0xcccccccc,0xcccccccc,0x80000000,0x42aaaaa8,0x42aaaaa8, + 0xaaaaaaa8,0x6eeeec01,0xdddddddd,0xdddddddd,0x02dddddd,0x00000000, + 0x00000000,0x00000000,0x7dc00000,0x2005ffff,0xfffffffd,0xffffffff, + 0x501fffff,0x005bdfd9,0xfffff500,0xfffffa8d,0xfffffb86,0x3ffe02ff, + 0xffffffff,0xffffffff,0xffffffff,0x00000003,0x00000000,0x00000000, + 0x20000000,0xfffffff8,0xffffb002,0xffffffff,0xffffffff,0xfffffb03, + 0xa9801bff,0xfff50aaa,0xfffa8dff,0xffd306ff,0x3e05ffff,0xffffffff, + 0xffffffff,0xffffffff,0x000003ff,0x00000000,0x00000000,0x00000000, + 0x3fffff60,0xffb006ff,0xffffffff,0xffffffff,0x7ff443ff,0xffffffff, + 0x3ffff601,0xbfffff31,0x5fffff98,0x3ffff620,0xffff81ff,0xffffffff, + 0xffffffff,0x3fffffff,0x00000000,0x00000000,0x00000000,0xf3000000, + 0xffffdfff,0xffffb009,0xffffffff,0xffffffff,0x7ffffdc3,0x2fffffff, + 0x21ffffb0,0x45fffff9,0x05fffff9,0xffffffb8,0x7fffffc1,0xffffffff, + 0xffffffff,0x003fffff,0x00000000,0x00000000,0x00000000,0xfffd0000, + 0x03ffffad,0x33333310,0x33333333,0xe8333333,0xffffffff,0x442fffff, + 0x3e27ffff,0x7c44ffff,0x3004ffff,0x03fffffd,0x00000000,0x00000000, + 0x00000000,0x00000000,0x7fdc0000,0xffff51ff,0x0000000b,0x67ffffd4, + 0xffffffb9,0xfffe98cf,0x3fffe26f,0xfffff84f,0x3bb22004,0x00000dee, + 0x00000000,0x00000000,0x00000000,0x00000000,0x45ffff88,0x002ffffd, + 0xff700000,0xffe889ff,0xffffffff,0x7ffc3fff,0xffff83ff,0x0000003f, + 0x00000000,0x00000000,0x00000000,0x00000000,0x3fff2000,0x7fffcc1f, + 0x0000000f,0x81ffffc8,0xffffffe8,0x40ffffff,0xf82fffff,0x0003ffff, + 0x00000000,0x00000000,0x00000000,0x00000000,0xf3000000,0x3f209fff, + 0x00004fff,0xffffd800,0xffffb101,0x07ffffff,0xd05ffffd,0x0005ffff, + 0x00000000,0x00000000,0x00000000,0x00000000,0x3a000000,0xf100ffff, + 0xd903ffff,0xdddddddd,0xdddddddd,0x2aaa3ddd,0x7fe400aa,0x02ffffff, + 0xd03ffffd,0x0003ffff,0x00000000,0x00000000,0x00000000,0x00000000, + 0xf5000000,0xfb807fff,0xffd86fff,0xffffffff,0xffffffff,0x4c0001ff, + 0x01cefffd,0x207ffff6,0x001ffffd,0x00000000,0x00000000,0x00000000, + 0x00000000,0x44000000,0xd006ffff,0xfd87ffff,0xffffffff,0xffffffff, + 0x00001fff,0xccca8002,0xcccca80c,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x17fffe40,0xfffffa80,0x3fffff60,0xffffffff, + 0x1fffffff,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x7ffcc000,0x7ff4006f,0x3bbb24ff,0xeeeeeeee,0xeeeeeeee, + 0x0000001e,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x65400000,0x4c001ccc,0x000ccccc,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, +}; + +static signed short stb__consolas_bold_50_usascii_x[95]={ 0,9,5,1,2,0,0,10,6,5,3,1,5,6, +8,1,1,2,3,3,0,3,2,2,2,1,9,5,2,3,4,6,0,0,3,2,2,4,4,1,2,3,4,3, +4,1,2,0,3,0,3,2,1,2,0,0,0,0,2,7,2,6,2,0,0,2,3,3,1,2,0,1,3,3, +2,3,3,1,3,1,3,1,4,3,1,3,0,0,0,0,3,3,11,5,1, }; +static signed short stb__consolas_bold_50_usascii_y[95]={ 37,2,2,5,0,2,2,2,0,0,2,11,27,21, +27,2,4,4,4,4,5,5,5,5,4,4,11,11,9,16,9,2,1,5,5,4,5,5,5,4,5,5,5,5, +5,5,5,4,5,4,5,4,5,5,5,5,5,5,5,1,2,1,5,42,2,11,2,11,2,11,2,11,2,1, +1,2,2,11,11,11,11,11,11,11,4,12,12,12,12,12,12,1,-3,1,17, }; +static unsigned short stb__consolas_bold_50_usascii_w[95]={ 0,9,17,26,24,28,29,8,17,16,22,25,14,16, +11,24,26,23,22,22,27,22,24,23,23,24,10,14,21,22,21,18,28,28,23,23,25,20,20,25,24,21,19,24, +21,26,24,27,23,28,24,23,25,24,28,27,28,28,23,14,24,14,24,28,17,23,23,21,24,23,26,25,22,22, +21,24,22,26,22,25,23,24,22,21,23,22,28,28,27,28,21,20,6,19,26, }; +static unsigned short stb__consolas_bold_50_usascii_h[95]={ 0,36,13,32,44,36,36,13,48,48,22,25,19,6, +11,41,34,33,33,34,32,33,33,32,34,33,27,35,29,15,29,36,47,32,32,34,32,32,32,34,32,32,33,32, +32,32,32,34,32,43,32,34,32,33,32,32,32,32,32,46,41,46,16,6,11,27,36,27,36,27,35,37,35,36, +47,35,35,26,26,27,36,36,26,27,34,26,25,25,25,36,25,46,51,46,13, }; +static unsigned short stb__consolas_bold_50_usascii_s[95]={ 254,244,76,79,165,82,52,244,25,8,231, +126,237,237,244,219,1,220,172,28,47,99,122,23,51,147,241,124,97,26,75, +111,43,199,175,191,127,106,235,215,54,1,1,210,153,154,129,163,228,190,49, +75,103,195,181,21,74,1,30,135,1,150,1,112,94,213,208,145,1,167,49, +26,26,232,72,76,101,24,51,119,184,159,1,191,139,74,97,180,152,130,209, +94,1,115,49, }; +static unsigned short stb__consolas_bold_50_usascii_t[95]={ 1,1,294,201,1,53,53,132,1,1,267, +267,234,254,146,1,132,132,132,132,234,132,132,234,132,132,91,91,234,294,234, +53,1,201,201,91,201,201,167,91,201,234,167,167,201,167,167,91,201,1,167, +132,167,132,167,167,167,201,201,1,53,1,294,294,294,234,53,234,95,234,91, +53,91,53,1,91,91,267,267,234,53,53,267,234,91,267,267,267,267,53,267, +1,1,1,294, }; +static unsigned short stb__consolas_bold_50_usascii_a[95]={ 440,440,440,440,440,440,440,440, +440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440, +440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440, +440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440, +440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440, +440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440, +440,440,440,440,440,440,440, }; + +// Call this function with +// font: NULL or array length +// data: NULL or specified size +// height: STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT or STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT_POW2 +// return value: spacing between lines +static void stb_font_consolas_bold_50_usascii(stb_fontchar font[STB_FONT_consolas_bold_50_usascii_NUM_CHARS], + unsigned char data[STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT][STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH], + int height) +{ + int i,j; + if (data != 0) { + unsigned int *bits = stb__consolas_bold_50_usascii_pixels; + unsigned int bitpack = *bits++, numbits = 32; + for (i=0; i < STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH*height; ++i) + data[0][i] = 0; // zero entire bitmap + for (j=1; j < STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT-1; ++j) { + for (i=1; i < STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH-1; ++i) { + unsigned int value; + if (numbits==0) bitpack = *bits++, numbits=32; + value = bitpack & 1; + bitpack >>= 1, --numbits; + if (value) { + if (numbits < 3) bitpack = *bits++, numbits = 32; + data[j][i] = (bitpack & 7) * 0x20 + 0x1f; + bitpack >>= 3, numbits -= 3; + } else { + data[j][i] = 0; + } + } + } + } + + // build font description + if (font != 0) { + float recip_width = 1.0f / STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH; + float recip_height = 1.0f / height; + for (i=0; i < STB_FONT_consolas_bold_50_usascii_NUM_CHARS; ++i) { + // pad characters so they bilerp from empty space around each character + font[i].s0 = (stb__consolas_bold_50_usascii_s[i]) * recip_width; + font[i].t0 = (stb__consolas_bold_50_usascii_t[i]) * recip_height; + font[i].s1 = (stb__consolas_bold_50_usascii_s[i] + stb__consolas_bold_50_usascii_w[i]) * recip_width; + font[i].t1 = (stb__consolas_bold_50_usascii_t[i] + stb__consolas_bold_50_usascii_h[i]) * recip_height; + font[i].x0 = stb__consolas_bold_50_usascii_x[i]; + font[i].y0 = stb__consolas_bold_50_usascii_y[i]; + font[i].x1 = stb__consolas_bold_50_usascii_x[i] + stb__consolas_bold_50_usascii_w[i]; + font[i].y1 = stb__consolas_bold_50_usascii_y[i] + stb__consolas_bold_50_usascii_h[i]; + font[i].advance_int = (stb__consolas_bold_50_usascii_a[i]+8)>>4; + font[i].s0f = (stb__consolas_bold_50_usascii_s[i] - 0.5f) * recip_width; + font[i].t0f = (stb__consolas_bold_50_usascii_t[i] - 0.5f) * recip_height; + font[i].s1f = (stb__consolas_bold_50_usascii_s[i] + stb__consolas_bold_50_usascii_w[i] + 0.5f) * recip_width; + font[i].t1f = (stb__consolas_bold_50_usascii_t[i] + stb__consolas_bold_50_usascii_h[i] + 0.5f) * recip_height; + font[i].x0f = stb__consolas_bold_50_usascii_x[i] - 0.5f; + font[i].y0f = stb__consolas_bold_50_usascii_y[i] - 0.5f; + font[i].x1f = stb__consolas_bold_50_usascii_x[i] + stb__consolas_bold_50_usascii_w[i] + 0.5f; + font[i].y1f = stb__consolas_bold_50_usascii_y[i] + stb__consolas_bold_50_usascii_h[i] + 0.5f; + font[i].advance = stb__consolas_bold_50_usascii_a[i]/16.0f; + } + } +} + +#ifndef STB_SOMEFONT_CREATE +#define STB_SOMEFONT_CREATE stb_font_consolas_bold_50_usascii +#define STB_SOMEFONT_BITMAP_WIDTH STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH +#define STB_SOMEFONT_BITMAP_HEIGHT STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT +#define STB_SOMEFONT_BITMAP_HEIGHT_POW2 STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT_POW2 +#define STB_SOMEFONT_FIRST_CHAR STB_FONT_consolas_bold_50_usascii_FIRST_CHAR +#define STB_SOMEFONT_NUM_CHARS STB_FONT_consolas_bold_50_usascii_NUM_CHARS +#define STB_SOMEFONT_LINE_SPACING STB_FONT_consolas_bold_50_usascii_LINE_SPACING +#endif + diff --git a/Projects/Asteroids/src/subset_d3d12.h b/Projects/Asteroids/src/subset_d3d12.h new file mode 100644 index 0000000..8fe2a1b --- /dev/null +++ b/Projects/Asteroids/src/subset_d3d12.h @@ -0,0 +1,50 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "util.h" +#include "descriptor.h" + +#include + +__declspec(align(64)) // Avoid false sharing +class SubsetD3D12 +{ +public: + SubsetD3D12(ID3D12Device* mDevice, UINT srvCount, ID3D12PipelineState* pso) + { + ThrowIfFailed(mDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCmdAlloc))); + ThrowIfFailed(mDevice->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, mCmdAlloc, pso, IID_PPV_ARGS(&mCmdLst))); + ThrowIfFailed(mCmdLst->Close()); + } + + ~SubsetD3D12() + { + SafeRelease(&mCmdLst); + SafeRelease(&mCmdAlloc); + } + + ID3D12GraphicsCommandList* Begin(ID3D12PipelineState* pso) + { + ThrowIfFailed(mCmdAlloc->Reset()); + ThrowIfFailed(mCmdLst->Reset(mCmdAlloc, pso)); + return mCmdLst; + } + + ID3D12GraphicsCommandList* End() + { + ThrowIfFailed(mCmdLst->Close()); + return mCmdLst; + } + + ID3D12GraphicsCommandList* mCmdLst = nullptr; + ID3D12CommandAllocator* mCmdAlloc = nullptr; +}; diff --git a/Projects/Asteroids/src/texture.cpp b/Projects/Asteroids/src/texture.cpp new file mode 100644 index 0000000..d62b913 --- /dev/null +++ b/Projects/Asteroids/src/texture.cpp @@ -0,0 +1,285 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#include "texture.h" +#include "util.h" +#include "noise.h" +#include "DDSTextureLoader.h" + +#include +#include + + +static void WaitForAll(ID3D12Device* device, ID3D12CommandQueue* queue) +{ + // Kind of ugly, but yeah... + ID3D12Fence* fence = nullptr; + ThrowIfFailed(device->CreateFence( 0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence))); + auto eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); + + queue->Signal(fence, 1); + fence->SetEventOnCompletion(1, eventHandle); + WaitForSingleObject(eventHandle, INFINITE); + + CloseHandle(eventHandle); + fence->Release(); +} + + +void GenerateMips2D_XXXX8(D3D11_SUBRESOURCE_DATA* subresources, size_t widthLevel0, size_t heightLevel0, size_t mipLevels) +{ + for (size_t m = 1; m < mipLevels; ++m) { + auto rowPitchSrc = subresources[m - 1].SysMemPitch; + const BYTE* dataSrc = (BYTE*)subresources[m - 1].pSysMem; + + auto rowPitchDst = subresources[m].SysMemPitch; + BYTE* dataDst = (BYTE*)subresources[m].pSysMem; + + auto width = widthLevel0 >> m; + auto height = heightLevel0 >> m; + + // Iterating byte-wise is simpler in this case (pulls apart color nicely) + // Not optimized at all, obviously... + for (size_t y = 0; y < height; ++y) { + auto rowSrc0 = (dataSrc + (y*2+0)*rowPitchSrc); + auto rowSrc1 = (dataSrc + (y*2+1)*rowPitchSrc); + auto rowDst = (dataDst + (y )*rowPitchDst); + for (size_t x = 0; x < width; ++x) { + for (size_t comp = 0; comp < 4; ++comp) { + uint32_t c = rowSrc0[x*8+comp+0]; + c += rowSrc0[x*8+comp+4]; + c += rowSrc1[x*8+comp+0]; + c += rowSrc1[x*8+comp+4]; + c = c / 4; + assert(c < 256); + rowDst[4*x+comp] = (byte)c; + } + } + } + } +} + + +void FillNoise2D_RGBA8(D3D11_SUBRESOURCE_DATA* subresources, size_t width, size_t height, size_t mipLevels, + float seed, float persistence, float noiseScale, float noiseStrength, + float redScale, float greenScale, float blueScale) +{ + NoiseOctaves<4> textureNoise(persistence); + + // Level 0 + for (size_t y = 0; y < height; ++y) { + uint32_t* row = (uint32_t*)((BYTE*)subresources[0].pSysMem + y*subresources[0].SysMemPitch); + for (size_t x = 0; x < width; ++x) { + auto c = textureNoise((float)x*noiseScale, (float)y*noiseScale, seed); + c = std::max(0.0f, std::min(1.0f, (c - 0.5f) * noiseStrength + 0.5f)); + + int32_t cr = (int32_t)(c * redScale); + int32_t cg = (int32_t)(c * greenScale); + int32_t cb = (int32_t)(c * blueScale); + assert(cr >= 0 && cr < 256); + assert(cg >= 0 && cg < 256); + assert(cb >= 0 && cb < 256); + + row[x] = (cr) << 16 | (cg) << 8 | (cb) << 0; + } + } + + if (mipLevels > 1) + GenerateMips2D_XXXX8(subresources, width, height, mipLevels); +} + + +void InitializeTexture2D( + ID3D12Device* device, ID3D12CommandQueue* cmdQueue, + ID3D12Resource* texture, const D3D12_RESOURCE_DESC* desc, UINT bytesPerPixel, + const D3D11_SUBRESOURCE_DATA* initialData, + D3D12_RESOURCE_STATES stateAfter) +{ + // Pull some data + auto format = desc->Format; + UINT width = (UINT)desc->Width; + UINT height = desc->Height; + UINT arraySize = desc->DepthOrArraySize; + UINT mipLevels = desc->MipLevels; + + // Pow2 mip chain! + assert(mipLevels == 1 || ((width & (width-1)) == 0 && (height & (height-1)) == 0)); + + std::vector placedUpload; + UINT64 totalSize = 0; + for (UINT a = 0; a < arraySize; ++a) { + for (UINT m = 0; m < mipLevels; ++m) { + D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed = {}; + placed.Footprint.Format = format; + placed.Footprint.Width = width >> m; // TODO: Handle mip sizes properly! + placed.Footprint.Height = height >> m; // TODO: Handle mip sizes properly! + placed.Footprint.Depth = 1; + placed.Footprint.RowPitch = Align(placed.Footprint.Width * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + placed.Offset = totalSize; + + totalSize = Align(placed.Offset + (placed.Footprint.RowPitch * placed.Footprint.Height), + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); + placedUpload.push_back(placed); + } + } + + ID3D12Resource* uploadBuffer = nullptr; + ThrowIfFailed(device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(totalSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&uploadBuffer) + )); + + BYTE *baseData = nullptr; + ThrowIfFailed(uploadBuffer->Map(0, nullptr, reinterpret_cast(&baseData))); + + // Fill in data (RGBA8) + for (UINT a = 0; a < arraySize; ++a) { + for (UINT m = 0; m < mipLevels; ++m) { + auto subresource = a * mipLevels + m; + + BYTE* dataSrc = (BYTE*)initialData[subresource].pSysMem; + auto rowPitchSrc = initialData[subresource].SysMemPitch; + + auto placed = &placedUpload[subresource]; + BYTE* dataDst = baseData + placed->Offset; + auto rowPitchDst = placed->Footprint.RowPitch; + UINT width_mip = placed->Footprint.Width; + UINT height_mip = placed->Footprint.Height; + + for (UINT y = 0; y < height_mip; ++y) { + memcpy(dataDst + y*rowPitchDst, dataSrc + y*rowPitchSrc, bytesPerPixel * width_mip); + } + } + } + + // Create some new resources for initialization + ID3D12GraphicsCommandList* cmdLst = nullptr; + ID3D12CommandAllocator* cmdAlloc = nullptr; + ThrowIfFailed(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc))); + ThrowIfFailed(device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdLst))); + + { + ResourceBarrier rb; + rb.AddTransition(texture, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST); + rb.Submit(cmdLst); + } + + // Copy data from each subresource into texture + for (size_t s = 0; s < placedUpload.size(); ++s) { + CD3DX12_TEXTURE_COPY_LOCATION dest(texture, static_cast(s)); + CD3DX12_TEXTURE_COPY_LOCATION src(uploadBuffer, placedUpload[s]); + + cmdLst->CopyTextureRegion( + &dest, 0, 0, 0, + &src, nullptr); + } + + { + ResourceBarrier rb; + rb.AddTransition(texture, D3D12_RESOURCE_STATE_COPY_DEST, stateAfter); + rb.Submit(cmdLst); + } + + ThrowIfFailed(cmdLst->Close()); + cmdQueue->ExecuteCommandLists(1, reinterpret_cast(&cmdLst)); + + // Kind of ugly... but yeah + WaitForAll(device, cmdQueue); + + SafeRelease(&uploadBuffer); + SafeRelease(&cmdLst); + SafeRelease(&cmdAlloc); +} + + +HRESULT CreateTexture2DFromDDS_XXXX8( + ID3D12Device* device, ID3D12CommandQueue* cmdQueue, + ID3D12Resource** texture, + const char* fileName, + DXGI_FORMAT format, + D3D12_RESOURCE_STATES stateAfter ) +{ + BYTE* heapData = nullptr; + DDS_HEADER* header = nullptr; + BYTE* bitData = nullptr; + UINT bitSize = 0; + + std::wostringstream wfileName; + wfileName << fileName; + + HRESULT hr = LoadTextureDataFromFile(wfileName.str().c_str(), &heapData, &header, &bitData, &bitSize); + if (FAILED(hr)) { + delete[] heapData; + return hr; + } + + unsigned int arraySize = 1; + + if (header->dwCaps2 & DDS_CUBEMAP) { + assert((header->dwCaps2 & DDS_CUBEMAP_ALLFACES ) == DDS_CUBEMAP_ALLFACES); + arraySize = 6; + } + + // We only support XXXX8_UNORM[_SRGB] atm... + if (format != DXGI_FORMAT_B8G8R8A8_UNORM && format != DXGI_FORMAT_R8G8B8A8_UNORM && + format != DXGI_FORMAT_B8G8R8A8_UNORM_SRGB && format != DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) { + return E_NOTIMPL; + } + + unsigned int mipLevels = header->dwMipMapCount; + if (mipLevels == 0) mipLevels = 1; // Hacky... but good enough for now + + // TODO: lots of stuff is not checked... just don't be stupid, this is hacky sample code after all :) + + auto desc = CD3DX12_RESOURCE_DESC::Tex2D( + format, header->dwWidth, header->dwHeight, + (UINT16)arraySize, (UINT16)mipLevels ); + + ThrowIfFailed(device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &desc, + D3D12_RESOURCE_STATE_COMMON, + nullptr, + IID_PPV_ARGS(texture) + )); + + std::vector initialData(desc.MipLevels * arraySize); + + BYTE* srcBits = bitData; + const BYTE *endBits = bitData + bitSize; + + for (UINT a = 0; a < arraySize; ++a) { + for (UINT m = 0; m < desc.MipLevels; ++m) { + auto width = (UINT)desc.Width >> m; + auto height = desc.Height >> m; + auto subresource = a * desc.MipLevels + m; + auto rowPitch = 4 * width; + auto bytes = rowPitch * height; + + assert(srcBits + bytes <= endBits); + + initialData[subresource].pSysMem = (void*)srcBits; + initialData[subresource].SysMemPitch = rowPitch; + initialData[subresource].SysMemSlicePitch = bytes; + + srcBits += bytes; + } + } + + InitializeTexture2D(device, cmdQueue, *texture, &desc, 4, initialData.data(), stateAfter); + + delete[] heapData; + return S_OK; +} diff --git a/Projects/Asteroids/src/texture.h b/Projects/Asteroids/src/texture.h new file mode 100644 index 0000000..d3ed698 --- /dev/null +++ b/Projects/Asteroids/src/texture.h @@ -0,0 +1,46 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include +#include +#include + +void GenerateMips2D_XXXX8(D3D11_SUBRESOURCE_DATA* subresources, size_t widthLevel0, size_t heightLevel0, size_t mipLevels); + +// Will generate mips (into subresources array) is mipLevels > 0 +void FillNoise2D_RGBA8(D3D11_SUBRESOURCE_DATA* subresources, size_t width, size_t height, size_t mipLevels, + float seed, float persistence, float noiseScale, float noiseStrength, + float redScale = 255.0f, float greenScale = 255.0f, float blueScale = 255.0f); + + +// Helper for uploading initial texture data in D3D12; as with D3D11, one initialData structure per subresource +// Creates temporary resources internally and syncs with GPU... this is a convenience function for init time! +// NOTE: Currently textures with mip chain must be pow2! +// Transitions resource from D3D12_RESOURCE_USAGE_INITIAL to "stateAfter" +void InitializeTexture2D( + ID3D12Device* device, + ID3D12CommandQueue* cmdQueue, + ID3D12Resource* texture, + const D3D12_RESOURCE_DESC* desc, + UINT bytesPerPixel, + const D3D11_SUBRESOURCE_DATA* initialData, + D3D12_RESOURCE_STATES stateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + +// NOTE: This function very much only works for the specific path(s) that we use it for! +// Not very general-purpose yet. +HRESULT CreateTexture2DFromDDS_XXXX8( + ID3D12Device* device, + ID3D12CommandQueue* cmdQueue, + ID3D12Resource** texture, + const char* fileName, + DXGI_FORMAT format, // Should match file otherwise expect explosion/wackiness... + D3D12_RESOURCE_STATES stateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); diff --git a/Projects/Asteroids/src/upload_heap.h b/Projects/Asteroids/src/upload_heap.h new file mode 100644 index 0000000..582925e --- /dev/null +++ b/Projects/Asteroids/src/upload_heap.h @@ -0,0 +1,60 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include "util.h" +#include + +// Untyped version +class UploadHeap +{ +public: + UploadHeap(ID3D12Device* device, UINT64 size) + { + ThrowIfFailed(device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES( D3D12_HEAP_TYPE_UPLOAD ), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer( size ), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&mHeap) + )); + + ThrowIfFailed(mHeap->Map(0, nullptr, reinterpret_cast(&mHeapWO))); + } + + ~UploadHeap() + { + SafeRelease(&mHeap); + } + + ID3D12Resource* Heap() { return mHeap; } + + // Write-only! + void* DataWO() { return mHeapWO; } + +private: + ID3D12Resource* mHeap = nullptr; + void* mHeapWO = nullptr; +}; + + +// Structure/typed version +template +class UploadHeapT : public UploadHeap +{ +public: + UploadHeapT(ID3D12Device* device) + : UploadHeap(device, sizeof(T)) + {} + + T* DataWO() { return (T*)UploadHeap::DataWO(); } +}; diff --git a/Projects/Asteroids/src/util.h b/Projects/Asteroids/src/util.h new file mode 100644 index 0000000..7779954 --- /dev/null +++ b/Projects/Asteroids/src/util.h @@ -0,0 +1,79 @@ +// Copyright 2014 Intel Corporation All Rights Reserved +// +// Intel makes no representations about the suitability of this software for any purpose. +// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, +// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, +// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY +// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Intel does not assume any responsibility for any errors which may appear in this software +// nor any responsibility to update it. + +#pragma once + +#include +#include + +#include +#include + +#define CBUFFER_ALIGN __declspec(align(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT)) + +#define WIDE_HELPER_2(x) L##x +#define WIDE_HELPER_1(x) WIDE_HELPER_2(x) +#define W__FILE__ WIDE_HELPER_1(__FILE__) + +template +inline void SafeRelease(T** p) +{ + auto q = *p; + if (q != nullptr) { + q->Release(); + *p = nullptr; + } +} + +inline HRESULT ThrowIfFailed(HRESULT hr) +{ + if (FAILED(hr)) throw; + return hr; +} + +template +inline T Align(T v, T align) +{ + return (v + (align-1)) & ~(align-1); +} + +struct ResourceBarrier { + std::vector mDescs; + + void AddTransition( + ID3D12Resource* resource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) + { + D3D12_RESOURCE_BARRIER desc = {}; + desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + desc.Transition.pResource = resource; + desc.Transition.StateBefore = stateBefore; + desc.Transition.StateAfter = stateAfter; + desc.Transition.Subresource = subresource; + mDescs.push_back(desc); + } + + void ReverseTransitions() + { + for (auto ii = mDescs.begin(), ie = mDescs.end(); ii != ie; ++ii) { + if (ii->Type == D3D12_RESOURCE_BARRIER_TYPE_TRANSITION) { + std::swap(ii->Transition.StateBefore, ii->Transition.StateAfter); + } + } + } + + void Submit(ID3D12GraphicsCommandList* commandList) const + { + assert(mDescs.size() <= UINT_MAX); + commandList->ResourceBarrier((UINT)mDescs.size(), mDescs.data()); + } +}; diff --git a/Projects/Asteroids/starbox_1024.dds b/Projects/Asteroids/starbox_1024.dds new file mode 100644 index 0000000..ecd1077 Binary files /dev/null and b/Projects/Asteroids/starbox_1024.dds differ -- cgit v1.2.3