#include "Dx12ChunkData.h" #include #include #include "d3dx12.h" #include "Dimension.h" #include "World.h" DX12ChunkData::DX12ChunkData(Framework::Point center) : ReferenceCounter(), aabbs(0), chunkInfoBuffer(0), blasScratchBuffer(0), customBlocksBlasScratchBuffer(0), oldBlasBuffer(0), blasBuffer(0), customBlocksBlasBuffer(0), blockIndexBuffer(0), textureIdBuffer(0), customBlockTextures(0), customBlocksCombinedIndexBuffer(0), customBlocksVertexDataBuffer(0), customBlocksIndexOffsetBuffer(0), customBlockMatrixBuffer(0), lastObjectIndex(-1), lastCustomObjectIndex(-1), lastHitGroupIndex(-1), lastCustomHitGroupIndex(-1), chunkCenter(center), blockIndices(new int[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT]), textureIds(), changed(0), bufferChanged(0), minZ(WORLD_HEIGHT), maxZ(0), minMaxChanged(0), customBufferChanged(0), customBlocksChanged(0), lightBufferSize(0), lightBuffer(0), dxLightBuffer(0) { memset( blockIndices, -1, sizeof(int) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT); } DX12ChunkData::~DX12ChunkData() { if (aabbs) { aabbs->release(); } if (chunkInfoBuffer) { chunkInfoBuffer->release(); } if (blasScratchBuffer) { blasScratchBuffer->release(); } if (customBlocksBlasScratchBuffer) { customBlocksBlasScratchBuffer->release(); } if (oldBlasBuffer) { oldBlasBuffer->Release(); } if (blasBuffer) { blasBuffer->release(); } if (customBlocksBlasBuffer) { customBlocksBlasBuffer->release(); } if (blockIndexBuffer) { blockIndexBuffer->release(); } if (textureIdBuffer) { textureIdBuffer->release(); } if (customBlockTextures) { customBlockTextures->release(); } if (customBlocksCombinedIndexBuffer) { customBlocksCombinedIndexBuffer->release(); } if (customBlocksVertexDataBuffer) { customBlocksVertexDataBuffer->release(); } if (customBlocksIndexOffsetBuffer) { customBlocksIndexOffsetBuffer->release(); } if (customBlockMatrixBuffer) { customBlockMatrixBuffer->release(); } if (dxLightBuffer) { dxLightBuffer->release(); } delete[] lightBuffer; delete[] blockIndices; } Framework::DX12Buffer* DX12ChunkData::zChunkInfoBuffer() const { return chunkInfoBuffer; } Framework::DX12Buffer* DX12ChunkData::zBlasBuffer() const { return blasBuffer; } Framework::DX12Buffer* DX12ChunkData::zBlockIndexBuffer() const { return blockIndexBuffer; } Framework::DX12Buffer* DX12ChunkData::zTextureIdBuffer() const { return textureIdBuffer; } Framework::DX12Buffer* DX12ChunkData::zLightBuffer() const { return dxLightBuffer; } Framework::DX12Buffer* DX12ChunkData::zCustomBlocksBlasBuffer() const { return customBlocksBlasBuffer; } Framework::DX12Buffer* DX12ChunkData::zCustomBlocksTextureBuffer() const { return customBlockTextures; } Framework::DX12Buffer* DX12ChunkData::zCustomBlocksVertexDataBuffer() const { return customBlocksVertexDataBuffer; } Framework::DX12Buffer* DX12ChunkData::zCustomBlocksCombinedIndexBuffer() const { return customBlocksCombinedIndexBuffer; } Framework::DX12Buffer* DX12ChunkData::zCustomBlocksIndexOffsetBuffer() const { return customBlocksIndexOffsetBuffer; } void DX12ChunkData::setBlock(int index, Block* zBlock) { cs.lock(); if (zBlock && zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube")) { if (blockIndices[index] < 0) { blockIndices[index] = textureIds.getEntryCount(); for (int i = 0; i < 6; ++i) { textureIds.add(zBlock->zTexture()->zPolygonTexture(i)->getId()); } } else { ArrayIterator textureIt = textureIds.begin(); int tmp = blockIndices[index]; while (tmp > 0) { ++textureIt; --tmp; } for (int i = 0; i < 6; ++i) { textureIt.set(zBlock->zTexture()->zPolygonTexture(i)->getId()); ++textureIt; } } if (zBlock->getLocation().z + 1 > maxZ) { maxZ = zBlock->getLocation().z + 1; minMaxChanged = 1; } if (zBlock->getLocation().z < minZ) { minZ = zBlock->getLocation().z; minMaxChanged = 1; } } else { if (blockIndices[index] >= 0) { int tmp = blockIndices[index]; ArrayIterator textureIt = textureIds.begin(); while (tmp > 0) { ++textureIt; --tmp; } for (int i = 0; i < 6; ++i) { textureIt.remove(); } int oldMinZ = minZ; int oldMaxZ = maxZ; maxZ = 0; minZ = WORLD_HEIGHT; for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i) { if (blockIndices[i] > blockIndices[index]) { blockIndices[i] -= 6; } if (blockIndices[i] >= 0) { if (i % WORLD_HEIGHT + 1 > maxZ) { maxZ = i % WORLD_HEIGHT + 1; } if (i % WORLD_HEIGHT < minZ) { minZ = i % WORLD_HEIGHT; } } } if (minZ != oldMinZ || maxZ != oldMaxZ) { minMaxChanged = 1; } } blockIndices[index] = -1; } if (zBlock && !zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube")) { auto iterator = customBlocks.begin(); bool found = 0; while (iterator) { if (iterator->getLocation() == zBlock->getLocation()) { iterator.set(dynamic_cast(zBlock->getThis())); found = 1; break; } ++iterator; } if (!found) { customBlocks.add(dynamic_cast(zBlock->getThis())); } customBlocksChanged = 1; } if (!zBlock || zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube")) { auto iterator = customBlocks.begin(); while (iterator) { if (Chunk::index( Dimension::chunkCoordinates(iterator->getLocation())) == index) { iterator.remove(); customBlocksChanged = 1; break; } ++iterator; } } changed = 1; cs.unlock(); } void DX12ChunkData::updateLightning(Chunk* zChunk) { int neededSize = textureIds.getEntryCount() * 8; if (neededSize > lightBufferSize) { delete[] lightBuffer; lightBuffer = new unsigned char[neededSize]; lightBufferSize = neededSize; if (dxLightBuffer) { dxLightBuffer->setData(lightBuffer, 1); dxLightBuffer->setLength(neededSize); } } Directions vertexDirections[8][3] = { {TOP, NORTH, EAST}, {TOP, SOUTH, EAST}, {TOP, SOUTH, WEST}, {TOP, NORTH, WEST}, {BOTTOM, NORTH, EAST}, {BOTTOM, SOUTH, EAST}, {BOTTOM, SOUTH, WEST}, {BOTTOM, NORTH, WEST} }; const unsigned char noLightData[6] = {0, 0, 0, 0, 0, 0}; for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i) { if (blockIndices[i] >= 0) { Vec3 blockLocation = Chunk::chunkCoordinates(i); Block* zBlock = zChunk->zBlockAt(blockLocation); union { const unsigned char* neighborLightMap[3][3][3]; const unsigned char* neighborLightMapEntries[3 * 3 * 3]; }; for (int j = 0; j < 3 * 3 * 3; j++) { neighborLightMapEntries[j] = noLightData; } for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) { for (int z = -1; z <= 1; ++z) { Vec3 neighborLocation = blockLocation + Vec3(x, y, z); if (neighborLocation.z >= 0 && neighborLocation.z < WORLD_HEIGHT) { if (neighborLocation.x >= 0 && neighborLocation.x < CHUNK_SIZE && neighborLocation.y >= 0 && neighborLocation.y < CHUNK_SIZE) { Block* zNeighborBlock = zChunk->zBlockAt(neighborLocation); if (zNeighborBlock) { for (int d = 0; d < 6; d++) { Vec3 lmi = getDirection( getDirectionFromIndex(d)) + Vec3(x, y, z); if (lmi.x >= -1 && lmi.x <= 1 && lmi.y >= -1 && lmi.y <= 1 && lmi.z >= -1 && lmi.z <= 1) { neighborLightMap[lmi.x + 1] [lmi.y + 1] [lmi.z + 1] = zNeighborBlock->getLightData( getDirectionFromIndex(d)); } } } } } } } } int offset = blockIndices[i] * 8; for (int j = 0; j < 8; ++j) { int lightData[6]; memset(lightData, 0, sizeof(int) * 6); int count = 0; for (int d = 1; d < 8; d++) { Directions direction = vertexDirections[j][0] * ((d & 0x1) != 0) + vertexDirections[j][1] * ((d & 0x2) != 0) + vertexDirections[j][2] * ((d & 0x4) != 0); Vec3 index = getDirection(direction); bool notZero = 0; const unsigned char* currentLight = neighborLightMap[index.x + 1][index.y + 1] [index.z + 1]; for (int k = 0; k < 6; ++k) { lightData[k] += (int)currentLight[k]; notZero |= currentLight[k] > 0; } if (notZero) { ++count; } } for (int k = 0; k < 6; ++k) { lightBuffer[offset + j * 6 + k] = count > 0 ? (unsigned char)(lightData[k] / count) : 0; } } } } if (dxLightBuffer) { dxLightBuffer->setChanged(); dxLightBuffer->copyToGPU(); } } struct ModelIdMapping { int modelId; int vertexBufferOffset; int indexBufferOffset; }; void DX12ChunkData::updateBuffers( ID3D12Device5* zDevice, Framework::DX12CommandQueue* zQueue) { cs.lock(); if (!aabbs) { aabbs = new DX12Buffer(sizeof(D3D12_RAYTRACING_AABB), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); aabbs->setLength(sizeof(D3D12_RAYTRACING_AABB)); D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f, chunkCenter.y - 8.f, (float)minZ, chunkCenter.x + 8.f, chunkCenter.y + 8.f, (float)maxZ}; aabbs->setData(&data, 1); aabbs->copyToGPU(); minMaxChanged = 0; } if (minMaxChanged) { D3D12_RAYTRACING_AABB data = {chunkCenter.x - 8.f, chunkCenter.y - 8.f, (float)minZ, chunkCenter.x + 8.f, chunkCenter.y + 8.f, (float)maxZ}; aabbs->setData(&data, 1); aabbs->copyToGPU(); minMaxChanged = 0; } if (!blasBuffer || minMaxChanged) { D3D12_RAYTRACING_GEOMETRY_DESC geometryDesc = {}; geometryDesc.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; geometryDesc.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; geometryDesc.AABBs.AABBCount = 1; geometryDesc.AABBs.AABBs.StartAddress = aabbs->zBuffer()->GetGPUVirtualAddress(); geometryDesc.AABBs.AABBs.StrideInBytes = sizeof(D3D12_RAYTRACING_AABB); D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc; prebuildDesc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; prebuildDesc.NumDescs = 1; prebuildDesc.pGeometryDescs = &geometryDesc; prebuildDesc.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE; D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {}; zDevice->GetRaytracingAccelerationStructurePrebuildInfo( &prebuildDesc, &info); if (oldBlasBuffer) { oldBlasBuffer->Release(); oldBlasBuffer = 0; } if (blasBuffer) { oldBlasBuffer = blasBuffer->zBuffer(); oldBlasBuffer->AddRef(); blasBuffer->release(); } blasBuffer = new DX12Buffer(1, zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); blasBuffer->setLength( ROUND_UP_POWER_OF_2(info.ResultDataMaxSizeInBytes, 256)); blasBuffer->createBufferWithoutData( D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE); blasScratchBuffer = new DX12Buffer(1, zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); blasScratchBuffer->setLength( ROUND_UP_POWER_OF_2(info.ScratchDataSizeInBytes, 256)); blasScratchBuffer->createBufferWithoutData(D3D12_RESOURCE_STATE_COMMON); D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc; buildDesc.Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; buildDesc.Inputs.NumDescs = 1; buildDesc.Inputs.pGeometryDescs = &geometryDesc; buildDesc.DestAccelerationStructureData = {blasBuffer->zBuffer()->GetGPUVirtualAddress()}; buildDesc.ScratchAccelerationStructureData = {blasScratchBuffer->zBuffer()->GetGPUVirtualAddress()}; buildDesc.SourceAccelerationStructureData = oldBlasBuffer ? oldBlasBuffer->GetGPUVirtualAddress() : 0; buildDesc.Inputs.Flags = oldBlasBuffer ? D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE : D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE; zQueue->zCommandList()->BuildRaytracingAccelerationStructure( &buildDesc, 0, nullptr); bufferChanged = 1; } if (!blockIndexBuffer) { blockIndexBuffer = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); blockIndexBuffer->setLength( sizeof(int) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT); bufferChanged = 1; } if (textureIdBuffer && textureIdBuffer->getElementCount() < textureIds.getEntryCount()) { textureIdBuffer->release(); textureIdBuffer = 0; } if (!textureIdBuffer) { textureIdBuffer = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); textureIdBuffer->setLength(textureIds.getEntryCount() * sizeof(int)); bufferChanged = 1; } if (!chunkInfoBuffer) { chunkInfoBuffer = new DX12Buffer(sizeof(ChunkShaderInfo), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); chunkInfoBuffer->setLength(sizeof(ChunkShaderInfo)); } if (customBlocksChanged) { int* cbts = new int[customBlocks.getEntryCount()]; int index = 0; D3D12_RAYTRACING_GEOMETRY_DESC* simpleBlockDescs = new D3D12_RAYTRACING_GEOMETRY_DESC[customBlocks.getEntryCount()]; int* indexOffsets = new int[customBlocks.getEntryCount()]; int vertexCount = 0; int indexCount = 0; Array idMapping; for (Block* block : customBlocks) { int id = block->zModelData()->getId(); bool found = 0; for (const ModelIdMapping& m : idMapping) { if (m.modelId == id) { found = 1; break; } } if (!found) { ModelIdMapping mapping; mapping.modelId = id; mapping.vertexBufferOffset = vertexCount; mapping.indexBufferOffset = indexCount; idMapping.add(mapping); vertexCount += block->zModelData()->getVertexCount(); indexCount += block->zModelData()->getIndexCount(); } } int* combinedIndexBuffer = new int[indexCount]; Framework::DX2VertexData* vertexDataBuffer = new Framework::DX2VertexData[vertexCount]; int vdIndex = 0; Array modelBuild; float* matrixDataBuffer = new float[customBlocks.getEntryCount() * 12]; int blockIndex = 0; for (Block* block : customBlocks) { Mat4 transform = Mat4::translation( (Vec3)Dimension::chunkCoordinates( block->getLocation()) + Vec3( 0.5f - CHUNK_SIZE / 2, 0.5f - CHUNK_SIZE / 2, 0.5f)) * Mat4::rotationZ(block->getZRotation()) * Mat4::rotationX(block->getXRotation()) * Mat4::rotationY(block->getYRotation()) * Mat4::scaling(block->getSize()); memcpy(matrixDataBuffer + 12 * blockIndex, &transform, 12 * sizeof(float)); ++blockIndex; } if (!customBlockMatrixBuffer) { customBlockMatrixBuffer = new DX12Buffer(sizeof(float) * 12, zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); } customBlockMatrixBuffer->setLength( sizeof(float) * 12 * customBlocks.getEntryCount()); customBlockMatrixBuffer->setData(matrixDataBuffer, 1); customBlockMatrixBuffer->copyToGPU(); CD3DX12_RESOURCE_BARRIER transition = CD3DX12_RESOURCE_BARRIER::Transition( customBlockMatrixBuffer->zBuffer(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); zQueue->zCommandList()->ResourceBarrier(1, &transition); for (Block* block : customBlocks) { int id = block->zModelData()->getId(); ModelIdMapping mapping; int mappingIndex = 0; for (const ModelIdMapping& m : idMapping) { if (m.modelId == id) { mapping = m; break; } ++mappingIndex; } if (modelBuild.getValueIndex(id) < 0) { modelBuild.add(id); while (vertexBuffers.getEntryCount() <= mappingIndex) { DX12Buffer* vBuffer = new DX12Buffer(sizeof(Vec3), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); vertexBuffers.add(vBuffer); } while (indexBuffers.getEntryCount() <= mappingIndex) { DX12Buffer* iBuffer = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); indexBuffers.add(iBuffer); } DX12Buffer* vBuffer = vertexBuffers.z(mappingIndex); Vec3* vertexBuffer = new Vec3[block->zModelData()->getVertexCount()]; const Vertex3D* rawVertexData = block->zModelData()->zVertexBuffer(); for (int i = 0; i < block->zModelData()->getVertexCount(); ++i) { vertexBuffer[i] = rawVertexData[i].pos; vertexDataBuffer[mapping.vertexBufferOffset + i] = {rawVertexData[i].tPos, rawVertexData[i].normal}; } const int* rawIndexBuffer = block->zModelData()->getIndexBuffer(); for (int i = 0; i < block->zModelData()->getIndexCount(); i++) { combinedIndexBuffer[mapping.indexBufferOffset + i] = rawIndexBuffer[i] + mapping.vertexBufferOffset; } vBuffer->setLength(sizeof(Vec3) * block->zModelData()->getVertexCount()); vBuffer->setData(vertexBuffer, 1); vBuffer->copyToGPU(); delete[] vertexBuffer; DX12Buffer* iBuffer = indexBuffers.z(mappingIndex); iBuffer->setLength( sizeof(int) * block->zModelData()->getIndexCount()); iBuffer->setData((void*)rawIndexBuffer, 1); iBuffer->copyToGPU(); } DX12Buffer* vBuffer = vertexBuffers.z(mappingIndex); DX12Buffer* iBuffer = indexBuffers.z(mappingIndex); simpleBlockDescs[index].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; simpleBlockDescs[index].Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; simpleBlockDescs[index].Triangles.VertexBuffer.StartAddress = vBuffer->zBuffer()->GetGPUVirtualAddress(); simpleBlockDescs[index].Triangles.VertexBuffer.StrideInBytes = vBuffer->getElementLength(); simpleBlockDescs[index].Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT; simpleBlockDescs[index].Triangles.VertexCount = (unsigned)vBuffer->getElementCount(); simpleBlockDescs[index].Triangles.IndexBuffer = iBuffer->zBuffer()->GetGPUVirtualAddress(); simpleBlockDescs[index].Triangles.IndexFormat = DXGI_FORMAT_R32_UINT; simpleBlockDescs[index].Triangles.IndexCount = (unsigned)iBuffer->getElementCount(); simpleBlockDescs[index].Triangles.Transform3x4 = customBlockMatrixBuffer->zBuffer()->GetGPUVirtualAddress() + 12 * index * sizeof(float); cbts[index] = block->zTexture()->zPolygonTexture(0)->getId(); indexOffsets[index] = mapping.indexBufferOffset; ++index; } D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc; prebuildDesc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; prebuildDesc.NumDescs = customBlocks.getEntryCount(); prebuildDesc.pGeometryDescs = simpleBlockDescs; prebuildDesc.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE; D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {}; zDevice->GetRaytracingAccelerationStructurePrebuildInfo( &prebuildDesc, &info); if (!customBlocksBlasScratchBuffer) { customBlocksBlasScratchBuffer = new DX12Buffer(1, zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); } if (!customBlocksBlasBuffer) { customBlocksBlasBuffer = new DX12Buffer(1, zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); } customBlocksBlasScratchBuffer->setLength( ROUND_UP_POWER_OF_2((int)info.ScratchDataSizeInBytes, 256)); customBlocksBlasScratchBuffer->createBufferWithoutData( D3D12_RESOURCE_STATE_COMMON); customBlocksBlasBuffer->setLength( ROUND_UP_POWER_OF_2((int)info.ResultDataMaxSizeInBytes, 256)); customBlocksBlasBuffer->createBufferWithoutData( D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE); D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc; buildDesc.Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; buildDesc.Inputs.NumDescs = customBlocks.getEntryCount(); buildDesc.Inputs.pGeometryDescs = simpleBlockDescs; buildDesc.DestAccelerationStructureData = {customBlocksBlasBuffer->zBuffer()->GetGPUVirtualAddress()}; buildDesc.ScratchAccelerationStructureData = { customBlocksBlasScratchBuffer->zBuffer()->GetGPUVirtualAddress()}; buildDesc.SourceAccelerationStructureData = 0; buildDesc.Inputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE; zQueue->zCommandList()->BuildRaytracingAccelerationStructure( &buildDesc, 0, nullptr); if (!customBlockTextures) { customBlockTextures = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); } customBlockTextures->setLength( sizeof(int) * customBlocks.getEntryCount()); customBlockTextures->setData(cbts, 1); customBlockTextures->copyToGPU(); if (!customBlocksIndexOffsetBuffer) { customBlocksIndexOffsetBuffer = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); } customBlocksIndexOffsetBuffer->setLength( sizeof(int) * customBlocks.getEntryCount()); customBlocksIndexOffsetBuffer->setData(indexOffsets, 1); customBlocksIndexOffsetBuffer->copyToGPU(); if (!customBlocksVertexDataBuffer) { customBlocksVertexDataBuffer = new DX12Buffer(sizeof(Framework::DX2VertexData), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); } customBlocksVertexDataBuffer->setLength( sizeof(Framework::DX2VertexData) * vertexCount); customBlocksVertexDataBuffer->setData(vertexDataBuffer, 1); customBlocksVertexDataBuffer->copyToGPU(); if (!customBlocksCombinedIndexBuffer) { customBlocksCombinedIndexBuffer = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); } customBlocksCombinedIndexBuffer->setLength(sizeof(int) * indexCount); customBlocksCombinedIndexBuffer->setData(combinedIndexBuffer, 1); customBlocksCombinedIndexBuffer->copyToGPU(); delete[] cbts; delete[] simpleBlockDescs; delete[] vertexDataBuffer; delete[] indexOffsets; delete[] combinedIndexBuffer; customBlocksChanged = 0; customBufferChanged = 1; } if (changed) { for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i) { assert(blockIndices[i] < 0 || blockIndices[i] <= textureIds.getEntryCount() - 6); } int* textureIdData = new int[textureIds.getEntryCount()]; ArrayIterator textureIt = textureIds.begin(); int index = 0; while (textureIt) { textureIdData[index++] = textureIt.val(); ++textureIt; } blockIndexBuffer->setData(blockIndices, 1); textureIdBuffer->setData(textureIdData, 1); blockIndexBuffer->copyToGPU(); textureIdBuffer->copyToGPU(sizeof(int) * textureIds.getEntryCount()); delete[] textureIdData; ChunkShaderInfo info = {chunkCenter, (unsigned int)textureIds.getEntryCount()}; chunkInfoBuffer->setData(&info, 1); chunkInfoBuffer->copyToGPU(); changed = 0; } if (!dxLightBuffer) { dxLightBuffer = new DX12Buffer(sizeof(unsigned char), zDevice, dynamic_cast(zQueue->getThis()), D3D12_RESOURCE_FLAG_NONE); if (!lightBuffer) { int neededSize = max(textureIds.getEntryCount() * 8, 6 * 8 * 16 * 16 * 2); lightBuffer = new unsigned char[neededSize]; lightBufferSize = neededSize; memset(lightBuffer, -1, lightBufferSize); } dxLightBuffer->setData(lightBuffer, 1); dxLightBuffer->setLength(lightBufferSize); dxLightBuffer->copyToGPU(); } cs.unlock(); } int DX12ChunkData::getLastObjectIndex() const { return lastObjectIndex; } int DX12ChunkData::getLastCustomObjectIndex() const { return lastCustomObjectIndex; } int DX12ChunkData::getLastHitGroupIndex() const { return lastHitGroupIndex; } int DX12ChunkData::getLastCustomHitGroupIndex() const { return lastCustomHitGroupIndex; } void DX12ChunkData::setLastObjectIndex(int index) { lastObjectIndex = index; } void DX12ChunkData::setLastCustomObjectIndex(int index) { lastCustomObjectIndex = index; } void DX12ChunkData::setLastHitGroupIndex(int index) { lastHitGroupIndex = index; } void DX12ChunkData::setLastCustomHitGroupIndex(int index) { lastCustomHitGroupIndex = index; } bool DX12ChunkData::wasBufferChanged() const { return bufferChanged; } void DX12ChunkData::setBufferChanged(bool changed) { bufferChanged = changed; } bool DX12ChunkData::isSimpleBlock(Block* zBlock) const { return zBlock->zBlockType()->getModelInfo().getModelName().isEqual("cube") || ((!zBlock->zModelData()->zSkeleton() || zBlock->zModelData()->zSkeleton()->getNextBoneId() <= 1) && zBlock->zModelData()->getPolygonCount() == 1); } bool DX12ChunkData::hasCustomBlocks() const { return customBlocks.getEntryCount() > 0; } bool DX12ChunkData::wasCustomBufferChanged() const { return customBufferChanged; } void DX12ChunkData::setCustomBufferChanged(bool changed) { customBufferChanged = changed; }