DX12ChunkData.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. #include "Dx12ChunkData.h"
  2. #include <DX12CommandQueue.h>
  3. #include "Constants.h"
  4. DX12ChunkData::DX12ChunkData(Framework::Point center)
  5. : ReferenceCounter(),
  6. aabbs(0),
  7. chunkInfoBuffer(0),
  8. blasScratchBuffer(0),
  9. blasBuffer(0),
  10. blockIndexBuffer(0),
  11. textureIdBuffer(0),
  12. lastObjectIndex(-1),
  13. lastHitGroupIndex(-1),
  14. chunkCenter(center),
  15. blockIndices(new int[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT]),
  16. textureIds(),
  17. changed(0),
  18. bufferChanged(0),
  19. minZ(WORLD_HEIGHT),
  20. maxZ(0),
  21. minMaxChanged(0)
  22. {
  23. memset(
  24. blockIndices, -1, sizeof(int) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
  25. }
  26. DX12ChunkData::~DX12ChunkData()
  27. {
  28. if (aabbs)
  29. {
  30. aabbs->release();
  31. }
  32. if (chunkInfoBuffer)
  33. {
  34. chunkInfoBuffer->release();
  35. }
  36. if (blasScratchBuffer)
  37. {
  38. blasScratchBuffer->release();
  39. }
  40. if (blasBuffer)
  41. {
  42. blasBuffer->release();
  43. }
  44. if (blockIndexBuffer)
  45. {
  46. blockIndexBuffer->release();
  47. }
  48. if (textureIdBuffer)
  49. {
  50. textureIdBuffer->release();
  51. }
  52. delete[] blockIndices;
  53. }
  54. Framework::DX12Buffer* DX12ChunkData::zChunkInfoBuffer() const
  55. {
  56. return chunkInfoBuffer;
  57. }
  58. Framework::DX12Buffer* DX12ChunkData::zBlasBuffer() const
  59. {
  60. return blasBuffer;
  61. }
  62. Framework::DX12Buffer* DX12ChunkData::zBlockIndexBuffer() const
  63. {
  64. return blockIndexBuffer;
  65. }
  66. Framework::DX12Buffer* DX12ChunkData::zTextureIdBuffer() const
  67. {
  68. return textureIdBuffer;
  69. }
  70. void DX12ChunkData::setBlock(int index, Block* zBlock)
  71. {
  72. cs.lock();
  73. if (zBlock)
  74. {
  75. if (blockIndices[index] < 0)
  76. {
  77. blockIndices[index] = textureIds.getEntryCount();
  78. for (int i = 0; i < 6; ++i)
  79. {
  80. textureIds.add(zBlock->zTexture()->zPolygonTexture(i)->getId());
  81. }
  82. }
  83. else
  84. {
  85. ArrayIterator<int> textureIt = textureIds.begin();
  86. int tmp = blockIndices[index];
  87. while (tmp > 0)
  88. {
  89. ++textureIt;
  90. --tmp;
  91. }
  92. for (int i = 0; i < 6; ++i)
  93. {
  94. textureIt.set(zBlock->zTexture()->zPolygonTexture(i)->getId());
  95. ++textureIt;
  96. }
  97. }
  98. if (zBlock->getLocation().z + 1 > maxZ)
  99. {
  100. maxZ = zBlock->getLocation().z + 1;
  101. minMaxChanged = 1;
  102. }
  103. if (zBlock->getLocation().z < minZ)
  104. {
  105. minZ = zBlock->getLocation().z;
  106. minMaxChanged = 1;
  107. }
  108. }
  109. else
  110. {
  111. if (blockIndices[index] >= 0)
  112. {
  113. int tmp = blockIndices[index];
  114. ArrayIterator<int> textureIt = textureIds.begin();
  115. while (tmp > 0)
  116. {
  117. ++textureIt;
  118. --tmp;
  119. }
  120. for (int i = 0; i < 6; ++i)
  121. {
  122. textureIt.remove();
  123. }
  124. int oldMinZ = minZ;
  125. int oldMaxZ = maxZ;
  126. maxZ = 0;
  127. minZ = WORLD_HEIGHT;
  128. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
  129. {
  130. if (blockIndices[i] > blockIndices[index])
  131. {
  132. blockIndices[i] -= 6;
  133. }
  134. if (blockIndices[i] >= 0)
  135. {
  136. if (i % WORLD_HEIGHT + 1 > maxZ)
  137. {
  138. maxZ = i % WORLD_HEIGHT + 1;
  139. }
  140. if (i % WORLD_HEIGHT < minZ)
  141. {
  142. minZ = i % WORLD_HEIGHT;
  143. }
  144. }
  145. }
  146. if (minZ != oldMinZ || maxZ != oldMaxZ)
  147. {
  148. minMaxChanged = 1;
  149. }
  150. }
  151. blockIndices[index] = -1;
  152. }
  153. changed = 1;
  154. cs.unlock();
  155. }
  156. void DX12ChunkData::updateBuffers(
  157. ID3D12Device5* zDevice, Framework::DX12CommandQueue* zQueue)
  158. {
  159. cs.lock();
  160. if (!aabbs)
  161. {
  162. aabbs = new DX12Buffer(sizeof(D3D12_RAYTRACING_AABB),
  163. zDevice,
  164. dynamic_cast<Framework::DX12CommandQueue*>(zQueue->getThis()),
  165. D3D12_RESOURCE_FLAG_NONE);
  166. aabbs->setLength(sizeof(D3D12_RAYTRACING_AABB));
  167. D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f,
  168. chunkCenter.y - 8.f,
  169. minZ,
  170. chunkCenter.x + 8.f,
  171. chunkCenter.y + 8.f,
  172. maxZ};
  173. aabbs->setData(&data, 1);
  174. aabbs->copyToGPU();
  175. minMaxChanged = 0;
  176. }
  177. if (minMaxChanged)
  178. {
  179. D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f,
  180. chunkCenter.y - 8.f,
  181. minZ,
  182. chunkCenter.x + 8.f,
  183. chunkCenter.y + 8.f,
  184. maxZ};
  185. aabbs->setData(&data, 1);
  186. aabbs->copyToGPU();
  187. minMaxChanged = 0;
  188. }
  189. if (!blasBuffer)
  190. {
  191. D3D12_RAYTRACING_GEOMETRY_DESC geometryDesc = {};
  192. geometryDesc.Type
  193. = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
  194. geometryDesc.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
  195. geometryDesc.AABBs.AABBCount = 1;
  196. geometryDesc.AABBs.AABBs.StartAddress
  197. = aabbs->zBuffer()->GetGPUVirtualAddress();
  198. geometryDesc.AABBs.AABBs.StrideInBytes = sizeof(D3D12_RAYTRACING_AABB);
  199. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc;
  200. prebuildDesc.Type
  201. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  202. prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  203. prebuildDesc.NumDescs = 1;
  204. prebuildDesc.pGeometryDescs = &geometryDesc;
  205. prebuildDesc.Flags
  206. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
  207. D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {};
  208. zDevice->GetRaytracingAccelerationStructurePrebuildInfo(
  209. &prebuildDesc, &info);
  210. ID3D12Resource* oldBuffer = 0;
  211. if (blasBuffer)
  212. {
  213. oldBuffer = blasBuffer->zBuffer();
  214. oldBuffer->AddRef();
  215. blasBuffer->release();
  216. }
  217. blasBuffer = new DX12Buffer(1,
  218. zDevice,
  219. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  220. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  221. blasBuffer->setLength(
  222. ROUND_UP_POWER_OF_2(info.ResultDataMaxSizeInBytes, 256));
  223. blasBuffer->createBufferWithoutData(
  224. D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
  225. blasScratchBuffer = new DX12Buffer(1,
  226. zDevice,
  227. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  228. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  229. blasScratchBuffer->setLength(
  230. ROUND_UP_POWER_OF_2(info.ScratchDataSizeInBytes, 256));
  231. blasScratchBuffer->createBufferWithoutData(D3D12_RESOURCE_STATE_COMMON);
  232. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc;
  233. buildDesc.Inputs.Type
  234. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  235. buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  236. buildDesc.Inputs.NumDescs = 1;
  237. buildDesc.Inputs.pGeometryDescs = &geometryDesc;
  238. buildDesc.DestAccelerationStructureData
  239. = {blasBuffer->zBuffer()->GetGPUVirtualAddress()};
  240. buildDesc.ScratchAccelerationStructureData
  241. = {blasScratchBuffer->zBuffer()->GetGPUVirtualAddress()};
  242. buildDesc.SourceAccelerationStructureData = oldBuffer ? oldBuffer->GetGPUVirtualAddress() : 0;
  243. buildDesc.Inputs.Flags
  244. = oldBuffer
  245. ? D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE
  246. : D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
  247. zQueue->zCommandList()->BuildRaytracingAccelerationStructure(
  248. &buildDesc, 0, nullptr);
  249. if (oldBuffer)
  250. {
  251. oldBuffer->Release();
  252. }
  253. bufferChanged = 1;
  254. }
  255. if (!blockIndexBuffer)
  256. {
  257. blockIndexBuffer = new DX12Buffer(sizeof(int),
  258. zDevice,
  259. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  260. D3D12_RESOURCE_FLAG_NONE);
  261. blockIndexBuffer->setLength(
  262. sizeof(int) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
  263. bufferChanged = 1;
  264. }
  265. if (textureIdBuffer
  266. && textureIdBuffer->getElementCount() < textureIds.getEntryCount())
  267. {
  268. textureIdBuffer->release();
  269. textureIdBuffer = 0;
  270. }
  271. if (!textureIdBuffer)
  272. {
  273. textureIdBuffer = new DX12Buffer(sizeof(int),
  274. zDevice,
  275. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  276. D3D12_RESOURCE_FLAG_NONE);
  277. textureIdBuffer->setLength(textureIds.getEntryCount() * sizeof(int));
  278. bufferChanged = 1;
  279. }
  280. if (!chunkInfoBuffer)
  281. {
  282. chunkInfoBuffer = new DX12Buffer(sizeof(ChunkShaderInfo),
  283. zDevice,
  284. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  285. D3D12_RESOURCE_FLAG_NONE);
  286. chunkInfoBuffer->setLength(sizeof(ChunkShaderInfo));
  287. }
  288. if (changed)
  289. {
  290. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
  291. {
  292. assert(blockIndices[i] < 0
  293. || blockIndices[i] <= textureIds.getEntryCount() - 6);
  294. }
  295. int* textureIdData = new int[textureIds.getEntryCount()];
  296. ArrayIterator<int> textureIt = textureIds.begin();
  297. int index = 0;
  298. while (textureIt)
  299. {
  300. textureIdData[index++] = textureIt.val();
  301. ++textureIt;
  302. }
  303. blockIndexBuffer->setData(blockIndices, 1);
  304. textureIdBuffer->setData(textureIdData, 1);
  305. blockIndexBuffer->copyToGPU();
  306. textureIdBuffer->copyToGPU(sizeof(int) * textureIds.getEntryCount());
  307. delete[] textureIdData;
  308. ChunkShaderInfo info
  309. = {chunkCenter, (unsigned int)textureIds.getEntryCount()};
  310. chunkInfoBuffer->setData(&info, 1);
  311. chunkInfoBuffer->copyToGPU();
  312. changed = 0;
  313. }
  314. cs.unlock();
  315. }
  316. int DX12ChunkData::getLastObjectIndex() const
  317. {
  318. return lastObjectIndex;
  319. }
  320. int DX12ChunkData::getLastHitGroupIndex() const
  321. {
  322. return lastHitGroupIndex;
  323. }
  324. void DX12ChunkData::setLastObjectIndex(int index)
  325. {
  326. lastObjectIndex = index;
  327. }
  328. void DX12ChunkData::setLastHitGroupIndex(int index)
  329. {
  330. lastHitGroupIndex = index;
  331. }
  332. bool DX12ChunkData::wasBufferChanged() const
  333. {
  334. return bufferChanged;
  335. }
  336. void DX12ChunkData::setBufferChanged(bool changed)
  337. {
  338. bufferChanged = changed;
  339. }