Guest User

netwars-govnoengine-02

a guest
May 31st, 2015
79
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //--------------------------------------------------------------------------------------
  2. // File: CS.cpp
  3. // Description: Class for work with compute shader.
  4. // Copyright (©) Dmitry N. Blinnikov (Jimnik). All rights reserved.
  5. //--------------------------------------------------------------------------------------
  6.  
  7.  
  8. #include "..\Engine\NetWars.h"  // NetWars Engine
  9. #include "D3Dcompiler.h"
  10. #include "D3DX10Math.h"
  11. #include "D3DX11async.h"    // D3DX11CompileFromFileW - Library D3DX11.lib
  12. #include <stdio.h>  // swprintf_s
  13.  
  14. #include "CS.h" // Class of Compute Shader
  15.  
  16.  
  17. //--------------------------------------------------------------------------------------
  18. // CONSTRUCTOR
  19. //--------------------------------------------------------------------------------------
  20. CCS::CCS()
  21. {
  22.     m_nMove = 0;    // Number of moves
  23. }
  24.  
  25.  
  26. //--------------------------------------------------------------------------------------
  27. // INITIALIZATION
  28. //--------------------------------------------------------------------------------------
  29. void CCS::init(ID3D11Device* pD3D)
  30. {
  31.     // Compile Compute Shader
  32.     ID3D10Blob* pBlob;      // Shader buffer
  33.     ID3D10Blob* pErrorBlob; // Shader error buffer
  34.     D3DX11CompileFromFileW(L"..\\Content\\Shader\\CS.hlsl", NULL, NULL, "CSMain", "cs_4_0", D3D10_SHADER_ENABLE_STRICTNESS, NULL, NULL, &pBlob, &pErrorBlob, NULL);
  35.     if (pErrorBlob)
  36.     {
  37.         pErrorBlob->GetBufferPointer();
  38.         // then cast to a char* to see it in the locals window
  39.     }
  40.  
  41.     // Create Compute Shader
  42.     m_pCS = NULL;
  43.     pD3D->CreateComputeShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, &m_pCS);
  44.  
  45.     // Release the shader buffers
  46.     SAFE_RELEASE(pBlob);
  47.     SAFE_RELEASE(pErrorBlob);
  48. }
  49.  
  50.  
  51. //--------------------------------------------------------------------------------------
  52. // RESIZE THE OUTPUT SCENE
  53. //--------------------------------------------------------------------------------------
  54. /*HRESULT   CCS::resize(ID3D11Device* pD3D, float fW, float fH)
  55. {
  56.     //m_fW = fW;    // Width
  57.     //m_fH = fH;    // Height
  58.  
  59.     return S_OK;
  60. }*/
  61.  
  62.  
  63. //--------------------------------------------------------------------------------------
  64. // CREATE STRUCTURED BUFFER ON GPU
  65. //-------------------------------------------------------------------------------------
  66. HRESULT CCS::CreateStructuredBufferOnGPU(ID3D11Device* pD3D, UINT uElementSize, UINT uCount, VOID* pInitData, ID3D11Buffer** ppBufOut)
  67. {
  68.     *ppBufOut = NULL;
  69.     D3D11_BUFFER_DESC desc;
  70.     ZeroMemory(&desc, sizeof(desc));
  71.     desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
  72.     desc.ByteWidth = uElementSize * uCount;
  73.     desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
  74.     desc.StructureByteStride = uElementSize;
  75.  
  76.     if (pInitData)
  77.     {
  78.         D3D11_SUBRESOURCE_DATA InitData;
  79.         InitData.pSysMem = pInitData;
  80.         return pD3D->CreateBuffer(&desc, &InitData, ppBufOut);
  81.     }
  82.     else
  83.         return pD3D->CreateBuffer(&desc, NULL, ppBufOut);
  84. }
  85.  
  86.  
  87. //--------------------------------------------------------------------------------------
  88. // CREATE A RESOURCE OF RAW OR STRUCTURED BUFFER
  89. //--------------------------------------------------------------------------------------
  90. HRESULT CCS::CreateBufferSRV(ID3D11Device* pD3D, ID3D11Buffer* pBuffer, ID3D11ShaderResourceView** ppSRVOut)
  91. {
  92.     D3D11_BUFFER_DESC descBuf;
  93.     ZeroMemory(&descBuf, sizeof(descBuf));
  94.     pBuffer->GetDesc(&descBuf);
  95.  
  96.     D3D11_SHADER_RESOURCE_VIEW_DESC desc;
  97.     ZeroMemory(&desc, sizeof(desc));
  98.     desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
  99.     desc.BufferEx.FirstElement = 0;
  100.  
  101.     if (descBuf.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) // If Raw buffer
  102.     {
  103.         desc.Format = DXGI_FORMAT_R32_TYPELESS;
  104.         desc.BufferEx.Flags = D3D11_BUFFEREX_SRV_FLAG_RAW;
  105.         desc.BufferEx.NumElements = descBuf.ByteWidth / 4;
  106.     }
  107.     else if (descBuf.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) // If Structured buffer
  108.     {
  109.         desc.Format = DXGI_FORMAT_UNKNOWN;
  110.         desc.BufferEx.NumElements = descBuf.ByteWidth / descBuf.StructureByteStride;
  111.     }
  112.     else
  113.         return E_INVALIDARG;
  114.  
  115.     return pD3D->CreateShaderResourceView(pBuffer, &desc, ppSRVOut);
  116. }
  117.  
  118.  
  119. //--------------------------------------------------------------------------------------
  120. // CREATE AN UNORDERED ACCESS TO THE RAW OR STRUCTURED BUFFER
  121. //--------------------------------------------------------------------------------------
  122. HRESULT CCS::CreateBufferUAV(ID3D11Device* pD3D, ID3D11Buffer* pBuffer, ID3D11UnorderedAccessView** ppUAVOut)
  123. {
  124.     D3D11_BUFFER_DESC descBuf;
  125.     ZeroMemory(&descBuf, sizeof(descBuf));
  126.     pBuffer->GetDesc(&descBuf);
  127.  
  128.     D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
  129.     ZeroMemory(&desc, sizeof(desc));
  130.     desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
  131.     desc.Buffer.FirstElement = 0;
  132.  
  133.     if (descBuf.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) // If Raw buffer
  134.     {
  135.         desc.Format = DXGI_FORMAT_R32_TYPELESS; // When creating a disordered access to buffer Raw its format must also be DXGI_FORMAT_R32_TYPELESS
  136.         desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
  137.         desc.Buffer.NumElements = descBuf.ByteWidth / 4;
  138.     }
  139.     else if (descBuf.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) // If Structured buffer
  140.     {
  141.         desc.Format = DXGI_FORMAT_UNKNOWN;      // When creating a disordered Structured access to its buffer size must also be DXGI_FORMAT_UNKNOWN
  142.         desc.Buffer.NumElements = descBuf.ByteWidth / descBuf.StructureByteStride;
  143.     }
  144.     else
  145.         return E_INVALIDARG;
  146.  
  147.     return pD3D->CreateUnorderedAccessView(pBuffer, &desc, ppUAVOut);
  148. }
  149.  
  150.  
  151. //--------------------------------------------------------------------------------------
  152. // RUN COMPUTE SHADER
  153. //--------------------------------------------------------------------------------------
  154. void CCS::RunComputeShader(ID3D11DeviceContext* pd3dImmediateContext, ID3D11ComputeShader* pComputeShader, UINT nNumViews,
  155.     ID3D11ShaderResourceView** pShaderResourceViews, ID3D11Buffer* pCBCS, void* pCSData, DWORD dwNumDataBytes,
  156.     ID3D11UnorderedAccessView* pUnorderedAccessView, UINT X, UINT Y, UINT Z)
  157. {
  158.     pd3dImmediateContext->CSSetShader(pComputeShader, NULL, 0);
  159.     pd3dImmediateContext->CSSetShaderResources(0, nNumViews, pShaderResourceViews);
  160.     pd3dImmediateContext->CSSetUnorderedAccessViews(0, 1, &pUnorderedAccessView, (UINT*)&pUnorderedAccessView);
  161.     if (pCBCS)
  162.     {
  163.         D3D11_MAPPED_SUBRESOURCE MappedResource;
  164.         pd3dImmediateContext->Map(pCBCS, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
  165.         memcpy(MappedResource.pData, pCSData, dwNumDataBytes);
  166.         pd3dImmediateContext->Unmap(pCBCS, 0);
  167.         ID3D11Buffer* ppCB[1] = { pCBCS };
  168.         pd3dImmediateContext->CSSetConstantBuffers(0, 1, ppCB);
  169.     }
  170.     pd3dImmediateContext->Dispatch(X, Y, Z);
  171.     ID3D11UnorderedAccessView* ppUAViewNULL[1] = { NULL };
  172.     pd3dImmediateContext->CSSetUnorderedAccessViews(0, 1, ppUAViewNULL, (UINT*)(&ppUAViewNULL));
  173.     ID3D11ShaderResourceView* ppSRVNULL[3] = { NULL, NULL, NULL };
  174.     pd3dImmediateContext->CSSetShaderResources(0, 3, ppSRVNULL);
  175.     pd3dImmediateContext->CSSetConstantBuffers(0, 0, NULL);
  176. }
  177.  
  178.  
  179. //--------------------------------------------------------------------------------------
  180. // CREATE CPU-BUFFER AND COPY GPU-BUFFER TO IT
  181. // THIS FEATURE IS VERY USEFUL FOR DEBUGGING COMPUTE SHADER
  182. //--------------------------------------------------------------------------------------
  183. ID3D11Buffer* CCS::CreateAndCopyToDebugBuf(ID3D11Device* pDevice, ID3D11DeviceContext* pd3dImmediateContext, ID3D11Buffer* pBuffer)
  184. {
  185.     ID3D11Buffer* debugbuf = NULL;
  186.     D3D11_BUFFER_DESC desc;
  187.     ZeroMemory(&desc, sizeof(desc));
  188.     pBuffer->GetDesc(&desc);
  189.     desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  190.     desc.Usage = D3D11_USAGE_STAGING;
  191.     desc.BindFlags = 0;
  192.     desc.MiscFlags = 0;
  193.     pDevice->CreateBuffer(&desc, NULL, &debugbuf);
  194.     pd3dImmediateContext->CopyResource(debugbuf, pBuffer);
  195.  
  196.     return debugbuf;
  197. }
  198.  
  199.  
  200. //--------------------------------------------------------------------------------------
  201. // RENDERING
  202. //--------------------------------------------------------------------------------------
  203. void CCS::render(ID3D11Device *pD3D, ID3D11DeviceContext* pContext, float)
  204. {
  205.     m_nMove = 8;
  206.     for (int i = 0; i < 320; i++)
  207.     {
  208.         iBeg[i] = 5;
  209.         iEnd[i] = 6;
  210.         iWeight[i] = 7;
  211.     }
  212.  
  213.     // Input output registers
  214.     m_pBufBeg = NULL;       // Buffer start of move
  215.     m_pBufEnd = NULL;       // Buffer end of move
  216.     m_pBufWeight = NULL;    // Buffer weight of move
  217.     m_pBufResult = NULL;    // Buffer result of move
  218.     CreateStructuredBufferOnGPU(pD3D, 4, (UINT)m_nMove, &iBeg[0], &m_pBufBeg);  // 4 - sizeof(int)
  219.     CreateStructuredBufferOnGPU(pD3D, 4, (UINT)m_nMove, &iEnd[0], &m_pBufEnd);
  220.     CreateStructuredBufferOnGPU(pD3D, 4, (UINT)m_nMove, &iWeight[0], &m_pBufWeight);
  221.     CreateStructuredBufferOnGPU(pD3D, 4, (UINT)m_nMove, NULL, &m_pBufResult);
  222.  
  223.     ID3D11ShaderResourceView *pBufBeg_SRV = NULL;
  224.     ID3D11ShaderResourceView *pBufEnd_SRV = NULL;
  225.     ID3D11ShaderResourceView *pBufWeight_SRV = NULL;
  226.     ID3D11UnorderedAccessView *pBufResult_UAV = NULL;
  227.  
  228.     CreateBufferSRV(pD3D, m_pBufBeg, &pBufBeg_SRV);
  229.     CreateBufferSRV(pD3D, m_pBufEnd, &pBufEnd_SRV);
  230.     CreateBufferSRV(pD3D, m_pBufWeight, &pBufWeight_SRV);
  231.     CreateBufferUAV(pD3D, m_pBufResult, &pBufResult_UAV);
  232.  
  233.     // Run compute shader
  234.     ID3D11ShaderResourceView* aRViews[3] = { pBufBeg_SRV, pBufEnd_SRV, pBufWeight_SRV };
  235.     RunComputeShader(pContext, m_pCS, 3, aRViews, NULL, NULL, 0, pBufResult_UAV, 200, 1, 1);
  236.  
  237.     // Read the result from the GPU, and copy to the CPU buffer
  238.     ID3D11Buffer* pBufResult = CreateAndCopyToDebugBuf(pD3D, pContext, m_pBufResult);
  239.     D3D11_MAPPED_SUBRESOURCE MappedResource;
  240.     if (S_OK == pContext->Map(pBufResult, 0, D3D11_MAP_READ, 0, &MappedResource))
  241.     {
  242.         int *p = (int*)MappedResource.pData;
  243.         for (UINT i = 0; i<(UINT)m_nMove; i++)
  244.             iWeight[i] = p[i];
  245.         pContext->Unmap(pBufResult, 0);
  246.     }
  247.  
  248.     UINT iBest = 0;
  249.     for (UINT i = 1; i<(UINT)m_nMove; i++)
  250.         if (iWeight[i]>iWeight[iBest])
  251.             iBest = i;
  252.  
  253.     m_iBestBeg = (byte)iBeg[iBest];
  254.     m_iBestEnd = (byte)iEnd[iBest];
  255.  
  256.     SAFE_RELEASE(pBufResult);
  257.  
  258.     SAFE_RELEASE(pBufBeg_SRV);
  259.     SAFE_RELEASE(pBufEnd_SRV);
  260.     SAFE_RELEASE(pBufWeight_SRV);
  261.     SAFE_RELEASE(pBufResult_UAV);
  262.  
  263.     SAFE_RELEASE(m_pBufBeg);
  264.     SAFE_RELEASE(m_pBufEnd);
  265.     SAFE_RELEASE(m_pBufWeight);
  266.     SAFE_RELEASE(m_pBufResult);
  267. }
  268.  
  269.  
  270. //--------------------------------------------------------------------------------------
  271. // DEINITIALIZATION
  272. //--------------------------------------------------------------------------------------
  273. void CCS::free()
  274. {
  275.     SAFE_RELEASE(m_pCS);
  276. }
RAW Paste Data