DX12ChunkData.cpp 32 KB

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