DX12ChunkData.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  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[] = {TOP | NORTH | EAST,
  289. TOP | SOUTH | EAST,
  290. TOP | SOUTH | WEST,
  291. TOP | NORTH | WEST,
  292. BOTTOM | NORTH | EAST,
  293. BOTTOM | SOUTH | EAST,
  294. BOTTOM | SOUTH | WEST,
  295. BOTTOM | NORTH | WEST};
  296. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
  297. {
  298. if (blockIndices[i] >= 0)
  299. {
  300. Vec3<int> blockLocation = Chunk::chunkCoordinates(i);
  301. Block* zBlock = zChunk->zBlockAt(blockLocation);
  302. int offset = blockIndices[i] * 8;
  303. for (int j = 0; j < 8; ++j)
  304. {
  305. Directions dir = vertexDirections[j];
  306. int lightData[6];
  307. memset(lightData, 0, sizeof(int) * 6);
  308. int count = 0;
  309. for (int d = 0; d < 6; d++)
  310. {
  311. Direction direction = getDirectionFromIndex(d);
  312. if ((dir | direction) == dir)
  313. {
  314. Vec3<int> neighborLocation
  315. = blockLocation + getDirection(direction);
  316. if (neighborLocation.z >= 0
  317. && neighborLocation.z < WORLD_HEIGHT)
  318. {
  319. if (neighborLocation.x >= 0
  320. && neighborLocation.x < CHUNK_SIZE
  321. && neighborLocation.y >= 0
  322. && neighborLocation.y < CHUNK_SIZE)
  323. {
  324. int index = Chunk::index(neighborLocation);
  325. if (blockIndices[index] < 0)
  326. {
  327. for (int k = 0; k < 6; ++k)
  328. {
  329. lightData[k]
  330. += (int)zBlock->getLightData(
  331. direction)[k];
  332. }
  333. ++count;
  334. }
  335. }
  336. else
  337. {
  338. if (!World::INSTANCE->zBlockAt(
  339. neighborLocation
  340. + Vec3<int>(zChunk->getCenter().x
  341. - CHUNK_SIZE / 2,
  342. zChunk->getCenter().y
  343. - CHUNK_SIZE / 2,
  344. 0)))
  345. {
  346. for (int k = 0; k < 6; ++k)
  347. {
  348. lightData[k]
  349. += (int)zBlock->getLightData(
  350. direction)[k];
  351. }
  352. ++count;
  353. }
  354. }
  355. }
  356. }
  357. }
  358. for (int k = 0; k < 6; ++k)
  359. {
  360. lightBuffer[offset + j * 6 + k]
  361. = count > 0 ? (unsigned char)(lightData[k] / count) : 0;
  362. }
  363. }
  364. }
  365. }
  366. if (dxLightBuffer)
  367. {
  368. dxLightBuffer->setChanged();
  369. dxLightBuffer->copyToGPU();
  370. }
  371. }
  372. struct ModelIdMapping
  373. {
  374. int modelId;
  375. int vertexBufferOffset;
  376. int indexBufferOffset;
  377. };
  378. void DX12ChunkData::updateBuffers(
  379. ID3D12Device5* zDevice, Framework::DX12CommandQueue* zQueue)
  380. {
  381. cs.lock();
  382. if (!aabbs)
  383. {
  384. aabbs = new DX12Buffer(sizeof(D3D12_RAYTRACING_AABB),
  385. zDevice,
  386. dynamic_cast<Framework::DX12CommandQueue*>(zQueue->getThis()),
  387. D3D12_RESOURCE_FLAG_NONE);
  388. aabbs->setLength(sizeof(D3D12_RAYTRACING_AABB));
  389. D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f,
  390. chunkCenter.y - 8.f,
  391. (float)minZ,
  392. chunkCenter.x + 8.f,
  393. chunkCenter.y + 8.f,
  394. (float)maxZ};
  395. aabbs->setData(&data, 1);
  396. aabbs->copyToGPU();
  397. minMaxChanged = 0;
  398. }
  399. if (minMaxChanged)
  400. {
  401. D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f,
  402. chunkCenter.y - 8.f,
  403. (float)minZ,
  404. chunkCenter.x + 8.f,
  405. chunkCenter.y + 8.f,
  406. (float)maxZ};
  407. aabbs->setData(&data, 1);
  408. aabbs->copyToGPU();
  409. minMaxChanged = 0;
  410. }
  411. if (!blasBuffer || minMaxChanged)
  412. {
  413. D3D12_RAYTRACING_GEOMETRY_DESC geometryDesc = {};
  414. geometryDesc.Type
  415. = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
  416. geometryDesc.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
  417. geometryDesc.AABBs.AABBCount = 1;
  418. geometryDesc.AABBs.AABBs.StartAddress
  419. = aabbs->zBuffer()->GetGPUVirtualAddress();
  420. geometryDesc.AABBs.AABBs.StrideInBytes = sizeof(D3D12_RAYTRACING_AABB);
  421. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc;
  422. prebuildDesc.Type
  423. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  424. prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  425. prebuildDesc.NumDescs = 1;
  426. prebuildDesc.pGeometryDescs = &geometryDesc;
  427. prebuildDesc.Flags
  428. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
  429. D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {};
  430. zDevice->GetRaytracingAccelerationStructurePrebuildInfo(
  431. &prebuildDesc, &info);
  432. if (oldBlasBuffer)
  433. {
  434. oldBlasBuffer->Release();
  435. oldBlasBuffer = 0;
  436. }
  437. if (blasBuffer)
  438. {
  439. oldBlasBuffer = blasBuffer->zBuffer();
  440. oldBlasBuffer->AddRef();
  441. blasBuffer->release();
  442. }
  443. blasBuffer = new DX12Buffer(1,
  444. zDevice,
  445. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  446. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  447. blasBuffer->setLength(
  448. ROUND_UP_POWER_OF_2(info.ResultDataMaxSizeInBytes, 256));
  449. blasBuffer->createBufferWithoutData(
  450. D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
  451. blasScratchBuffer = new DX12Buffer(1,
  452. zDevice,
  453. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  454. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  455. blasScratchBuffer->setLength(
  456. ROUND_UP_POWER_OF_2(info.ScratchDataSizeInBytes, 256));
  457. blasScratchBuffer->createBufferWithoutData(D3D12_RESOURCE_STATE_COMMON);
  458. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc;
  459. buildDesc.Inputs.Type
  460. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  461. buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  462. buildDesc.Inputs.NumDescs = 1;
  463. buildDesc.Inputs.pGeometryDescs = &geometryDesc;
  464. buildDesc.DestAccelerationStructureData
  465. = {blasBuffer->zBuffer()->GetGPUVirtualAddress()};
  466. buildDesc.ScratchAccelerationStructureData
  467. = {blasScratchBuffer->zBuffer()->GetGPUVirtualAddress()};
  468. buildDesc.SourceAccelerationStructureData
  469. = oldBlasBuffer ? oldBlasBuffer->GetGPUVirtualAddress() : 0;
  470. buildDesc.Inputs.Flags
  471. = oldBlasBuffer
  472. ? D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE
  473. : D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
  474. zQueue->zCommandList()->BuildRaytracingAccelerationStructure(
  475. &buildDesc, 0, nullptr);
  476. bufferChanged = 1;
  477. }
  478. if (!blockIndexBuffer)
  479. {
  480. blockIndexBuffer = new DX12Buffer(sizeof(int),
  481. zDevice,
  482. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  483. D3D12_RESOURCE_FLAG_NONE);
  484. blockIndexBuffer->setLength(
  485. sizeof(int) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
  486. bufferChanged = 1;
  487. }
  488. if (textureIdBuffer
  489. && textureIdBuffer->getElementCount() < textureIds.getEntryCount())
  490. {
  491. textureIdBuffer->release();
  492. textureIdBuffer = 0;
  493. }
  494. if (!textureIdBuffer)
  495. {
  496. textureIdBuffer = new DX12Buffer(sizeof(int),
  497. zDevice,
  498. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  499. D3D12_RESOURCE_FLAG_NONE);
  500. textureIdBuffer->setLength(textureIds.getEntryCount() * sizeof(int));
  501. bufferChanged = 1;
  502. }
  503. if (!chunkInfoBuffer)
  504. {
  505. chunkInfoBuffer = new DX12Buffer(sizeof(ChunkShaderInfo),
  506. zDevice,
  507. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  508. D3D12_RESOURCE_FLAG_NONE);
  509. chunkInfoBuffer->setLength(sizeof(ChunkShaderInfo));
  510. }
  511. if (customBlocksChanged)
  512. {
  513. int* cbts = new int[customBlocks.getEntryCount()];
  514. int index = 0;
  515. D3D12_RAYTRACING_GEOMETRY_DESC* simpleBlockDescs
  516. = new D3D12_RAYTRACING_GEOMETRY_DESC[customBlocks.getEntryCount()];
  517. int* indexOffsets = new int[customBlocks.getEntryCount()];
  518. int vertexCount = 0;
  519. int indexCount = 0;
  520. Array<ModelIdMapping> idMapping;
  521. for (Block* block : customBlocks)
  522. {
  523. int id = block->zModelData()->getId();
  524. bool found = 0;
  525. for (const ModelIdMapping& m : idMapping)
  526. {
  527. if (m.modelId == id)
  528. {
  529. found = 1;
  530. break;
  531. }
  532. }
  533. if (!found)
  534. {
  535. ModelIdMapping mapping;
  536. mapping.modelId = id;
  537. mapping.vertexBufferOffset = vertexCount;
  538. mapping.indexBufferOffset = indexCount;
  539. idMapping.add(mapping);
  540. vertexCount += block->zModelData()->getVertexCount();
  541. indexCount += block->zModelData()->getIndexCount();
  542. }
  543. }
  544. int* combinedIndexBuffer = new int[indexCount];
  545. Framework::DX2VertexData* vertexDataBuffer
  546. = new Framework::DX2VertexData[vertexCount];
  547. int vdIndex = 0;
  548. Array<int> modelBuild;
  549. float* matrixDataBuffer = new float[customBlocks.getEntryCount() * 12];
  550. int blockIndex = 0;
  551. for (Block* block : customBlocks)
  552. {
  553. Mat4<float> transform
  554. = Mat4<float>::translation(
  555. (Vec3<float>)Dimension::chunkCoordinates(
  556. block->getLocation())
  557. + Vec3<float>(
  558. 0.5f - CHUNK_SIZE / 2, 0.5f - CHUNK_SIZE / 2, 0.5f))
  559. * Mat4<float>::rotationZ(block->getZRotation())
  560. * Mat4<float>::rotationX(block->getXRotation())
  561. * Mat4<float>::rotationY(block->getYRotation())
  562. * Mat4<float>::scaling(block->getSize());
  563. memcpy(matrixDataBuffer + 12 * blockIndex,
  564. &transform,
  565. 12 * sizeof(float));
  566. ++blockIndex;
  567. }
  568. if (!customBlockMatrixBuffer)
  569. {
  570. customBlockMatrixBuffer = new DX12Buffer(sizeof(float) * 12,
  571. zDevice,
  572. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  573. D3D12_RESOURCE_FLAG_NONE);
  574. }
  575. customBlockMatrixBuffer->setLength(
  576. sizeof(float) * 12 * customBlocks.getEntryCount());
  577. customBlockMatrixBuffer->setData(matrixDataBuffer, 1);
  578. customBlockMatrixBuffer->copyToGPU();
  579. CD3DX12_RESOURCE_BARRIER transition
  580. = CD3DX12_RESOURCE_BARRIER::Transition(
  581. customBlockMatrixBuffer->zBuffer(),
  582. D3D12_RESOURCE_STATE_COMMON,
  583. D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
  584. zQueue->zCommandList()->ResourceBarrier(1, &transition);
  585. for (Block* block : customBlocks)
  586. {
  587. int id = block->zModelData()->getId();
  588. ModelIdMapping mapping;
  589. int mappingIndex = 0;
  590. for (const ModelIdMapping& m : idMapping)
  591. {
  592. if (m.modelId == id)
  593. {
  594. mapping = m;
  595. break;
  596. }
  597. ++mappingIndex;
  598. }
  599. if (modelBuild.getValueIndex(id) < 0)
  600. {
  601. modelBuild.add(id);
  602. while (vertexBuffers.getEntryCount() <= mappingIndex)
  603. {
  604. DX12Buffer* vBuffer = new DX12Buffer(sizeof(Vec3<float>),
  605. zDevice,
  606. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  607. D3D12_RESOURCE_FLAG_NONE);
  608. vertexBuffers.add(vBuffer);
  609. }
  610. while (indexBuffers.getEntryCount() <= mappingIndex)
  611. {
  612. DX12Buffer* iBuffer = new DX12Buffer(sizeof(int),
  613. zDevice,
  614. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  615. D3D12_RESOURCE_FLAG_NONE);
  616. indexBuffers.add(iBuffer);
  617. }
  618. DX12Buffer* vBuffer = vertexBuffers.z(mappingIndex);
  619. Vec3<float>* vertexBuffer
  620. = new Vec3<float>[block->zModelData()->getVertexCount()];
  621. const Vertex3D* rawVertexData
  622. = block->zModelData()->zVertexBuffer();
  623. for (int i = 0; i < block->zModelData()->getVertexCount(); ++i)
  624. {
  625. vertexBuffer[i] = rawVertexData[i].pos;
  626. vertexDataBuffer[mapping.vertexBufferOffset + i]
  627. = {rawVertexData[i].tPos, rawVertexData[i].normal};
  628. }
  629. const int* rawIndexBuffer
  630. = block->zModelData()->getIndexBuffer();
  631. for (int i = 0; i < block->zModelData()->getIndexCount(); i++)
  632. {
  633. combinedIndexBuffer[mapping.indexBufferOffset + i]
  634. = rawIndexBuffer[i] + mapping.vertexBufferOffset;
  635. }
  636. vBuffer->setLength(sizeof(Vec3<float>)
  637. * block->zModelData()->getVertexCount());
  638. vBuffer->setData(vertexBuffer, 1);
  639. vBuffer->copyToGPU();
  640. delete[] vertexBuffer;
  641. DX12Buffer* iBuffer = indexBuffers.z(mappingIndex);
  642. iBuffer->setLength(
  643. sizeof(int) * block->zModelData()->getIndexCount());
  644. iBuffer->setData((void*)rawIndexBuffer, 1);
  645. iBuffer->copyToGPU();
  646. }
  647. DX12Buffer* vBuffer = vertexBuffers.z(mappingIndex);
  648. DX12Buffer* iBuffer = indexBuffers.z(mappingIndex);
  649. simpleBlockDescs[index].Type
  650. = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
  651. simpleBlockDescs[index].Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
  652. simpleBlockDescs[index].Triangles.VertexBuffer.StartAddress
  653. = vBuffer->zBuffer()->GetGPUVirtualAddress();
  654. simpleBlockDescs[index].Triangles.VertexBuffer.StrideInBytes
  655. = vBuffer->getElementLength();
  656. simpleBlockDescs[index].Triangles.VertexFormat
  657. = DXGI_FORMAT_R32G32B32_FLOAT;
  658. simpleBlockDescs[index].Triangles.VertexCount
  659. = vBuffer->getElementCount();
  660. simpleBlockDescs[index].Triangles.IndexBuffer
  661. = iBuffer->zBuffer()->GetGPUVirtualAddress();
  662. simpleBlockDescs[index].Triangles.IndexFormat
  663. = DXGI_FORMAT_R32_UINT;
  664. simpleBlockDescs[index].Triangles.IndexCount
  665. = iBuffer->getElementCount();
  666. simpleBlockDescs[index].Triangles.Transform3x4
  667. = customBlockMatrixBuffer->zBuffer()->GetGPUVirtualAddress()
  668. + 12 * index * sizeof(float);
  669. cbts[index] = block->zTexture()->zPolygonTexture(0)->getId();
  670. indexOffsets[index] = mapping.indexBufferOffset;
  671. ++index;
  672. }
  673. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc;
  674. prebuildDesc.Type
  675. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  676. prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  677. prebuildDesc.NumDescs = customBlocks.getEntryCount();
  678. prebuildDesc.pGeometryDescs = simpleBlockDescs;
  679. prebuildDesc.Flags
  680. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
  681. D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {};
  682. zDevice->GetRaytracingAccelerationStructurePrebuildInfo(
  683. &prebuildDesc, &info);
  684. if (!customBlocksBlasScratchBuffer)
  685. {
  686. customBlocksBlasScratchBuffer = new DX12Buffer(1,
  687. zDevice,
  688. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  689. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  690. }
  691. if (!customBlocksBlasBuffer)
  692. {
  693. customBlocksBlasBuffer = new DX12Buffer(1,
  694. zDevice,
  695. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  696. D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
  697. }
  698. customBlocksBlasScratchBuffer->setLength(
  699. ROUND_UP_POWER_OF_2((int)info.ScratchDataSizeInBytes, 256));
  700. customBlocksBlasScratchBuffer->createBufferWithoutData(
  701. D3D12_RESOURCE_STATE_COMMON);
  702. customBlocksBlasBuffer->setLength(
  703. ROUND_UP_POWER_OF_2((int)info.ResultDataMaxSizeInBytes, 256));
  704. customBlocksBlasBuffer->createBufferWithoutData(
  705. D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
  706. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc;
  707. buildDesc.Inputs.Type
  708. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
  709. buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
  710. buildDesc.Inputs.NumDescs = customBlocks.getEntryCount();
  711. buildDesc.Inputs.pGeometryDescs = simpleBlockDescs;
  712. buildDesc.DestAccelerationStructureData
  713. = {customBlocksBlasBuffer->zBuffer()->GetGPUVirtualAddress()};
  714. buildDesc.ScratchAccelerationStructureData = {
  715. customBlocksBlasScratchBuffer->zBuffer()->GetGPUVirtualAddress()};
  716. buildDesc.SourceAccelerationStructureData = 0;
  717. buildDesc.Inputs.Flags
  718. = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
  719. zQueue->zCommandList()->BuildRaytracingAccelerationStructure(
  720. &buildDesc, 0, nullptr);
  721. if (!customBlockTextures)
  722. {
  723. customBlockTextures = new DX12Buffer(sizeof(int),
  724. zDevice,
  725. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  726. D3D12_RESOURCE_FLAG_NONE);
  727. }
  728. customBlockTextures->setLength(
  729. sizeof(int) * customBlocks.getEntryCount());
  730. customBlockTextures->setData(cbts, 1);
  731. customBlockTextures->copyToGPU();
  732. if (!customBlocksIndexOffsetBuffer)
  733. {
  734. customBlocksIndexOffsetBuffer = new DX12Buffer(sizeof(int),
  735. zDevice,
  736. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  737. D3D12_RESOURCE_FLAG_NONE);
  738. }
  739. customBlocksIndexOffsetBuffer->setLength(
  740. sizeof(int) * customBlocks.getEntryCount());
  741. customBlocksIndexOffsetBuffer->setData(indexOffsets, 1);
  742. customBlocksIndexOffsetBuffer->copyToGPU();
  743. if (!customBlocksVertexDataBuffer)
  744. {
  745. customBlocksVertexDataBuffer
  746. = new DX12Buffer(sizeof(Framework::DX2VertexData),
  747. zDevice,
  748. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  749. D3D12_RESOURCE_FLAG_NONE);
  750. }
  751. customBlocksVertexDataBuffer->setLength(
  752. sizeof(Framework::DX2VertexData) * vertexCount);
  753. customBlocksVertexDataBuffer->setData(vertexDataBuffer, 1);
  754. customBlocksVertexDataBuffer->copyToGPU();
  755. if (!customBlocksCombinedIndexBuffer)
  756. {
  757. customBlocksCombinedIndexBuffer = new DX12Buffer(sizeof(int),
  758. zDevice,
  759. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  760. D3D12_RESOURCE_FLAG_NONE);
  761. }
  762. customBlocksCombinedIndexBuffer->setLength(sizeof(int) * indexCount);
  763. customBlocksCombinedIndexBuffer->setData(combinedIndexBuffer, 1);
  764. customBlocksCombinedIndexBuffer->copyToGPU();
  765. delete[] cbts;
  766. delete[] simpleBlockDescs;
  767. delete[] vertexDataBuffer;
  768. delete[] indexOffsets;
  769. delete[] combinedIndexBuffer;
  770. customBlocksChanged = 0;
  771. customBufferChanged = 1;
  772. }
  773. if (changed)
  774. {
  775. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
  776. {
  777. assert(blockIndices[i] < 0
  778. || blockIndices[i] <= textureIds.getEntryCount() - 6);
  779. }
  780. int* textureIdData = new int[textureIds.getEntryCount()];
  781. ArrayIterator<int> textureIt = textureIds.begin();
  782. int index = 0;
  783. while (textureIt)
  784. {
  785. textureIdData[index++] = textureIt.val();
  786. ++textureIt;
  787. }
  788. blockIndexBuffer->setData(blockIndices, 1);
  789. textureIdBuffer->setData(textureIdData, 1);
  790. blockIndexBuffer->copyToGPU();
  791. textureIdBuffer->copyToGPU(sizeof(int) * textureIds.getEntryCount());
  792. delete[] textureIdData;
  793. ChunkShaderInfo info
  794. = {chunkCenter, (unsigned int)textureIds.getEntryCount()};
  795. chunkInfoBuffer->setData(&info, 1);
  796. chunkInfoBuffer->copyToGPU();
  797. changed = 0;
  798. }
  799. if (!dxLightBuffer)
  800. {
  801. dxLightBuffer = new DX12Buffer(sizeof(unsigned char),
  802. zDevice,
  803. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  804. D3D12_RESOURCE_FLAG_NONE);
  805. if (!lightBuffer)
  806. {
  807. int neededSize
  808. = max(textureIds.getEntryCount() * 8, 6 * 8 * 16 * 16 * 2);
  809. lightBuffer = new unsigned char[neededSize];
  810. lightBufferSize = neededSize;
  811. memset(lightBuffer, -1, lightBufferSize);
  812. }
  813. dxLightBuffer->setData(lightBuffer, 1);
  814. dxLightBuffer->setLength(lightBufferSize);
  815. dxLightBuffer->copyToGPU();
  816. }
  817. cs.unlock();
  818. }
  819. int DX12ChunkData::getLastObjectIndex() const
  820. {
  821. return lastObjectIndex;
  822. }
  823. int DX12ChunkData::getLastCustomObjectIndex() const
  824. {
  825. return lastCustomObjectIndex;
  826. }
  827. int DX12ChunkData::getLastHitGroupIndex() const
  828. {
  829. return lastHitGroupIndex;
  830. }
  831. int DX12ChunkData::getLastCustomHitGroupIndex() const
  832. {
  833. return lastCustomHitGroupIndex;
  834. }
  835. void DX12ChunkData::setLastObjectIndex(int index)
  836. {
  837. lastObjectIndex = index;
  838. }
  839. void DX12ChunkData::setLastCustomObjectIndex(int index)
  840. {
  841. lastCustomObjectIndex = index;
  842. }
  843. void DX12ChunkData::setLastHitGroupIndex(int index)
  844. {
  845. lastHitGroupIndex = index;
  846. }
  847. void DX12ChunkData::setLastCustomHitGroupIndex(int index)
  848. {
  849. lastCustomHitGroupIndex = index;
  850. }
  851. bool DX12ChunkData::wasBufferChanged() const
  852. {
  853. return bufferChanged;
  854. }
  855. void DX12ChunkData::setBufferChanged(bool changed)
  856. {
  857. bufferChanged = changed;
  858. }
  859. bool DX12ChunkData::isSimpleBlock(Block* zBlock) const
  860. {
  861. return zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube")
  862. || ((!zBlock->zModelData()->zSkeleton()
  863. || zBlock->zModelData()->zSkeleton()->getNextBoneId() <= 1)
  864. && zBlock->zModelData()->getPolygonCount() == 1);
  865. }
  866. bool DX12ChunkData::hasCustomBlocks() const
  867. {
  868. return customBlocks.getEntryCount() > 0;
  869. }
  870. bool DX12ChunkData::wasCustomBufferChanged() const
  871. {
  872. return customBufferChanged;
  873. }
  874. void DX12ChunkData::setCustomBufferChanged(bool changed)
  875. {
  876. customBufferChanged = changed;
  877. }