DeviceResources.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // The MIT License(MIT)
  2. //
  3. // Copyright(c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. // this software and associated documentation files(the "Software"), to deal in
  7. // the Software without restriction, including without limitation the rights to
  8. // use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
  9. // the Software, and to permit persons to whom the Software is furnished to do so,
  10. // subject to the following conditions :
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
  18. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #include "DeviceResources.h"
  22. #include "DXUtilities.h"
  23. void DeviceResources::create(HWND hWnd, uint32_t adapterIdx)
  24. {
  25. DXGI_SWAP_CHAIN_DESC desc;
  26. ZeroMemory(&desc, sizeof(desc));
  27. desc.BufferCount = 2;
  28. desc.BufferDesc.Width = 320;
  29. desc.BufferDesc.Height = 200;
  30. desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  31. desc.BufferDesc.RefreshRate.Numerator = 0;
  32. desc.BufferDesc.RefreshRate.Denominator = 0;
  33. desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
  34. desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  35. desc.OutputWindow = hWnd;
  36. desc.SampleDesc.Count = 1;
  37. desc.SampleDesc.Quality = 0;
  38. desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  39. desc.Windowed = TRUE;
  40. ComPtr<IDXGIFactory> pFactory;
  41. CreateDXGIFactory(__uuidof(IDXGIFactory) ,(void**)&pFactory);
  42. ComPtr<IDXGIAdapter> pAdapter;
  43. if(pFactory->EnumAdapters(adapterIdx, &pAdapter) != DXGI_ERROR_NOT_FOUND)
  44. {
  45. DXGI_ADAPTER_DESC desc;
  46. pAdapter->GetDesc(&desc);
  47. char description[256]{};
  48. snprintf(description, sizeof(description), "%ls", desc.Description);
  49. m_adapter.Description = description;
  50. m_adapter.DeviceId = desc.DeviceId;
  51. m_adapter.VendorId = desc.VendorId;
  52. m_adapter.DedicatedSystemMemory = desc.DedicatedSystemMemory;
  53. m_adapter.DedicatedVideoMemory = desc.DedicatedVideoMemory;
  54. m_adapter.SharedSystemMemory = desc.SharedSystemMemory;
  55. }
  56. else
  57. {
  58. throw std::runtime_error("Adapter not found");
  59. }
  60. uint32_t createDeviceFlags = 0;
  61. #ifdef DX11_ENABLE_DEBUG_LAYER
  62. createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
  63. #endif
  64. D3D_FEATURE_LEVEL featureLevel;
  65. const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0 };
  66. HRESULT hr = D3D11CreateDeviceAndSwapChain(pAdapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
  67. createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &desc,
  68. &m_swapChain, &m_d3dDevice, &featureLevel, &m_d3dContext);
  69. DX::ThrowIfFailed(hr);
  70. initRenderTarget();
  71. m_initialized = true;
  72. }
  73. void DeviceResources::initRenderTarget()
  74. {
  75. DX::ThrowIfFailed(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &m_d3dRenderTarget));
  76. DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(m_d3dRenderTarget.Get(), NULL, &m_d3dRenderTargetView));
  77. }
  78. void DeviceResources::resizeRenderTarget(uint32_t Width, uint32_t Height, DXGI_FORMAT format)
  79. {
  80. m_width = Width;
  81. m_height = Height;
  82. m_d3dRenderTargetUAV = nullptr;
  83. m_d3dRenderTargetView = nullptr;
  84. m_d3dRenderTarget = nullptr;
  85. DX::ThrowIfFailed(m_swapChain->ResizeBuffers(0, Width, Height, format, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH));
  86. initRenderTarget();
  87. }
  88. void DeviceResources::clearRenderTargetView(const float color[4])
  89. {
  90. m_d3dContext->ClearRenderTargetView(m_d3dRenderTargetView.Get(), color);
  91. }
  92. void DeviceResources::createUAV(ID3D11Resource* pResource, DXGI_FORMAT format, ID3D11UnorderedAccessView** ppUAView)
  93. {
  94. D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
  95. ZeroMemory(&uavDesc, sizeof(D3D11_UNORDERED_ACCESS_VIEW_DESC));
  96. uavDesc.Format = format;
  97. uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
  98. DX::ThrowIfFailed(m_d3dDevice->CreateUnorderedAccessView(pResource, &uavDesc, ppUAView));
  99. }
  100. void DeviceResources::createSRV(ID3D11Resource* pResource, DXGI_FORMAT format, ID3D11ShaderResourceView** ppSRView)
  101. {
  102. D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
  103. ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
  104. srvDesc.Format = format;
  105. srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
  106. srvDesc.Texture2D.MostDetailedMip = 0;
  107. srvDesc.Texture2D.MipLevels = 1;
  108. DX::ThrowIfFailed(m_d3dDevice->CreateShaderResourceView(pResource, &srvDesc, ppSRView));
  109. }
  110. void DeviceResources::createLinearClampSampler(ID3D11SamplerState** ppSampleState)
  111. {
  112. D3D11_SAMPLER_DESC samplerDesc;
  113. ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC));
  114. samplerDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
  115. samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
  116. samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
  117. samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
  118. samplerDesc.MipLODBias = 0.0f;
  119. samplerDesc.MaxAnisotropy = 1;
  120. samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
  121. samplerDesc.MinLOD = 0;
  122. samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
  123. DX::ThrowIfFailed(m_d3dDevice->CreateSamplerState(&samplerDesc, ppSampleState));
  124. }
  125. void DeviceResources::createTexture2D(int w, int h, DXGI_FORMAT format, D3D11_USAGE heapType, const void* data, uint32_t rowPitch, uint32_t imageSize, ID3D11Texture2D** ppTexture2D)
  126. {
  127. D3D11_TEXTURE2D_DESC desc;
  128. desc.Width = w;
  129. desc.Height = h;
  130. desc.MipLevels = 1;
  131. desc.ArraySize = 1;
  132. desc.Format = format;
  133. desc.SampleDesc.Count = 1;
  134. desc.SampleDesc.Quality = 0;
  135. desc.MiscFlags = 0;
  136. desc.Usage = heapType;
  137. if (heapType == D3D11_USAGE_STAGING)
  138. {
  139. desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
  140. desc.BindFlags = 0;
  141. }
  142. else
  143. {
  144. desc.CPUAccessFlags = 0;
  145. desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
  146. desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
  147. }
  148. D3D11_SUBRESOURCE_DATA* pInitialData = nullptr;
  149. D3D11_SUBRESOURCE_DATA initData;
  150. if (data)
  151. {
  152. initData.pSysMem = data;
  153. initData.SysMemPitch = rowPitch;
  154. initData.SysMemSlicePitch = imageSize;
  155. pInitialData = &initData;
  156. }
  157. DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&desc, pInitialData, ppTexture2D));
  158. }
  159. void DeviceResources::getTextureData(ID3D11Texture2D* texture, std::vector<uint8_t>& data, uint32_t& width, uint32_t& height, uint32_t& rowPitch)
  160. {
  161. D3D11_TEXTURE2D_DESC desc;
  162. texture->GetDesc(&desc);
  163. desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  164. desc.BindFlags = 0;
  165. desc.Usage = D3D11_USAGE_STAGING;
  166. ComPtr<ID3D11Texture2D> stage;
  167. m_d3dDevice->CreateTexture2D(&desc, nullptr, &stage);
  168. m_d3dContext->CopyResource(stage.Get(), texture);
  169. D3D11_MAPPED_SUBRESOURCE mappedResource;
  170. DX::ThrowIfFailed(m_d3dContext->Map(stage.Get(), 0, D3D11_MAP_READ, 0, &mappedResource));
  171. uint8_t* mappData = (uint8_t*)mappedResource.pData;
  172. width = desc.Width;
  173. height = desc.Height;
  174. rowPitch = mappedResource.RowPitch;
  175. data.resize(mappedResource.DepthPitch);
  176. memcpy(data.data(), mappData, mappedResource.DepthPitch);
  177. m_d3dContext->Unmap(stage.Get(), 0);
  178. }
  179. void DeviceResources::updateConstBuffer(void* data, uint32_t size, ID3D11Buffer* ppBuffer)
  180. {
  181. D3D11_MAPPED_SUBRESOURCE mappedResource;
  182. m_d3dContext->Map(ppBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
  183. uint8_t* mappData = (uint8_t*)mappedResource.pData;
  184. memcpy(mappData, data, size);
  185. m_d3dContext->Unmap(ppBuffer, 0);
  186. }
  187. void DeviceResources::createConstBuffer(void* initialData, uint32_t size, ID3D11Buffer** ppBuffer)
  188. {
  189. D3D11_BUFFER_DESC bDesc;
  190. bDesc.ByteWidth = size;
  191. bDesc.Usage = D3D11_USAGE_DYNAMIC;
  192. bDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  193. bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  194. bDesc.MiscFlags = 0;
  195. bDesc.StructureByteStride = 0;
  196. D3D11_SUBRESOURCE_DATA srData;
  197. srData.pSysMem = initialData;
  198. DX::ThrowIfFailed(m_d3dDevice->CreateBuffer(&bDesc, &srData, ppBuffer));
  199. }