2014幎3æ20æ¥ã«ãMicrosoftã¯Game Developers Conferenceã§DirectX * 12ã®ãªãªãŒã¹ãçºè¡šããŸããããªãœãŒã¹ã®éå°ãªåŠçãåæžããããšã«ãããDirectX 12ã¯ããå¹ççãªã¢ããªã±ãŒã·ã§ã³ããã©ãŒãã³ã¹ãšäœæ¶è²»é»åã«è²¢ç®ãããããå é»ããã«ã¢ãã€ã«ããã€ã¹ã§é·æéãã¬ã€ã§ããŸãã
SIGGRAPH 2014ã§ã¯ãIntelã®å°é家ãMicrosoft Surface * Pro 3ã¿ãã¬ããã§å°ææã䜿çšããç°¡åãªãã¢ãéå§ããéã®CPUã®æ¶è²»é»åã枬å®ããŸãã ããã¿ã³ãæŒããšããã¢ã¢ããªã±ãŒã·ã§ã³ãDirectX 11 APIããDirectX 12 APIã«åãæ¿ããããšãã§ããŸã ãã®ãã¢ã¢ããªã±ãŒã·ã§ã³ã¯ãåºå®ãã¬ãŒã ã¬ãŒãã§å®å®ã«èšå€§ãªæ°ã®å°ææãæç»ããŸãã DirectX 12 APIã䜿çšããå ŽåãCPUã®æ¶è²»é»åã¯DirectX 11 **ã«æ¯ã¹ãŠåå以äžã«ãªããŸãã ããã€ã¹ã¯äœåŒ·åºŠã®ãµãŒãã«ã¢ãŒãã§åäœããããããªãŒé»åã§ããé·ãåäœããããšãã§ããŸãã å žåçãªã²ãŒã ã·ããªãªã§ã¯ãæªäœ¿çšã®CPUãã¯ãŒã¯ãã¹ãŠãç©çåŠã人工ç¥èœãçµè·¯æ¢çŽ¢ã¢ã«ãŽãªãºã ããŸãã¯CPUè² è·ãé«ããã®ä»ã®ã¿ã¹ã¯ã®æ¹åã«è²»ããããšãã§ããŸãã ãããã£ãŠãã²ãŒã ã¯æ©èœããã匷åã«ãªããé»åæ¶è²»ã®èŠ³ç¹ããããçµæžçã«ãªããŸãã
ããŒã«
DirectX 12ããŒã¹ã®ã²ãŒã ã«ã¯æ¬¡ã®ãã®ãå¿ èŠã§ãã
- Windows * 10
- DirectX 12 SDK
- Visual Studio * 2013
- DirectX 12ããµããŒãããGPUãã©ã€ããŒ
ã²ãŒã éçºè ã®æ¹ã¯ãMicrosoft DirectX Early Access Programã«åå ããŠã¿ãŠãã ããã
DirectX Early Access Programã«åæãããšãSDKã®ã€ã³ã¹ããŒã«æé ãšGPçšãã©ã€ããŒãå±ããŸãã
埩ç¿
é«ã¬ãã«ã®èŠ³ç¹ãããDirectX 10ããã³DirectX 11ãšæ¯èŒããŠãDirectX 12ã¢ãŒããã¯ãã£ã¯ã¡ã¢ãªå ã®ç¶æ 管çã远跡ãããã³ãªãœãŒã¹ç®¡çã®åéãç°ãªããŸãã
DirectX 10ã¯ãå®è¡æã«ç¶æ ã®ã°ã«ãŒããæ§æããç¶æ ãªããžã§ã¯ããå°å ¥ããŸããã DirectX 12ã§ã¯ãç¶æ ãã€ãã©ã€ã³ãªããžã§ã¯ãïŒPSOïŒãå°å ¥ãããã·ã§ãŒããŒãšå ±ã«ããã«å€§ããªç¶æ ãªããžã§ã¯ããšããŠæ©èœããŸãã ãã®èšäºã§ã¯ããªãœãŒã¹ã®æäœã«ãããå€æŽã«ã€ããŠèª¬æããŸãã PSOã®ç¶æ ã®ã°ã«ãŒãåã«ã€ããŠã¯ãä»åŸã®èšäºã§èª¬æããŸãã
DirectX 11ã§ã¯ãã·ã¹ãã ããªãœãŒã¹äœ¿çšéã®äºæž¬ãšè¿œè·¡ãæ åœããŠããŸãããããã«ãããDirectX 11ã®å€§èŠæš¡ãªäœ¿çšã®ããã«ã¢ããªã±ãŒã·ã§ã³ãäœæããæ©èœãå¶éãããŸãããDirectX12ã§ã¯ã
1.ãªãœãŒã¹ãã€ã³ãã£ã³ã°
äžå®å šãªGPæäœããããã®ãªãœãŒã¹ãåç §ããå¯èœæ§ããããããDirectX 10ããã³11ã¯ãã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠæ¢ã«ãªãªãŒã¹ããããªãœãŒã¹ãç¶æããããã«ãã°ã©ãã£ãã¯ã¹ãã€ãã©ã€ã³ãžã®ãªãœãŒã¹ã®ãã€ã³ãã远跡ããŸããã DirectX 12ã§ã¯ãã·ã¹ãã ã¯ãªãœãŒã¹ãã€ã³ãã£ã³ã°ã远跡ããŸããã ã¢ããªã±ãŒã·ã§ã³ãã€ãŸãããã°ã©ãã¯ããªããžã§ã¯ãã®ã©ã€ããµã€ã¯ã«ã®ç®¡çã«é¢äžããå¿ èŠããããŸãã
2.ãªãœãŒã¹ãã€ã³ãã£ã³ã°åæ
DirectX 12ã¯ããªãœãŒã¹ãã€ã³ãã£ã³ã°ã远跡ããŠããªãœãŒã¹åãæ¿ããçºçãããã©ãããå€æããŸããã ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã¯ãã¬ã³ããŒã¿ãŒã²ããïŒRTVïŒè¡šçŸã䜿çšããŠã¬ã³ããŒã¿ãŒã²ããã«æžã蟌ã¿ãã·ã§ãŒããŒãªãœãŒã¹ãã¥ãŒïŒSRVïŒã䜿çšããŠãã®ã¬ã³ããŒã¿ãŒã²ããããã¯ã¹ãã£ãšããŠèªã¿åãããšãã§ããŸãã DirectX 11 APIã§ã¯ãGPUãã©ã€ããŒã¯ãããŒã¿ã®èªã¿åããå€æŽãããã³ã¡ã¢ãªãžã®æžã蟌ã¿æã®ç«¶åãåé¿ããããã«ããªãœãŒã¹ã®åãæ¿ãããã€è¡ããããããç¥ããå¿ èŠããããŸããã DirectX 12ã§ã¯ãåå¥ã®APIåŒã³åºãã䜿çšããŠãã¹ãŠã®ãªãœãŒã¹è»¢éãèå¥ããã³è¿œè·¡ããå¿ èŠããããŸãã
3.ããããããã¡ã¢ãªã®åæ
DirectX 11ã§ã¯ããã©ã€ããŒã¯CPUãšGPUéã®ããããããã¡ã¢ãªã®åæãåŠçããŸãã CPUã¢ã¯ã»ã¹çšã«ãããã³ã°ããããªãœãŒã¹ã®ãããã³ã°ããŸã ãã£ã³ã»ã«ãããŠããªããããã·ã¹ãã ã¯ãªãœãŒã¹ãã€ã³ãã£ã³ã°ãåæããŠã¬ã³ããªã³ã°é 延ãå¿ èŠãã©ããã確èªããŸããã DirectX 12ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯ãªãœãŒã¹ãžã®CPUããã³GPUã¢ã¯ã»ã¹ã®åæãåŠçããå¿ èŠããããŸãã ã¡ã¢ãªã¢ã¯ã»ã¹ãåæããããã®åäžã®ã¡ã«ããºã ã¯ãGPUã§åŠçãå®äºãããšãã«ã¹ã¬ãããèµ·åããã€ãã³ããèŠæ±ããŸãã
ãããã®ãªãœãŒã¹äœ¿çšãã¿ãŒã³ãã¢ããªã±ãŒã·ã§ã³ã«ç§»è¡ããã«ã¯ãåºç¯ãªGPUã¢ãŒããã¯ãã£ããµããŒãã§ããæ°ããããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ã®ã»ãããå¿ èŠã§ãã
ãã®èšäºã®æ®ãã®éšåã§ã¯ãæ°ãããªãœãŒã¹ãã€ã³ãã£ã³ã°ã¡ã«ããºã ã«ã€ããŠèª¬æããŸããæåã®ã¡ã«ããºã ã¯èšè¿°åã§ãã
èšè¿°å
èšè¿°åã¯ãã¡ã¢ãªã«æ ŒçŽãããŠãããªãœãŒã¹ãèšè¿°ããŸãã èšè¿°åã¯ãGPçšã®ãäžéæãªã圢åŒã§GPã®ãªããžã§ã¯ããèšè¿°ããããŒã¿ãããã¯ã§ãã ãããã«äŒžã³ãèšè¿°åã¯ãDirectX 11ã®ãè¡šçŸãã®å€ãã·ã¹ãã ã®ä»£æ¿ãšèŠãªãããšãã§ããŸããã·ã§ãŒããŒãªãœãŒã¹è¡šçŸïŒSRVïŒãç¡ç§©åºãªã¢ã¯ã»ã¹è¡šçŸïŒUAVïŒãªã©ã®ããŸããŸãªçš®é¡ã®DirectX 11èšè¿°åã«å ããŠãä»ã®çš®é¡ã®èšè¿°åãDirectX 12ã«ç»å ŽããŸããããšãã°ããµã³ãã©ãŒããã³æ°žç¶çãããã¡è¡šçŸïŒCBVïŒã
ããšãã°ãSRVã¯ã䜿çšããããŒã¹ãªãœãŒã¹ããã³ãããããšã¢ã¬ã€ã®ã¹ã©ã€ã¹ã®ã»ãããããã³ã¡ã¢ãªã解éãã圢åŒãéžæããŸãã SRVèšè¿°åã«ã¯ãGPUã®Direct3D *ãªãœãŒã¹ïŒãã¯ã¹ãã£ã®å ŽåããããŸãïŒã®ä»®æ³ã¢ãã¬ã¹ãå«ãŸããŠããå¿ èŠããããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯ãåºç€ãšãªããªãœãŒã¹ãç Žå£ããããéå± äœè ã®ããã«ã¢ã¯ã»ã¹ã§ããªãããšã確èªããå¿ èŠããããŸãã
å³ 1ã¯ããã¯ã¹ãã£ã®ãè¡šçŸããžã®ãã³ãã«ã瀺ããŠããŸãã
å³1.èšè¿°åå ã®ã·ã§ãŒããŒãªãœãŒã¹ã®è¡šçŸ[èš±å¯ãåŸãŠäœ¿çšÂ©Microsoft Corporation]
DirectX 12ã§ã·ã§ãŒããŒãªãœãŒã¹è¡šçŸãäœæããã«ã¯ã次ã®Direct3Dããã€ã¹æ§é ãšã¡ãœããã䜿çšããŸãã
typedef struct D3D12_SHADER_RESOURCE_VIEW_DESC { DXGI_FORMAT Format; D3D12_SRV_DIMENSION ViewDimension; union { D3D12_BUFFER_SRV Buffer; D3D12_TEX1D_SRV Texture1D; D3D12_TEX1D_ARRAY_SRV Texture1DArray; D3D12_TEX2D_SRV Texture2D; D3D12_TEX2D_ARRAY_SRV Texture2DArray; D3D12_TEX2DMS_SRV Texture2DMS; D3D12_TEX2DMS_ARRAY_SRV Texture2DMSArray; D3D12_TEX3D_SRV Texture3D; D3D12_TEXCUBE_SRV TextureCube; D3D12_TEXCUBE_ARRAY_SRV TextureCubeArray; D3D12_BUFFEREX_SRV BufferEx; }; } D3D12_SHADER_RESOURCE_VIEW_DESC; interface ID3D12Device { ... void CreateShaderResourceView ( _In_opt_ ID3D12Resource* pResource, _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); };
SRVã³ãŒãã®äŸã¯æ¬¡ã®ããã«ãªããŸãã
// create SRV D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(D3D12_SHADER_RESOURCE_VIEW_DESC)); srvDesc.Format = mTexture->Format; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; mDevice->CreateShaderResourceView(mTexture.Get(), &srvDesc, mCbvSrvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
ãã®ã³ãŒãã¯ã2次å ãã¯ã¹ãã£ã®SRVãäœæãããã®åœ¢åŒãšä»®æ³GPUã¢ãã¬ã¹ã瀺ããŸãã CreateShaderResourceViewã®æåŸã®åŒæ°ã¯ããã®ã¡ãœãããåŒã³åºãåã«å²ãåœãŠããããã³ãã«ã®ãã³ãã«ãžã®ãã³ãã«ã§ãã èšè¿°åã¯éåžžãèšè¿°åã®ããŒãã«æ ŒçŽãããŸãã詳现ã«ã€ããŠã¯ã次ã®ã»ã¯ã·ã§ã³ã§èª¬æããŸãã
ã泚æ ããããã«ãŒããã©ã¡ãŒã¿ãŒã䜿çšããŠãããã€ãã®ã¿ã€ãã®èšè¿°åãGPUã«è»¢éããããšãã§ããŸãïŒãã©ã€ããŒã®ããŒãžã§ã³ãèæ ®ã«å ¥ããŠïŒã 詳现ã«ã€ããŠã¯ã以äžãåç §ããŠãã ããã
èšè¿°åã®ããŒã
èšè¿°åã®æã¯ãè€æ°ã®èšè¿°åã«å²ãåœãŠããã1ã€ã®ã¡ã¢ãªéãšèããããšãã§ããŸãã ç°ãªãã¿ã€ãã®ããŒãã«ã¯ã1ã€ä»¥äžã®ã¿ã€ãã®èšè¿°åãå«ãŸããå ŽåããããŸãã çŸåšã次ã®ã¿ã€ãããµããŒããããŠããŸãã
Typedef enum D3D12_DESCRIPTOR_HEAP_TYPE { D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP = 0, D3D12_SAMPLER_DESCRIPTOR_HEAP = (D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP + 1) , D3D12_RTV_DESCRIPTOR_HEAP = ( D3D12_SAMPLER_DESCRIPTOR_HEAP + 1 ) , D3D12_DSV_DESCRIPTOR_HEAP = ( D3D12_RTV_DESCRIPTOR_HEAP + 1 ) , D3D12_NUM_DESCRIPTOR_HEAP_TYPES = ( D3D12_DSV_DESCRIPTOR_HEAP + 1 ) } D3D12_DESCRIPTOR_HEAP_TYPE;
CBVãSRVãããã³UAVèšè¿°åã«ã¯ããŒãã¿ã€ãããããŸãã ã¬ã³ããªã³ã°ã¿ãŒã²ãããã¥ãŒïŒRTVïŒããã³æ·±åºŠãã©ãŒããããã¥ãŒïŒDSVïŒãæäœããããã®ã¿ã€ãããããŸãã
次ã®ã³ãŒãã¯ã9ã€ã®èšè¿°åã®èšè¿°åã®æãäœæããŸããåèšè¿°åã¯ãCBVãSRVããŸãã¯UAVã§ãã
// create shader resource view and constant buffer view descriptor heap D3D12_DESCRIPTOR_HEAP_DESC descHeapCbvSrv = {}; descHeapCbvSrv.NumDescriptors = 9; descHeapCbvSrv.Type = D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP; descHeapCbvSrv.Flags = D3D12_DESCRIPTOR_HEAP_SHADER_VISIBLE; ThrowIfFailed(mDevice->CreateDescriptorHeap(&descHeapCbvSrv, __uuidof(ID3D12DescriptorHeap), (void**)&mCbvSrvDescriptorHeap));
ããŒãèšè¿°ã®æåã®2ã€ã®ãšã³ããªã¯ããã®ããŒãå ã«ååšããå¯èœæ§ã®ããèšè¿°åã®æ°ãšèšè¿°åã®ã¿ã€ãã§ãã 3çªç®ã®ãã©ã¡ãŒã¿ãŒD3D12_DESCRIPTOR_HEAP_SHADER_VISIBLE㯠ãã·ã§ãŒããŒããèŠããèšè¿°åã®ãã®æãèšè¿°ããŸãã ããšãã°ãCPUå ã®èšè¿°åã®äžéã¹ãã¬ãŒãžããŸãã¯ã·ã§ãŒããŒå ããã¢ã¯ã»ã¹ã§ããªãRTVã«ãã·ã§ãŒããŒããã¯èŠããªãããŒãèšè¿°åã䜿çšã§ããŸãã
ãã®ã³ãŒãã¯ãã©ã°ãèšå®ããŸããããã«ãããå€ãã®èšè¿°åãã·ã§ãŒããŒããèŠããããã«ãªããŸãããéæ¥ã¢ãã¬ã¹æå®ã«ã¯å¥ã®ã¬ãã«ããããŸãã ã·ã§ãŒããŒã¯ãèšè¿°åããŒãã«ãéããŠèšè¿°åã®æããèŠããããšãã§ããŸãïŒããŒãã«ã䜿çšããªãã«ãŒãèšè¿°åããããŸãã詳现ã«ã€ããŠã¯ä»¥äžãåç §ããŠãã ããïŒã
èšè¿°åããŒãã«
èšè¿°åããŒãã®äž»ãªç®æšã¯ãã¬ã³ããªã³ã°ã«å¿ èŠãªãã¹ãŠã®èšè¿°åãæ ŒçŽããããã«å¿ èŠãªéã®ã¡ã¢ãªãå²ãåœãŠãããšã§ããããšãã°ã1ãã¬ãŒã 以äž
ã泚æ èšè¿°åã®ããŒããåãæ¿ãããšãã䜿çšããæ©åšã«å¿ããŠGPãã€ãã©ã€ã³ãã¯ãªãŒãã³ã°ã§ããŸãã ãããã£ãŠãèšè¿°åã®ããŒãéã®åãæ¿ãã®æäœãæå°éã«æãããããã€ãã©ã€ã³ããŸã ã¯ãªãŒã³ã¢ãããããŠããä»ã®æäœãšçµã¿åãããå¿ èŠããããŸãã
èšè¿°åããŒãã«ã¯ããªãã»ããã䜿çšããèšè¿°åã®æãæããŸãã ã°ã©ãã£ãã¯ãã€ãã©ã€ã³ã«åžžã«æå šäœã匷å¶çã«è¡šç€ºããã代ããã«ãèšè¿°åããŒãã«ãåãæ¿ããããšã§ããã®ã·ã§ãŒããŒã§äœ¿çšããããªãœãŒã¹ã®ã»ãããå€§å¹ ãªã³ã¹ããªãã§å€æŽã§ããŸãã ãã®å Žåãã·ã§ãŒããŒã¯ããŒãã¹ããŒã¹ã§ãªãœãŒã¹ãèŠã€ããå¿ èŠã¯ãããŸããã
èšãæãããšãå³7ã«ç€ºãããã«ãã¢ããªã±ãŒã·ã§ã³ã¯åãããŒããæãããŸããŸãªã·ã§ãŒããŒã«å¯ŸããŠè€æ°ã®èšè¿°åããŒãã«ã䜿çšã§ããŸãã 2ã
å³2.ããŸããŸãªã·ã§ãŒããŒããè€æ°ã®èšè¿°åããŒãã«ã䜿çšããäžé£ã®èšè¿°åãæããŠãã
次ã®ã³ãŒãäŸã§ã¯ããã¯ã»ã«ã·ã§ãŒããŒããèŠããSRVãšãµã³ãã©ãŒã®èšè¿°åããŒãã«ãäœæããŸãã
// define descriptor tables for a SRV and a sampler for pixel shaders D3D12_DESCRIPTOR_RANGE descRange[2]; descRange[0].Init(D3D12_DESCRIPTOR_RANGE_SRV, 1, 0); descRange[1].Init(D3D12_DESCRIPTOR_RANGE_SAMPLER, 1, 0); D3D12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[1].InitAsDescriptorTable(1, &descRange[1], D3D12_SHADER_VISIBILITY_PIXEL);
åæã«ãèšè¿°åããŒãã«ã¯ãã¯ã»ã«ã·ã§ãŒããŒã®ã¿ã«è¡šç€ºãããŸãã ãã®å¶éã¯ã D3D12_SHADER_VISIBILITY_PIXELãã©ã°ã䜿çšããŠèšå®ãããŸãã 次ã®ãªã¹ãã¯ãèšè¿°åããŒãã«ã®å¯èŠæ§ã®ããŸããŸãªã¬ãã«ãå®çŸ©ããŠããŸãã
typedef enum D3D12_SHADER_VISIBILITY { D3D12_SHADER_VISIBILITY_ALL = 0, D3D12_SHADER_VISIBILITY_VERTEX = 1, D3D12_SHADER_VISIBILITY_HULL = 2, D3D12_SHADER_VISIBILITY_DOMAIN = 3, D3D12_SHADER_VISIBILITY_GEOMETRY = 4, D3D12_SHADER_VISIBILITY_PIXEL = 5 } D3D12_SHADER_VISIBILITY;
ãã¹ãŠã®å¯èŠæ§ãèšå®ãããã©ã°ãæå®ãããšãå¯èŠæ§ã¯1åã ãèšå®ãããŸãããåŒæ°ã¯ã·ã§ãŒããŒã®ãã¹ãŠã®ã¹ããŒãžã«æž¡ãããŸãã
ã·ã§ãŒããŒã¯èšè¿°åããŒãã«ã䜿çšããŠãªãœãŒã¹ãæ€åºã§ããŸãããæåã«ãã·ã§ãŒããŒã¯ã«ãŒã眲åã®ã«ãŒããã©ã¡ãŒã¿ãŒã䜿çšããŠãããã®èšè¿°åããŒãã«ã«ã€ããŠãåŠç¿ãããå¿ èŠããããŸãã
ã«ãŒã眲åãšãã©ã¡ãŒã¿ãŒ
ã«ãŒãã·ã°ããã£ã«ã¯ãã·ã§ãŒããŒãã¢ã¯ã»ã¹ãå¿ èŠãšãããªãœãŒã¹ãèŠã€ããããã«äœ¿çšããã«ãŒããã©ã¡ãŒã¿ãŒãæ ŒçŽãããŸãã ãããã®ãã©ã¡ãŒã¿ãŒã¯ãã¢ããªã±ãŒã·ã§ã³ãã·ã§ãŒããŒã§å©çšã§ããããã«ããå¿ èŠãããäžé£ã®ãªãœãŒã¹ã®ã³ãã³ãã®ãªã¹ãã«ãã€ã³ãã£ã³ã°ã¹ããŒã¹ã®åœ¢åŒã§ååšããŸãã
ã«ãŒãåŒæ°ã¯æ¬¡ã®ããã«ãªããŸãã
- èšè¿°åããŒãã«ã åè¿°ã®ããã«ããããã«ã¯ããŒãå ã®ãªãã»ãããšèšè¿°åã®æ°ãå«ãŸããŸãã
- ã«ãŒãèšè¿°åã ã«ãŒããã©ã¡ãŒã¿ã«çŽæ¥æ ŒçŽã§ããèšè¿°åã¯ããå°æ°ã§ãã ãã®å Žåãã¢ããªã±ãŒã·ã§ã³ã¯ãããã®èšè¿°åãèšè¿°åã®ããŒãã«é 眮ããå¿ èŠããªããªããéæ¥çãªã¢ãã¬ã¹æå®ããªããªããŸãã
- ã«ãŒãå®æ°ã ãããã¯ã·ã§ãŒããŒã«çŽæ¥æäŸãããå®æ°ã§ãããã«ãŒãèšè¿°åãšèšè¿°åããŒãã«ãæäœããå¿ èŠã¯ãããŸããã
æé©ãªããã©ãŒãã³ã¹ãå®çŸããããã«ãã¢ããªã±ãŒã·ã§ã³ã¯éåžžãã«ãŒããã©ã¡ãŒã¿ãŒãé »åºŠã®éé ã§äžŠã¹æ¿ããŸãã
èšè¿°åããŒãã«ãã«ãŒãèšè¿°åãã«ãŒãå®æ°ãªã©ã®ãã¹ãŠã®ã«ãŒããã©ã¡ãŒã¿ãŒã¯ãã³ãã³ãã®ãªã¹ãã«çµåããããã©ã€ããŒã¯ã¢ããªã±ãŒã·ã§ã³ã«ä»£ãã£ãŠããŒãžã§ã³ãå¶åŸ¡ããŸãã ã€ãŸããã¬ã³ããŒã³ãŒã«ãŸãã¯éä¿¡ã³ãŒã«éã§ã«ãŒããã©ã¡ãŒã¿ãŒãå€æŽããããã³ã«ãæ©åšã¯ã«ãŒã眲åã®ããŒãžã§ã³çªå·ãæŽæ°ããŸãã åŒæ°ãå€æŽããããšãåã¬ã³ããŒã³ãŒã«ãŸãã¯éä¿¡ã³ãŒã«ã¯ãã«ãŒããã©ã¡ãŒã¿ãŒç¶æ ã®äžæã®å®å šãªã»ãããåãåããŸãã
ã«ãŒãèšè¿°åãšã«ãŒãå®æ°ã¯ãã¢ã¯ã»ã¹æã®éæ¥GPã¢ãã¬ã¹æå®ã®ã¬ãã«ãäžããŸãã èšè¿°åããŒãã«ã䜿çšãããšããã倧éã®ããŒã¿ã«ã¢ã¯ã»ã¹ã§ããŸãããéæ¥ã¢ãã¬ã¹æå®ã®ã¬ãã«ãäžãããŸãã éæ¥ã¢ãã¬ã¹æå®ã®ã¬ãã«ãé«ããããèšè¿°åããŒãã«ã䜿çšããå Žåãã³ãã³ãã®ãªã¹ããå®è¡ã®ããã«éä¿¡ããããŸã§ãã¢ããªã±ãŒã·ã§ã³ã¯ã³ã³ãã³ããåæåã§ããŸãã ããã«ããã¹ãŠã®DirectX 12ããŒããŠã§ã¢ã§ãµããŒãããã5.1ã·ã§ãŒããŒã¢ãã«ã«ãããã·ã§ãŒããŒã¯æå®ããããã¹ãŠã®èšè¿°åããŒãã«ã«åçã«ã€ã³ããã¯ã¹ãä»ããããšãã§ããŸãã ãããã£ãŠãã·ã§ãŒããŒã¯ã·ã§ãŒããŒã®å®è¡äžã«èšè¿°åããŒãã«ããç®çã®èšè¿°åãéžæã§ããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯åçŽã«1ã€ã®å€§ããªèšè¿°åããŒãã«ãäœæããåžžã«ã€ã³ããã¯ã¹ã䜿çšããŠïŒããšãã°ãææèå¥åã䜿çšããŠïŒå¿ èŠãªèšè¿°åãååŸã§ããŸãã
èšè¿°åããŒãã«ã䜿çšããå Žåãšæ¯èŒããŠãã«ãŒãå®æ°ãšã«ãŒãèšè¿°åã®å€§ããªã»ããã䜿çšããå Žåãç°ãªãã¢ãŒããã¯ãã£ã®ããã©ãŒãã³ã¹ã¯ç°ãªãå ŽåããããŸãã ãã®ãããã¿ãŒã²ããããŒããŠã§ã¢ãã©ãããã©ãŒã ã«å¿ããŠãã«ãŒããã©ã¡ãŒã¿ãŒãšèšè¿°åããŒãã«ã®é¢ä¿ãæé©ã«æ§æããå¿ èŠããããŸãã
å®å šã«ãã©ã³ã¹ã®ãšããã¢ããªã±ãŒã·ã§ã³ã¯ããã¹ãŠã®ã¿ã€ãã®ãã€ã³ãã£ã³ã°ã®çµã¿åããã䜿çšã§ããŸããã«ãŒãå®æ°ãã«ãŒãèšè¿°åãã¬ã³ããªã³ã°åŒã³åºãã®çºè¡æã«ãªã³ã¶ãã©ã€ã§åä¿¡ãããèšè¿°åã®èšè¿°åããŒãã«ãããã³å€§ããªèšè¿°åããŒãã«ã®åçã€ã³ããã¯ã¹ä»ãã
次ã®ã³ãŒãã§ã¯ãäžèšã®2ã€ã®èšè¿°åããŒãã«ãã«ãŒã眲åã®ã«ãŒããã©ã¡ãŒã¿ãŒãšããŠä¿åãããŸãã
// define descriptor tables for a SRV and a sampler for pixel shaders D3D12_DESCRIPTOR_RANGE descRange[2]; descRange[0].Init(D3D12_DESCRIPTOR_RANGE_SRV, 1, 0); descRange[1].Init(D3D12_DESCRIPTOR_RANGE_SAMPLER, 1, 0); D3D12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[1].InitAsDescriptorTable(1, &descRange[1], D3D12_SHADER_VISIBILITY_PIXEL); // store the descriptor tables int the root signature D3D12_ROOT_SIGNATURE descRootSignature; descRootSignature.Init(2, rootParameters, 0); ComPtr<ID3DBlob> pOutBlob; ComPtr<ID3DBlob> pErrorBlob; ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_V1, pOutBlob.GetAddressOf(), pErrorBlob.GetAddressOf())); ThrowIfFailed(mDevice->CreateRootSignature(pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), (void**)&mRootSignature));
PSOã®ãã¹ãŠã®ã·ã§ãŒããŒã¯ããã®PSOã§æå®ãããã«ãŒãã·ã°ããã£ãšäºææ§ãããå¿ èŠããããŸãã ããããªããšãPSOã¯äœæãããŸããã
ã«ãŒã眲åã¯ãã³ãã³ããŸãã¯ããã±ãŒãžã®ãªã¹ãã«æå®ããå¿ èŠããããŸãã ãããè¡ãã«ã¯ã次ãåŒã³åºããŸãã
1 commandList-> SetGraphicsRootSignatureïŒmRootSignatureïŒ;
ã«ãŒã眲åãèšå®ããåŸãäžé£ã®ãã€ã³ãã£ã³ã°ãå®çŸ©ããå¿ èŠããããŸãã äžèšã®äŸã§ã¯ãããã¯æ¬¡ã®ã³ãŒãã䜿çšããŠè¡ãããŸãã
// set the two descriptor tables to index into the descriptor heap // for the SRV and the sampler commandList->SetGraphicsRootDescriptorTable(0, mCbvSrvDescriptorHeap->GetGPUDescriptorHandleForHeapStart()); commandList->SetGraphicsRootDescriptorTable(1, mSamplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
ã¢ããªã±ãŒã·ã§ã³ã¯ãã¬ã³ããŒã³ãŒã«ãŸãã¯éä¿¡ã³ãŒã«ãçºè¡ããåã«ãã«ãŒã眲åã®2ã€ã®ã»ã«ã®ããããã«é©åãªãã©ã¡ãŒã¿ãŒãèšå®ããå¿ èŠããããŸãã ããšãã°ãæåã®ã»ã«ã«ã¯ãèšè¿°åã®ããŒããã€ã³ããã¯ã¹å ã®SRVèšè¿°åãšäžèŽãããèšè¿°åããŒã«ãŒãããã2çªç®ã®ã»ã«ã«ã¯ãèšè¿°åã®ããŒããã€ã³ããã¯ã¹å ã®èšè¿°åãµã³ãã©ãšäžèŽãããèšè¿°åããŒãã«ããããŸãã
ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã¯ãåŒã³åºãã®ã¬ã³ããªã³ã°ã®ééã§2çªç®ã®ã»ã«ã®ãã€ã³ããå€æŽã§ããŸãã ããã¯ã2åç®ã®ã¬ã³ããªã³ã°åŒã³åºãã§ã¯ã2çªç®ã®ã»ã«ãã€ã³ãã£ã³ã°ã®ã¿ãå¿ èŠã§ããããšãæå³ããŸãã
ã³ã³ããŒãã³ãããŸãšãã
以äžã®å€§ããªã³ãŒãã¹ããããã¯ããªãœãŒã¹ã®ãã€ã³ãã«äœ¿çšããããã¹ãŠã®ã¡ã«ããºã ã瀺ããŠããŸãã ãã®ã¢ããªã±ãŒã·ã§ã³ã¯1ã€ã®ãã¯ã¹ãã£ã®ã¿ã䜿çšãããã®ã³ãŒãã¯ãã®ãã¯ã¹ãã£ã®ãµã³ãã©ãŒãšSRVãæäŸããŸãã
// define descriptor tables for a SRV and a sampler for pixel shaders D3D12_DESCRIPTOR_RANGE descRange[2]; descRange[0].Init(D3D12_DESCRIPTOR_RANGE_SRV, 1, 0); descRange[1].Init(D3D12_DESCRIPTOR_RANGE_SAMPLER, 1, 0); D3D12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[1].InitAsDescriptorTable(1, &descRange[1], D3D12_SHADER_VISIBILITY_PIXEL); // store the descriptor tables in the root signature D3D12_ROOT_SIGNATURE descRootSignature; descRootSignature.Init(2, rootParameters, 0); ComPtr<ID3DBlob> pOutBlob; ComPtr<ID3DBlob> pErrorBlob; ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_V1, pOutBlob.GetAddressOf(), pErrorBlob.GetAddressOf())); ThrowIfFailed(mDevice->CreateRootSignature(pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), (void**)&mRootSignature)); // create descriptor heap for shader resource view D3D12_DESCRIPTOR_HEAP_DESC descHeapCbvSrv = {}; descHeapCbvSrv.NumDescriptors = 1; // for SRV descHeapCbvSrv.Type = D3D12_CBV_SRV_UAV_DESCRIPTOR_HEAP; descHeapCbvSrv.Flags = D3D12_DESCRIPTOR_HEAP_SHADER_VISIBLE; ThrowIfFailed(mDevice->CreateDescriptorHeap(&descHeapCbvSrv, __uuidof(ID3D12DescriptorHeap), (void**)&mCbvSrvDescriptorHeap)); // create sampler descriptor heap D3D12_DESCRIPTOR_HEAP_DESC descHeapSampler = {}; descHeapSampler.NumDescriptors = 1; descHeapSampler.Type = D3D12_SAMPLER_DESCRIPTOR_HEAP; descHeapSampler.Flags = D3D12_DESCRIPTOR_HEAP_SHADER_VISIBLE; ThrowIfFailed(mDevice->CreateDescriptorHeap(&descHeapSampler, __uuidof(ID3D12DescriptorHeap), (void**)&mSamplerDescriptorHeap)); // skip the code that uploads the texture data into heap // create sampler descriptor in the sample descriptor heap D3D12_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(D3D12_SAMPLER_DESC)); samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_WRAP; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; samplerDesc.MipLODBias = 0.0f; samplerDesc.MaxAnisotropy = 1; samplerDesc.ComparisonFunc = D3D12_COMPARISON_ALWAYS; mDevice->CreateSampler(&samplerDesc, mSamplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); // create SRV descriptor in the SRV descriptor heap D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(D3D12_SHADER_RESOURCE_VIEW_DESC)); srvDesc.Format = SampleAssets::Textures->Format; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; mDevice->CreateShaderResourceView(mTexture.Get(), &srvDesc, mCbvSrvDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); // writing into the command list // set the root signature commandList->SetGraphicsRootSignature(mRootSignature); // other commands here ... // set the two descriptor tables to index into the descriptor heap // for the SRV and the sampler commandList->SetGraphicsRootDescriptorTable(0, mCbvSrvDescriptorHeap->GetGPUDescriptorHandleForHeapStart()); commandList->SetGraphicsRootDescriptorTable(1, mSamplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
éçãµã³ãã©ãŒ
ãã®ãããèšè¿°åã®æãšèšè¿°åããŒãã«ã䜿çšããŠãµã³ãã©ãŒãäœæããæ¹æ³ãèŠãŸããã ããããã¢ããªã±ãŒã·ã§ã³ã§ãµã³ãã©ãŒã䜿çšããå¥ã®æ¹æ³ããããŸãã å€ãã®ã¢ããªã±ãŒã·ã§ã³ã§å¿ èŠãªãµã³ãã©ãŒã®ã»ããã¯éãããŠãããããéçãµã³ãã©ãŒãã«ãŒãåŒæ°ãšããŠäœ¿çšã§ããŸãã
çŸåšãã«ãŒã眲åã¯æ¬¡ã®ãšããã§ãã
typedef struct D3D12_ROOT_SIGNATURE { UINT NumParameters; const D3D12_ROOT_PARAMETER* pParameters; UINT NumStaticSamplers; const D3D12_STATIC_SAMPLER* pStaticSamplers; D3D12_ROOT_SIGNATURE_FLAGS Flags; // Initialize struct void Init( UINT numParameters, const D3D12_ROOT_PARAMETER* _pParameters, UINT numStaticSamplers = 0, const D3D12_STATIC_SAMPLER* _pStaticSamplers = NULL, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_NONE) { NumParameters = numParameters; pParameters = _pParameters; NumStaticSamplers = numStaticSamplers; pStaticSamplers = _pStaticSamplers; Flags = flags; } D3D12_ROOT_SIGNATURE() { Init(0,NULL,0,NULL,D3D12_ROOT_SIGNATURE_NONE);} D3D12_ROOT_SIGNATURE( UINT numParameters, const D3D12_ROOT_PARAMETER* _pParameters, UINT numStaticSamplers = 0, const D3D12_STATIC_SAMPLER* _pStaticSamplers = NULL, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_NONE) { Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); } } D3D12_ROOT_SIGNATURE;
éçãµã³ãã©ãŒã®ã»ããã¯ãã«ãŒã眲åã®ã«ãŒããã©ã¡ãŒã¿ãŒãšã¯ç¡é¢ä¿ã«å®çŸ©ã§ããŸãã åè¿°ã®ããã«ãã«ãŒããã©ã¡ãŒã¿ãŒã¯ãå®è¡æã«åŒæ°ãæäŸã§ãããã€ã³ãã£ã³ã°ã¹ããŒã¹ãå®çŸ©ããŸãããéçãµã³ãã©ãŒã¯å®çŸ©ã«ãã£ãŠå€æŽãããŸããã
ã«ãŒã眲åã¯HLSLã§äœæã§ãããããåãå Žæã«éçãµã³ãã©ãŒãäœæã§ããŸãã çŸåšãã¢ããªã±ãŒã·ã§ã³ã«ã¯2032åãŸã§ã®äžæã®éçãµã³ãã©ãŒãå«ããããšãã§ããŸãã ããã¯ã次ã®2ã®ã¹ãä¹ããããããã«å°ãªãããã©ã€ããŒãå éšäœ¿çšã®ããã«ã¹ããŒã¹ã䜿çšã§ããããã«ããŸãã
ã«ãŒãã·ã°ããã£ã§å®çŸ©ãããéçãµã³ãã©ãŒã¯ãã¢ããªã±ãŒã·ã§ã³ãããŒãèšè¿°åã«é 眮ããããã«éžæãããµã³ãã©ãŒããç¬ç«ããŠãããããäž¡æ¹ã®ã¡ã«ããºã ãåæã«äœ¿çšã§ããŸãã
ãµã³ãã©ãŒã®éžæãå®å šã«åçã§ãããã·ã§ãŒããŒã®ã³ã³ãã€ã«æã«äžæã§ããå Žåãã¢ããªã±ãŒã·ã§ã³ã¯èšè¿°åã®ããŒãå ã§ãµã³ãã©ãŒã管çããå¿ èŠããããŸãã
ãããã«
DirectX 12ã¯ããªãœãŒã¹äœ¿çšãã¿ãŒã³ã®å®å šãªå¶åŸ¡ããµããŒãããŸãã ã¢ããªã±ãŒã·ã§ã³éçºè ã¯ãèšè¿°åããŒãå ã®ã¡ã¢ãªã®å²ãåœãŠãèšè¿°åå ã®ãªãœãŒã¹ã®èšè¿°ãããã³èšè¿°åããŒãã«ãä»ããããŒãèšè¿°åãžã®ã€ã³ããã¯ã¹å ã®ã·ã§ãŒããŒã®ã¢ãã¬ã¹æå®ãæ åœããŸããããã¯ãã«ãŒã眲åã䜿çšããŠã·ã§ãŒããŒçšã«ãæ¡åŒµããããŸãã
ããã«ãã«ãŒãã·ã°ããã£ã䜿çšããŠã次ã®4ã€ã®ã¿ã€ãã®ã³ã³ããŒãã³ããä»»æã®çµã¿åããã§äœ¿çšããŠãã·ã§ãŒããŒã®ã«ã¹ã¿ã ãã©ã¡ãŒã¿ã¹ããŒã¹ãå®çŸ©ã§ããŸãã
- ã«ãŒãå®æ°ã
- éçãµã³ãã©ãŒ
- ã«ãŒãèšè¿°åã
- èšè¿°åããŒãã«ã
ã¿ã¹ã¯ã¯ã察å¿ããã¿ã€ãã®ãªãœãŒã¹ãšãã®æŽæ°ã®é »åºŠã«å¿ èŠãªãã€ã³ãã£ã³ã°ã®åœ¢åŒãéžæããããšã§ãã