DX12ChunkData.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. #include "Dx12ChunkData.h"
  2. #include <DX12BLASModel.h>
  3. #include <DX12CommandQueue.h>
  4. #include "d3dx12.h"
  5. #include "Dimension.h"
  6. #include "World.h"
  7. DX12ChunkData::DX12ChunkData(Framework::Point center)
  8. : ReferenceCounter(),
  9. aabbs(0),
  10. chunkInfoBuffer(0),
  11. blasScratchBuffer(0),
  12. customBlocksBlasScratchBuffer(0),
  13. oldBlasBuffer(0),
  14. blasBuffer(0),
  15. customBlocksBlasBuffer(0),
  16. blockIndexBuffer(0),
  17. textureIdBuffer(0),
  18. customBlockTextures(0),
  19. customBlocksCombinedIndexBuffer(0),
  20. customBlocksVertexDataBuffer(0),
  21. customBlocksIndexOffsetBuffer(0),
  22. customBlocksMatrixBuffer(0),
  23. customLightBuffer(0),
  24. customLightBufferSize(0),
  25. customBlocksLightBuffer(0),
  26. lastObjectIndex(-1),
  27. lastCustomObjectIndex(-1),
  28. lastHitGroupIndex(-1),
  29. lastCustomHitGroupIndex(-1),
  30. chunkCenter(center),
  31. blockIndices(new int[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT]),
  32. textureIds(),
  33. changed(0),
  34. bufferChanged(0),
  35. minZ(WORLD_HEIGHT),
  36. maxZ(0),
  37. minMaxChanged(0),
  38. customBufferChanged(0),
  39. customBlocksChanged(0),
  40. lightBufferSize(0),
  41. lightBuffer(0),
  42. dxLightBuffer(0)
  43. {
  44. memset(
  45. blockIndices, -1, sizeof(int) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
  46. }
  47. DX12ChunkData::~DX12ChunkData()
  48. {
  49. if (aabbs)
  50. {
  51. aabbs->release();
  52. }
  53. if (chunkInfoBuffer)
  54. {
  55. chunkInfoBuffer->release();
  56. }
  57. if (blasScratchBuffer)
  58. {
  59. blasScratchBuffer->release();
  60. }
  61. if (customBlocksBlasScratchBuffer)
  62. {
  63. customBlocksBlasScratchBuffer->release();
  64. }
  65. if (oldBlasBuffer)
  66. {
  67. oldBlasBuffer->Release();
  68. }
  69. if (blasBuffer)
  70. {
  71. blasBuffer->release();
  72. }
  73. if (customBlocksBlasBuffer)
  74. {
  75. customBlocksBlasBuffer->release();
  76. }
  77. if (blockIndexBuffer)
  78. {
  79. blockIndexBuffer->release();
  80. }
  81. if (textureIdBuffer)
  82. {
  83. textureIdBuffer->release();
  84. }
  85. if (customBlockTextures)
  86. {
  87. customBlockTextures->release();
  88. }
  89. if (customBlocksCombinedIndexBuffer)
  90. {
  91. customBlocksCombinedIndexBuffer->release();
  92. }
  93. if (customBlocksVertexDataBuffer)
  94. {
  95. customBlocksVertexDataBuffer->release();
  96. }
  97. if (customBlocksIndexOffsetBuffer)
  98. {
  99. customBlocksIndexOffsetBuffer->release();
  100. }
  101. if (customBlocksMatrixBuffer)
  102. {
  103. customBlocksMatrixBuffer->release();
  104. }
  105. if (customBlocksLightBuffer)
  106. {
  107. customBlocksLightBuffer->release();
  108. }
  109. if (dxLightBuffer)
  110. {
  111. dxLightBuffer->release();
  112. }
  113. delete[] lightBuffer;
  114. delete[] customLightBuffer;
  115. delete[] blockIndices;
  116. }
  117. Framework::DX12Buffer* DX12ChunkData::zChunkInfoBuffer() const
  118. {
  119. return chunkInfoBuffer;
  120. }
  121. Framework::DX12Buffer* DX12ChunkData::zBlasBuffer() const
  122. {
  123. return blasBuffer;
  124. }
  125. Framework::DX12Buffer* DX12ChunkData::zBlockIndexBuffer() const
  126. {
  127. return blockIndexBuffer;
  128. }
  129. Framework::DX12Buffer* DX12ChunkData::zTextureIdBuffer() const
  130. {
  131. return textureIdBuffer;
  132. }
  133. Framework::DX12Buffer* DX12ChunkData::zLightBuffer() const
  134. {
  135. return dxLightBuffer;
  136. }
  137. Framework::DX12Buffer* DX12ChunkData::zCustomBlocksBlasBuffer() const
  138. {
  139. return customBlocksBlasBuffer;
  140. }
  141. Framework::DX12Buffer* DX12ChunkData::zCustomBlocksTextureBuffer() const
  142. {
  143. return customBlockTextures;
  144. }
  145. Framework::DX12Buffer* DX12ChunkData::zCustomBlocksVertexDataBuffer() const
  146. {
  147. return customBlocksVertexDataBuffer;
  148. }
  149. Framework::DX12Buffer* DX12ChunkData::zCustomBlocksCombinedIndexBuffer() const
  150. {
  151. return customBlocksCombinedIndexBuffer;
  152. }
  153. Framework::DX12Buffer* DX12ChunkData::zCustomBlocksIndexOffsetBuffer() const
  154. {
  155. return customBlocksIndexOffsetBuffer;
  156. }
  157. Framework::DX12Buffer* DX12ChunkData::zCustomBlocksLightBuffer() const
  158. {
  159. return customBlocksLightBuffer;
  160. }
  161. void DX12ChunkData::setBlock(int index, Block* zBlock)
  162. {
  163. cs.lock();
  164. if (zBlock
  165. && zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube"))
  166. {
  167. if (blockIndices[index] < 0)
  168. {
  169. blockIndices[index] = textureIds.getEntryCount();
  170. for (int i = 0; i < 6; ++i)
  171. {
  172. textureIds.add(zBlock->zTexture()->zPolygonTexture(i)->getId());
  173. }
  174. }
  175. else
  176. {
  177. ArrayIterator<int> textureIt = textureIds.begin();
  178. int tmp = blockIndices[index];
  179. while (tmp > 0)
  180. {
  181. ++textureIt;
  182. --tmp;
  183. }
  184. for (int i = 0; i < 6; ++i)
  185. {
  186. textureIt.set(zBlock->zTexture()->zPolygonTexture(i)->getId());
  187. ++textureIt;
  188. }
  189. }
  190. if (zBlock->getLocation().z + 1 > maxZ)
  191. {
  192. maxZ = zBlock->getLocation().z + 1;
  193. minMaxChanged = 1;
  194. }
  195. if (zBlock->getLocation().z < minZ)
  196. {
  197. minZ = zBlock->getLocation().z;
  198. minMaxChanged = 1;
  199. }
  200. }
  201. else
  202. {
  203. if (blockIndices[index] >= 0)
  204. {
  205. int tmp = blockIndices[index];
  206. ArrayIterator<int> textureIt = textureIds.begin();
  207. while (tmp > 0)
  208. {
  209. ++textureIt;
  210. --tmp;
  211. }
  212. for (int i = 0; i < 6; ++i)
  213. {
  214. textureIt.remove();
  215. }
  216. int oldMinZ = minZ;
  217. int oldMaxZ = maxZ;
  218. maxZ = 0;
  219. minZ = WORLD_HEIGHT;
  220. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
  221. {
  222. if (blockIndices[i] > blockIndices[index])
  223. {
  224. blockIndices[i] -= 6;
  225. }
  226. if (blockIndices[i] >= 0)
  227. {
  228. if (i % WORLD_HEIGHT + 1 > maxZ)
  229. {
  230. maxZ = i % WORLD_HEIGHT + 1;
  231. }
  232. if (i % WORLD_HEIGHT < minZ)
  233. {
  234. minZ = i % WORLD_HEIGHT;
  235. }
  236. }
  237. }
  238. if (minZ != oldMinZ || maxZ != oldMaxZ)
  239. {
  240. minMaxChanged = 1;
  241. }
  242. }
  243. blockIndices[index] = -1;
  244. }
  245. if (zBlock
  246. && !zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube"))
  247. {
  248. auto iterator = customBlocks.begin();
  249. bool found = 0;
  250. while (iterator)
  251. {
  252. if (iterator->getLocation() == zBlock->getLocation())
  253. {
  254. iterator.set(dynamic_cast<Block*>(zBlock->getThis()));
  255. found = 1;
  256. break;
  257. }
  258. ++iterator;
  259. }
  260. if (!found)
  261. {
  262. customBlocks.add(dynamic_cast<Block*>(zBlock->getThis()));
  263. }
  264. customBlocksChanged = 1;
  265. }
  266. if (!zBlock
  267. || zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube"))
  268. {
  269. auto iterator = customBlocks.begin();
  270. while (iterator)
  271. {
  272. if (Chunk::index(
  273. Dimension::chunkCoordinates(iterator->getLocation()))
  274. == index)
  275. {
  276. iterator.remove();
  277. customBlocksChanged = 1;
  278. break;
  279. }
  280. ++iterator;
  281. }
  282. }
  283. changed = 1;
  284. cs.unlock();
  285. }
  286. void DX12ChunkData::updateLightning(Chunk* zChunk)
  287. {
  288. // simple blocks
  289. int neededSize = textureIds.getEntryCount() * 8;
  290. if (neededSize > lightBufferSize)
  291. {
  292. delete[] lightBuffer;
  293. lightBuffer = new unsigned char[neededSize];
  294. lightBufferSize = neededSize;
  295. if (dxLightBuffer)
  296. {
  297. dxLightBuffer->setData(lightBuffer, 1);
  298. dxLightBuffer->setLength(neededSize);
  299. }
  300. }
  301. Directions vertexDirections[8][3] = {
  302. {TOP, NORTH, EAST},
  303. {TOP, SOUTH, EAST},
  304. {TOP, SOUTH, WEST},
  305. {TOP, NORTH, WEST},
  306. {BOTTOM, NORTH, EAST},
  307. {BOTTOM, SOUTH, EAST},
  308. {BOTTOM, SOUTH, WEST},
  309. {BOTTOM, NORTH, WEST}
  310. };
  311. const unsigned char noLightData[6] = {0, 0, 0, 0, 0, 0};
  312. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
  313. {
  314. if (blockIndices[i] >= 0)
  315. {
  316. Vec3<int> blockLocation = Chunk::chunkCoordinates(i);
  317. Block* zBlock = zChunk->zBlockAt(blockLocation);
  318. union
  319. {
  320. const unsigned char* neighborLightMap[3][3][3];
  321. const unsigned char* neighborLightMapEntries[3 * 3 * 3];
  322. };
  323. for (int j = 0; j < 3 * 3 * 3; j++)
  324. {
  325. neighborLightMapEntries[j] = noLightData;
  326. }
  327. for (int x = -1; x <= 1; ++x)
  328. {
  329. for (int y = -1; y <= 1; ++y)
  330. {
  331. for (int z = -1; z <= 1; ++z)
  332. {
  333. Vec3<int> neighborLocation
  334. = blockLocation + Vec3<int>(x, y, z);
  335. if (neighborLocation.z >= 0
  336. && neighborLocation.z < WORLD_HEIGHT)
  337. {
  338. if (neighborLocation.x >= 0
  339. && neighborLocation.x < CHUNK_SIZE
  340. && neighborLocation.y >= 0
  341. && neighborLocation.y < CHUNK_SIZE)
  342. {
  343. Block* zNeighborBlock
  344. = zChunk->zBlockAt(neighborLocation);
  345. if (zNeighborBlock)
  346. {
  347. for (int d = 0; d < 6; d++)
  348. {
  349. Vec3<int> lmi
  350. = getDirection(
  351. getDirectionFromIndex(d))
  352. + Vec3<int>(x, y, z);
  353. if (lmi.x >= -1 && lmi.x <= 1
  354. && lmi.y >= -1 && lmi.y <= 1
  355. && lmi.z >= -1 && lmi.z <= 1)
  356. {
  357. neighborLightMap[lmi.x + 1]
  358. [lmi.y + 1]
  359. [lmi.z + 1]
  360. = zNeighborBlock->getLightData(
  361. getDirectionFromIndex(d));
  362. }
  363. }
  364. }
  365. }
  366. }
  367. }
  368. }
  369. }
  370. int offset = blockIndices[i] * 8;
  371. for (int j = 0; j < 8; ++j)
  372. {
  373. int lightData[6];
  374. memset(lightData, 0, sizeof(int) * 6);
  375. int count = 0;
  376. for (int d = 1; d < 8; d++)
  377. {
  378. Directions direction
  379. = vertexDirections[j][0] * ((d & 0x1) != 0)
  380. + vertexDirections[j][1] * ((d & 0x2) != 0)
  381. + vertexDirections[j][2] * ((d & 0x4) != 0);
  382. Vec3<int> index = getDirection(direction);
  383. bool notZero = 0;
  384. const unsigned char* currentLight
  385. = neighborLightMap[index.x + 1][index.y + 1]
  386. [index.z + 1];
  387. for (int k = 0; k < 6; ++k)
  388. {
  389. lightData[k] += (int)currentLight[k];
  390. notZero |= currentLight[k] > 0;
  391. }
  392. if (notZero)
  393. {
  394. ++count;
  395. }
  396. }
  397. for (int k = 0; k < 6; ++k)
  398. {
  399. lightBuffer[offset + j * 6 + k]
  400. = count > 0 ? (unsigned char)(lightData[k] / count) : 0;
  401. }
  402. }
  403. }
  404. }
  405. if (dxLightBuffer)
  406. {
  407. dxLightBuffer->setChanged();
  408. dxLightBuffer->copyToGPU();
  409. }
  410. // custom blocks
  411. neededSize = customBlocks.getEntryCount() * 6;
  412. if (neededSize >= customLightBufferSize)
  413. {
  414. delete[] customLightBuffer;
  415. customLightBuffer = new unsigned char[neededSize];
  416. customLightBufferSize = neededSize;
  417. if (customBlocksLightBuffer)
  418. {
  419. customBlocksLightBuffer->setData(customLightBuffer, 1);
  420. customBlocksLightBuffer->setLength(neededSize);
  421. }
  422. }
  423. int index = 0;
  424. for (const Block* zBlock : customBlocks)
  425. {
  426. int offset = index * 6;
  427. int lightData[6];
  428. memset(lightData, 0, sizeof(int) * 6);
  429. int count = 0;
  430. for (int d = 0; d < 6; ++d)
  431. {
  432. const unsigned char* currentLight
  433. = zBlock->getLightData(getDirectionFromIndex(d));
  434. bool notZero = 0;
  435. for (int i = 0; i < 6; ++i)
  436. {
  437. lightData[i] += (int)currentLight[i];
  438. notZero |= currentLight[i] > 0;
  439. }
  440. if (notZero)
  441. {
  442. ++count;
  443. }
  444. }
  445. for (int k = 0; k < 6; ++k)
  446. {
  447. customLightBuffer[offset + k]
  448. = count > 0 ? (unsigned char)(lightData[k] / count) : 0;
  449. }
  450. ++index;
  451. }
  452. if (customBlocksLightBuffer)
  453. {
  454. customBlocksLightBuffer->setChanged();
  455. customBlocksLightBuffer->copyToGPU();
  456. }
  457. }
  458. struct ModelIdMapping
  459. {
  460. int modelId;
  461. int vertexBufferOffset;
  462. int indexBufferOffset;
  463. };
  464. void DX12ChunkData::updateBuffers(
  465. ID3D12Device5* zDevice, Framework::DX12CommandQueue* zQueue)
  466. {
  467. cs.lock();
  468. if (!aabbs)
  469. {
  470. aabbs = new DX12Buffer(sizeof(D3D12_RAYTRACING_AABB),
  471. zDevice,
  472. dynamic_cast<Framework::DX12CommandQueue*>(zQueue->getThis()),
  473. D3D12_RESOURCE_FLAG_NONE);
  474. aabbs->setLength(sizeof(D3D12_RAYTRACING_AABB));
  475. D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f,
  476. chunkCenter.y - 8.f,
  477. (float)minZ,
  478. chunkCenter.x + 8.f,
  479. chunkCenter.y + 8.f,
  480. (float)maxZ};
  481. aabbs->setData(&data, 1);
  482. aabbs->copyToGPU();
  483. minMaxChanged = 0;
  484. }
  485. if (minMaxChanged)
  486. {
  487. D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f,
  488. chunkCenter.y - 8.f,
  489. (float)minZ,
  490. chunkCenter.x + 8.f,
  491. chunkCenter.y + 8.f,
  492. (float)maxZ};
  493. aabbs->setData(&data, 1);
  494. aabbs->copyToGPU();
  495. minMaxChanged = 0;
  496. }
  497. if (!blasBuffer || minMaxChanged)
  498. {
  499. D3D12_RAYTRACING_GEOMETRY_DESC geometryDesc = {};
  500. geometryDesc.Type
  501. = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
  502. geometryDesc.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
  503. geometryDesc.AABBs.AABBCount = 1;
  504. geometryDesc.AABBs.AABBs.StartAddress
  505. = aabbs->zBuffer()->GetGPUVirtualAddress();
  506. geometryDesc.AABBs.AABBs.StrideInBytes = sizeof(D3D12_RAYTRACING_AABB);
  507. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc;
  508. prebuildDesc.Type
  509. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  510. prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  511. prebuildDesc.NumDescs = 1;
  512. prebuildDesc.pGeometryDescs = &geometryDesc;
  513. prebuildDesc.Flags
  514. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
  515. D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {};
  516. zDevice->GetRaytracingAccelerationStructurePrebuildInfo(
  517. &prebuildDesc, &info);
  518. if (oldBlasBuffer)
  519. {
  520. oldBlasBuffer->Release();
  521. oldBlasBuffer = 0;
  522. }
  523. if (blasBuffer)
  524. {
  525. oldBlasBuffer = blasBuffer->zBuffer();
  526. oldBlasBuffer->AddRef();
  527. blasBuffer->release();
  528. }
  529. blasBuffer = new DX12Buffer(1,
  530. zDevice,
  531. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  532. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  533. blasBuffer->setLength(
  534. ROUND_UP_POWER_OF_2(info.ResultDataMaxSizeInBytes, 256));
  535. blasBuffer->createBufferWithoutData(
  536. D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
  537. blasScratchBuffer = new DX12Buffer(1,
  538. zDevice,
  539. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  540. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  541. blasScratchBuffer->setLength(
  542. ROUND_UP_POWER_OF_2(info.ScratchDataSizeInBytes, 256));
  543. blasScratchBuffer->createBufferWithoutData(D3D12_RESOURCE_STATE_COMMON);
  544. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc;
  545. buildDesc.Inputs.Type
  546. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  547. buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  548. buildDesc.Inputs.NumDescs = 1;
  549. buildDesc.Inputs.pGeometryDescs = &geometryDesc;
  550. buildDesc.DestAccelerationStructureData
  551. = {blasBuffer->zBuffer()->GetGPUVirtualAddress()};
  552. buildDesc.ScratchAccelerationStructureData
  553. = {blasScratchBuffer->zBuffer()->GetGPUVirtualAddress()};
  554. buildDesc.SourceAccelerationStructureData
  555. = oldBlasBuffer ? oldBlasBuffer->GetGPUVirtualAddress() : 0;
  556. buildDesc.Inputs.Flags
  557. = oldBlasBuffer
  558. ? D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE
  559. : D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
  560. zQueue->zCommandList()->BuildRaytracingAccelerationStructure(
  561. &buildDesc, 0, nullptr);
  562. bufferChanged = 1;
  563. }
  564. if (!blockIndexBuffer)
  565. {
  566. blockIndexBuffer = new DX12Buffer(sizeof(int),
  567. zDevice,
  568. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  569. D3D12_RESOURCE_FLAG_NONE);
  570. blockIndexBuffer->setLength(
  571. sizeof(int) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
  572. bufferChanged = 1;
  573. }
  574. if (textureIdBuffer
  575. && textureIdBuffer->getElementCount() < textureIds.getEntryCount())
  576. {
  577. textureIdBuffer->release();
  578. textureIdBuffer = 0;
  579. }
  580. if (!textureIdBuffer)
  581. {
  582. textureIdBuffer = new DX12Buffer(sizeof(int),
  583. zDevice,
  584. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  585. D3D12_RESOURCE_FLAG_NONE);
  586. textureIdBuffer->setLength(textureIds.getEntryCount() * sizeof(int));
  587. bufferChanged = 1;
  588. }
  589. if (!chunkInfoBuffer)
  590. {
  591. chunkInfoBuffer = new DX12Buffer(sizeof(ChunkShaderInfo),
  592. zDevice,
  593. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  594. D3D12_RESOURCE_FLAG_NONE);
  595. chunkInfoBuffer->setLength(sizeof(ChunkShaderInfo));
  596. }
  597. if (customBlocksChanged)
  598. {
  599. int* cbts = new int[customBlocks.getEntryCount()];
  600. int index = 0;
  601. D3D12_RAYTRACING_GEOMETRY_DESC* simpleBlockDescs
  602. = new D3D12_RAYTRACING_GEOMETRY_DESC[customBlocks.getEntryCount()];
  603. int* indexOffsets = new int[customBlocks.getEntryCount()];
  604. int vertexCount = 0;
  605. int indexCount = 0;
  606. Array<ModelIdMapping> idMapping;
  607. for (Block* block : customBlocks)
  608. {
  609. int id = block->zModelData()->getId();
  610. bool found = 0;
  611. for (const ModelIdMapping& m : idMapping)
  612. {
  613. if (m.modelId == id)
  614. {
  615. found = 1;
  616. break;
  617. }
  618. }
  619. if (!found)
  620. {
  621. ModelIdMapping mapping;
  622. mapping.modelId = id;
  623. mapping.vertexBufferOffset = vertexCount;
  624. mapping.indexBufferOffset = indexCount;
  625. idMapping.add(mapping);
  626. vertexCount += block->zModelData()->getVertexCount();
  627. indexCount += block->zModelData()->getIndexCount();
  628. }
  629. }
  630. int* combinedIndexBuffer = new int[indexCount];
  631. Framework::DX2VertexData* vertexDataBuffer
  632. = new Framework::DX2VertexData[vertexCount];
  633. int vdIndex = 0;
  634. Array<int> modelBuild;
  635. float* matrixDataBuffer = new float[customBlocks.getEntryCount() * 12];
  636. int blockIndex = 0;
  637. for (Block* block : customBlocks)
  638. {
  639. Mat4<float> transform
  640. = Mat4<float>::translation(
  641. (Vec3<float>)Dimension::chunkCoordinates(
  642. block->getLocation())
  643. + Vec3<float>(
  644. 0.5f - CHUNK_SIZE / 2, 0.5f - CHUNK_SIZE / 2, 0.5f))
  645. * Mat4<float>::rotationZ(block->getZRotation())
  646. * Mat4<float>::rotationX(block->getXRotation())
  647. * Mat4<float>::rotationY(block->getYRotation())
  648. * Mat4<float>::scaling(block->getSize());
  649. memcpy(matrixDataBuffer + 12 * blockIndex,
  650. &transform,
  651. 12 * sizeof(float));
  652. ++blockIndex;
  653. }
  654. if (!customBlocksMatrixBuffer)
  655. {
  656. customBlocksMatrixBuffer = new DX12Buffer(sizeof(float) * 12,
  657. zDevice,
  658. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  659. D3D12_RESOURCE_FLAG_NONE);
  660. }
  661. customBlocksMatrixBuffer->setLength(
  662. sizeof(float) * 12 * customBlocks.getEntryCount());
  663. customBlocksMatrixBuffer->setData(matrixDataBuffer, 1);
  664. customBlocksMatrixBuffer->copyToGPU();
  665. CD3DX12_RESOURCE_BARRIER transition
  666. = CD3DX12_RESOURCE_BARRIER::Transition(
  667. customBlocksMatrixBuffer->zBuffer(),
  668. D3D12_RESOURCE_STATE_COMMON,
  669. D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
  670. zQueue->zCommandList()->ResourceBarrier(1, &transition);
  671. for (Block* block : customBlocks)
  672. {
  673. int id = block->zModelData()->getId();
  674. ModelIdMapping mapping;
  675. int mappingIndex = 0;
  676. for (const ModelIdMapping& m : idMapping)
  677. {
  678. if (m.modelId == id)
  679. {
  680. mapping = m;
  681. break;
  682. }
  683. ++mappingIndex;
  684. }
  685. if (modelBuild.getValueIndex(id) < 0)
  686. {
  687. modelBuild.add(id);
  688. while (vertexBuffers.getEntryCount() <= mappingIndex)
  689. {
  690. DX12Buffer* vBuffer = new DX12Buffer(sizeof(Vec3<float>),
  691. zDevice,
  692. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  693. D3D12_RESOURCE_FLAG_NONE);
  694. vertexBuffers.add(vBuffer);
  695. }
  696. while (indexBuffers.getEntryCount() <= mappingIndex)
  697. {
  698. DX12Buffer* iBuffer = new DX12Buffer(sizeof(int),
  699. zDevice,
  700. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  701. D3D12_RESOURCE_FLAG_NONE);
  702. indexBuffers.add(iBuffer);
  703. }
  704. DX12Buffer* vBuffer = vertexBuffers.z(mappingIndex);
  705. Vec3<float>* vertexBuffer
  706. = new Vec3<float>[block->zModelData()->getVertexCount()];
  707. const Vertex3D* rawVertexData
  708. = block->zModelData()->zVertexBuffer();
  709. for (int i = 0; i < block->zModelData()->getVertexCount(); ++i)
  710. {
  711. vertexBuffer[i] = rawVertexData[i].pos;
  712. vertexDataBuffer[mapping.vertexBufferOffset + i]
  713. = {rawVertexData[i].tPos, rawVertexData[i].normal};
  714. }
  715. const int* rawIndexBuffer
  716. = block->zModelData()->getIndexBuffer();
  717. for (int i = 0; i < block->zModelData()->getIndexCount(); i++)
  718. {
  719. combinedIndexBuffer[mapping.indexBufferOffset + i]
  720. = rawIndexBuffer[i] + mapping.vertexBufferOffset;
  721. }
  722. vBuffer->setLength(sizeof(Vec3<float>)
  723. * block->zModelData()->getVertexCount());
  724. vBuffer->setData(vertexBuffer, 1);
  725. vBuffer->copyToGPU();
  726. delete[] vertexBuffer;
  727. DX12Buffer* iBuffer = indexBuffers.z(mappingIndex);
  728. iBuffer->setLength(
  729. sizeof(int) * block->zModelData()->getIndexCount());
  730. iBuffer->setData((void*)rawIndexBuffer, 1);
  731. iBuffer->copyToGPU();
  732. }
  733. DX12Buffer* vBuffer = vertexBuffers.z(mappingIndex);
  734. DX12Buffer* iBuffer = indexBuffers.z(mappingIndex);
  735. simpleBlockDescs[index].Type
  736. = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
  737. simpleBlockDescs[index].Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
  738. simpleBlockDescs[index].Triangles.VertexBuffer.StartAddress
  739. = vBuffer->zBuffer()->GetGPUVirtualAddress();
  740. simpleBlockDescs[index].Triangles.VertexBuffer.StrideInBytes
  741. = vBuffer->getElementLength();
  742. simpleBlockDescs[index].Triangles.VertexFormat
  743. = DXGI_FORMAT_R32G32B32_FLOAT;
  744. simpleBlockDescs[index].Triangles.VertexCount
  745. = (unsigned)vBuffer->getElementCount();
  746. simpleBlockDescs[index].Triangles.IndexBuffer
  747. = iBuffer->zBuffer()->GetGPUVirtualAddress();
  748. simpleBlockDescs[index].Triangles.IndexFormat
  749. = DXGI_FORMAT_R32_UINT;
  750. simpleBlockDescs[index].Triangles.IndexCount
  751. = (unsigned)iBuffer->getElementCount();
  752. simpleBlockDescs[index].Triangles.Transform3x4
  753. = customBlocksMatrixBuffer->zBuffer()->GetGPUVirtualAddress()
  754. + 12 * index * sizeof(float);
  755. cbts[index] = block->zTexture()->zPolygonTexture(0)->getId();
  756. indexOffsets[index] = mapping.indexBufferOffset;
  757. ++index;
  758. }
  759. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc;
  760. prebuildDesc.Type
  761. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  762. prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  763. prebuildDesc.NumDescs = customBlocks.getEntryCount();
  764. prebuildDesc.pGeometryDescs = simpleBlockDescs;
  765. prebuildDesc.Flags
  766. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
  767. D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {};
  768. zDevice->GetRaytracingAccelerationStructurePrebuildInfo(
  769. &prebuildDesc, &info);
  770. if (!customBlocksBlasScratchBuffer)
  771. {
  772. customBlocksBlasScratchBuffer = new DX12Buffer(1,
  773. zDevice,
  774. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  775. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  776. }
  777. if (!customBlocksBlasBuffer)
  778. {
  779. customBlocksBlasBuffer = new DX12Buffer(1,
  780. zDevice,
  781. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  782. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  783. }
  784. customBlocksBlasScratchBuffer->setLength(
  785. ROUND_UP_POWER_OF_2((int)info.ScratchDataSizeInBytes, 256));
  786. customBlocksBlasScratchBuffer->createBufferWithoutData(
  787. D3D12_RESOURCE_STATE_COMMON);
  788. customBlocksBlasBuffer->setLength(
  789. ROUND_UP_POWER_OF_2((int)info.ResultDataMaxSizeInBytes, 256));
  790. customBlocksBlasBuffer->createBufferWithoutData(
  791. D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
  792. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc;
  793. buildDesc.Inputs.Type
  794. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  795. buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  796. buildDesc.Inputs.NumDescs = customBlocks.getEntryCount();
  797. buildDesc.Inputs.pGeometryDescs = simpleBlockDescs;
  798. buildDesc.DestAccelerationStructureData
  799. = {customBlocksBlasBuffer->zBuffer()->GetGPUVirtualAddress()};
  800. buildDesc.ScratchAccelerationStructureData = {
  801. customBlocksBlasScratchBuffer->zBuffer()->GetGPUVirtualAddress()};
  802. buildDesc.SourceAccelerationStructureData = 0;
  803. buildDesc.Inputs.Flags
  804. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
  805. zQueue->zCommandList()->BuildRaytracingAccelerationStructure(
  806. &buildDesc, 0, nullptr);
  807. if (!customBlockTextures)
  808. {
  809. customBlockTextures = new DX12Buffer(sizeof(int),
  810. zDevice,
  811. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  812. D3D12_RESOURCE_FLAG_NONE);
  813. }
  814. customBlockTextures->setLength(
  815. sizeof(int) * customBlocks.getEntryCount());
  816. customBlockTextures->setData(cbts, 1);
  817. customBlockTextures->copyToGPU();
  818. if (!customBlocksIndexOffsetBuffer)
  819. {
  820. customBlocksIndexOffsetBuffer = new DX12Buffer(sizeof(int),
  821. zDevice,
  822. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  823. D3D12_RESOURCE_FLAG_NONE);
  824. }
  825. customBlocksIndexOffsetBuffer->setLength(
  826. sizeof(int) * customBlocks.getEntryCount());
  827. customBlocksIndexOffsetBuffer->setData(indexOffsets, 1);
  828. customBlocksIndexOffsetBuffer->copyToGPU();
  829. if (!customBlocksVertexDataBuffer)
  830. {
  831. customBlocksVertexDataBuffer
  832. = new DX12Buffer(sizeof(Framework::DX2VertexData),
  833. zDevice,
  834. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  835. D3D12_RESOURCE_FLAG_NONE);
  836. }
  837. customBlocksVertexDataBuffer->setLength(
  838. sizeof(Framework::DX2VertexData) * vertexCount);
  839. customBlocksVertexDataBuffer->setData(vertexDataBuffer, 1);
  840. customBlocksVertexDataBuffer->copyToGPU();
  841. if (!customBlocksCombinedIndexBuffer)
  842. {
  843. customBlocksCombinedIndexBuffer = new DX12Buffer(sizeof(int),
  844. zDevice,
  845. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  846. D3D12_RESOURCE_FLAG_NONE);
  847. }
  848. customBlocksCombinedIndexBuffer->setLength(sizeof(int) * indexCount);
  849. customBlocksCombinedIndexBuffer->setData(combinedIndexBuffer, 1);
  850. customBlocksCombinedIndexBuffer->copyToGPU();
  851. delete[] cbts;
  852. delete[] simpleBlockDescs;
  853. delete[] vertexDataBuffer;
  854. delete[] indexOffsets;
  855. delete[] combinedIndexBuffer;
  856. customBlocksChanged = 0;
  857. customBufferChanged = 1;
  858. }
  859. if (changed)
  860. {
  861. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
  862. {
  863. assert(blockIndices[i] < 0
  864. || blockIndices[i] <= textureIds.getEntryCount() - 6);
  865. }
  866. int* textureIdData = new int[textureIds.getEntryCount()];
  867. ArrayIterator<int> textureIt = textureIds.begin();
  868. int index = 0;
  869. while (textureIt)
  870. {
  871. textureIdData[index++] = textureIt.val();
  872. ++textureIt;
  873. }
  874. blockIndexBuffer->setData(blockIndices, 1);
  875. textureIdBuffer->setData(textureIdData, 1);
  876. blockIndexBuffer->copyToGPU();
  877. textureIdBuffer->copyToGPU(sizeof(int) * textureIds.getEntryCount());
  878. delete[] textureIdData;
  879. ChunkShaderInfo info
  880. = {chunkCenter, (unsigned int)textureIds.getEntryCount()};
  881. chunkInfoBuffer->setData(&info, 1);
  882. chunkInfoBuffer->copyToGPU();
  883. changed = 0;
  884. }
  885. if (!dxLightBuffer)
  886. {
  887. dxLightBuffer = new DX12Buffer(sizeof(unsigned char),
  888. zDevice,
  889. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  890. D3D12_RESOURCE_FLAG_NONE);
  891. if (!lightBuffer)
  892. {
  893. int neededSize
  894. = max(textureIds.getEntryCount() * 8, 6 * 8 * 16 * 16 * 2);
  895. lightBuffer = new unsigned char[neededSize];
  896. lightBufferSize = neededSize;
  897. memset(lightBuffer, 0, lightBufferSize);
  898. }
  899. dxLightBuffer->setData(lightBuffer, 1);
  900. dxLightBuffer->setLength(lightBufferSize);
  901. dxLightBuffer->copyToGPU();
  902. }
  903. if (!customBlocksLightBuffer)
  904. {
  905. customBlocksLightBuffer = new DX12Buffer(sizeof(unsigned char),
  906. zDevice,
  907. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  908. D3D12_RESOURCE_FLAG_NONE);
  909. if (!customLightBuffer)
  910. {
  911. int neededSize = max(customBlocks.getEntryCount() * 6, 6);
  912. customLightBuffer = new unsigned char[neededSize];
  913. customLightBufferSize = neededSize;
  914. memset(customLightBuffer, 0, customLightBufferSize);
  915. }
  916. customBlocksLightBuffer->setData(customLightBuffer, 1);
  917. customBlocksLightBuffer->setLength(customLightBufferSize);
  918. customBlocksLightBuffer->copyToGPU();
  919. }
  920. cs.unlock();
  921. }
  922. int DX12ChunkData::getLastObjectIndex() const
  923. {
  924. return lastObjectIndex;
  925. }
  926. int DX12ChunkData::getLastCustomObjectIndex() const
  927. {
  928. return lastCustomObjectIndex;
  929. }
  930. int DX12ChunkData::getLastHitGroupIndex() const
  931. {
  932. return lastHitGroupIndex;
  933. }
  934. int DX12ChunkData::getLastCustomHitGroupIndex() const
  935. {
  936. return lastCustomHitGroupIndex;
  937. }
  938. void DX12ChunkData::setLastObjectIndex(int index)
  939. {
  940. lastObjectIndex = index;
  941. }
  942. void DX12ChunkData::setLastCustomObjectIndex(int index)
  943. {
  944. lastCustomObjectIndex = index;
  945. }
  946. void DX12ChunkData::setLastHitGroupIndex(int index)
  947. {
  948. lastHitGroupIndex = index;
  949. }
  950. void DX12ChunkData::setLastCustomHitGroupIndex(int index)
  951. {
  952. lastCustomHitGroupIndex = index;
  953. }
  954. bool DX12ChunkData::wasBufferChanged() const
  955. {
  956. return bufferChanged;
  957. }
  958. void DX12ChunkData::setBufferChanged(bool changed)
  959. {
  960. bufferChanged = changed;
  961. }
  962. bool DX12ChunkData::isSimpleBlock(Block* zBlock) const
  963. {
  964. return zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube")
  965. || ((!zBlock->zModelData()->zSkeleton()
  966. || zBlock->zModelData()->zSkeleton()->getNextBoneId() <= 1)
  967. && zBlock->zModelData()->getPolygonCount() == 1);
  968. }
  969. bool DX12ChunkData::hasCustomBlocks() const
  970. {
  971. return customBlocks.getEntryCount() > 0;
  972. }
  973. bool DX12ChunkData::wasCustomBufferChanged() const
  974. {
  975. return customBufferChanged;
  976. }
  977. void DX12ChunkData::setCustomBufferChanged(bool changed)
  978. {
  979. customBufferChanged = changed;
  980. }