| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- #include "CustomDX12API.h"
- #include <DX12Buffer.h>
- #include <DX12CommandQueue.h>
- #include <DX12Shader.h>
- #include <DX12Texture.h>
- #include <DX12TLAS.h>
- #include "CustomChunkAnyHitShader.h"
- #include "CustomChunkClosestHitShader.h"
- #include "CustomChunkIntersectionShader.h"
- #include "CustomCustomMissShader.h"
- #include "CustomCustomRayGenShader.h"
- #include "CustomDefaultAnyHitShader.h"
- #include "CustomDefaultClosestHitShader.h"
- #include "CustomSimpleBlocksAnyHitShader.h"
- #include "CustomSimpleBlocksClosestHitShader.h"
- #include "Dimension.h"
- #include "DX12ChunkData.h"
- #include "World.h"
- using namespace Framework;
- CustomDX12API::CustomDX12API()
- : DirectX12(),
- sbtChunkTextureIdBufferOffset(0),
- sbtChunkIndexBufferOffset(0),
- sbtChunkDataBufferOffset(0),
- sbtChunkLightBufferOffset(0),
- sbtSimpleBlocksTextureIdBufferOffset(0),
- sbtSimpleBlocksIndexBufferOffset(0),
- sbtSimpleBlocksVertexDataBufferOffset(0),
- sbtSimpleBlocksIndexOffsetBufferOffset(0),
- sbtSimpleBlocksLightBufferOffset(0),
- sbtDefaultLightBufferOffset(0),
- globalLightBufferOffset(0),
- chunkHitGroup(0),
- simpleBlocksHitGroup(0),
- lightInfoBuffer(0),
- defaultLightBuffer(0)
- {}
- CustomDX12API::~CustomDX12API()
- {
- if (lightInfoBuffer)
- {
- lightInfoBuffer->release();
- }
- if (defaultLightBuffer)
- {
- defaultLightBuffer->release();
- }
- }
- void CustomDX12API::initializePipeline()
- {
- if (!lightInfoBuffer)
- {
- lightInfoBuffer = new DX12Buffer(sizeof(DX12ShaderLightInfo),
- device,
- dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
- D3D12_RESOURCE_FLAG_NONE);
- lightInfoBuffer->setData(&lightInfo, 1);
- lightInfoBuffer->setLength(sizeof(DX12ShaderLightInfo));
- }
- if (!defaultLightBuffer)
- {
- defaultLightBuffer = new DX12Buffer(sizeof(unsigned char),
- device,
- dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
- D3D12_RESOURCE_FLAG_NONE);
- defaultLightBuffer->setLength(6);
- unsigned char defaultLight[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
- defaultLightBuffer->setData(defaultLight, 1);
- defaultLightBuffer->copyToGPU();
- }
- if (pipeline->getShaders().getEntryCount() == 0)
- { // add default shaders
- pipeline->zGlobalSignature()->addRegisterUsageLinkedToDescriptorHeap(
- 0, DX12_SHADER_REGISTER_S_SAMPLER, 0, 0, SAMPLER_DESCRIPTOR_HEAP);
- pipeline->zGlobalSignature()->addRegisterUsageLinkedToDescriptorHeap(
- firstTextureHeapIndex,
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE,
- 0,
- 1,
- GLOBAL_DESCRIPTOR_HEAP,
- 1);
- globalLightBufferOffset
- = pipeline->zGlobalSignature()
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_B_CONST_BUFFER, 0, 1);
- globalTLASoffset = pipeline->zGlobalSignature()
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 0);
- pipeline->zGlobalSignature()->addRegisterUsageLinkedToDescriptorHeap(
- 0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 0);
- pipeline->zGlobalSignature()->addRegisterUsageLinkedToDescriptorHeap(
- 1, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 1);
- globalRayGenerationSettingsOffset
- = pipeline->zGlobalSignature()
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_B_CONST_BUFFER, 0);
- DX12Shader* rayGenShader = new DX12Shader(
- CustomCustomRayGenShader, sizeof(CustomCustomRayGenShader));
- // RayGen from RayGen.hlsl
- DX12ShaderSignature* rayGenSignature = new DX12ShaderSignature();
- defaultRayGenerationShaderFunction = new DX12ShaderFunction(
- "RayGen", rayGenSignature, DX12_SHADER_FUNCTION_TYPE_RAY_GEN);
- rayGenShader->addFunction(defaultRayGenerationShaderFunction);
- pipeline->addShader(rayGenShader);
- DX12Shader* missShader = new DX12Shader(
- CustomCustomMissShader, sizeof(CustomCustomMissShader));
- // Miss from Miss.hlsl
- missShader->addFunction(new DX12ShaderFunction(
- "Miss", new DX12ShaderSignature(), DX12_SHADER_FUNCTION_TYPE_MISS));
- pipeline->addShader(missShader);
- DX12ShaderSignature* hitSignature = new DX12ShaderSignature();
- sbtTextureIdBufferOffset
- = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 2);
- sbtIndexBufferOffset
- = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 3);
- sbtVertexDataBufferOffset
- = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 4);
- sbtPolygonSizeBufferOffset
- = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 5);
- sbtDefaultLightBufferOffset
- = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 6);
- DX12Shader* anyHitShader = new DX12Shader(
- CustomDefaultAnyHitShader, sizeof(CustomDefaultAnyHitShader));
- DX12ShaderFunction* anyHitFunction = new DX12ShaderFunction(
- "AnyHit", hitSignature, DX12_SHADER_FUNCTION_TYPE_ANY_HIT);
- // AnyHit from AnyHit.hlsl
- anyHitShader->addFunction(anyHitFunction);
- pipeline->addShader(anyHitShader);
- DX12Shader* hitShader = new DX12Shader(CustomDefaultClosestHitShader,
- sizeof(CustomDefaultClosestHitShader));
- // ClosestHit from Hit.hlsl
- DX12ShaderFunction* closestHitFunction
- = new DX12ShaderFunction("ClosestHit",
- dynamic_cast<DX12ShaderSignature*>(hitSignature->getThis()),
- DX12_SHADER_FUNCTION_TYPE_CLOSEST_HIT);
- hitShader->addFunction(closestHitFunction);
- pipeline->addShader(hitShader);
- defaultHitGroup = new DX12ShaderHitGroup("HitGroup");
- defaultHitGroup->setAttributeSize(8);
- defaultHitGroup->setPayloadSize(40 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
- defaultHitGroup->setAnyHitShaderFunction(anyHitFunction);
- defaultHitGroup->setClosestHitShaderFunction(closestHitFunction);
- pipeline->addHitGroup(defaultHitGroup);
- // Chunk ray traversal shaders
- DX12ShaderSignature* chunkHitSignature = new DX12ShaderSignature();
- sbtChunkTextureIdBufferOffset
- = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 2);
- sbtChunkIndexBufferOffset
- = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 3);
- sbtChunkLightBufferOffset
- = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 4);
- sbtChunkDataBufferOffset
- = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_B_CONST_BUFFER, 0, 2);
- DX12Shader* chunkIntersectionShader
- = new DX12Shader(CustomChunkIntersectionShader,
- sizeof(CustomChunkIntersectionShader));
- DX12ShaderFunction* chunkIntersectionFunction
- = new DX12ShaderFunction("ChunkIntersection",
- chunkHitSignature,
- DX12_SHADER_FUNCTION_TYPE_INTERSECTION);
- chunkIntersectionShader->addFunction(chunkIntersectionFunction);
- pipeline->addShader(chunkIntersectionShader);
- DX12Shader* chunkAnyHitShader = new DX12Shader(
- CustomChunkAnyHitShader, sizeof(CustomChunkAnyHitShader));
- DX12ShaderFunction* chunkAnyHitFunction = new DX12ShaderFunction(
- "ChunkAnyHit",
- dynamic_cast<DX12ShaderSignature*>(chunkHitSignature->getThis()),
- DX12_SHADER_FUNCTION_TYPE_ANY_HIT);
- chunkAnyHitShader->addFunction(chunkAnyHitFunction);
- pipeline->addShader(chunkAnyHitShader);
- DX12Shader* chunkClosestHitShader = new DX12Shader(
- CustomChunkClosestHitShader, sizeof(CustomChunkClosestHitShader));
- DX12ShaderFunction* chunkClosestHitFunction = new DX12ShaderFunction(
- "ChunkClosestHit",
- dynamic_cast<DX12ShaderSignature*>(chunkHitSignature->getThis()),
- DX12_SHADER_FUNCTION_TYPE_CLOSEST_HIT);
- chunkClosestHitShader->addFunction(chunkClosestHitFunction);
- pipeline->addShader(chunkClosestHitShader);
- chunkHitGroup = new DX12ShaderHitGroup("ChunkHitGroup");
- chunkHitGroup->setIntersectionShaderFunction(chunkIntersectionFunction);
- chunkHitGroup->setAnyHitShaderFunction(chunkAnyHitFunction);
- chunkHitGroup->setClosestHitShaderFunction(chunkClosestHitFunction);
- chunkHitGroup->setAttributeSize(32);
- chunkHitGroup->setPayloadSize(40 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
- pipeline->addHitGroup(chunkHitGroup);
- // simple blocks hit shaders
- DX12ShaderSignature* simpleBlocksHitSignature
- = new DX12ShaderSignature();
- sbtSimpleBlocksTextureIdBufferOffset
- = simpleBlocksHitSignature
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 2);
- sbtSimpleBlocksIndexBufferOffset
- = simpleBlocksHitSignature
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 3);
- sbtSimpleBlocksVertexDataBufferOffset
- = simpleBlocksHitSignature
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 4);
- sbtSimpleBlocksIndexOffsetBufferOffset
- = simpleBlocksHitSignature
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 5);
- sbtSimpleBlocksLightBufferOffset
- = simpleBlocksHitSignature
- ->addRegisterUsageLinkedToShaderBindingTable(
- DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 6);
- DX12Shader* simpleBlocksAnyHitShader
- = new DX12Shader(CustomSimpleBlocksAnyHitShader,
- sizeof(CustomSimpleBlocksAnyHitShader));
- DX12ShaderFunction* simpleBlocksAnyHitFunction
- = new DX12ShaderFunction("SimpleBlocksAnyHit",
- simpleBlocksHitSignature,
- DX12_SHADER_FUNCTION_TYPE_ANY_HIT);
- simpleBlocksAnyHitShader->addFunction(simpleBlocksAnyHitFunction);
- pipeline->addShader(simpleBlocksAnyHitShader);
- DX12Shader* simpleBlocksClosestHitShader
- = new DX12Shader(CustomSimpleBlocksClosestHitShader,
- sizeof(CustomSimpleBlocksClosestHitShader));
- DX12ShaderFunction* simpleBlocksClosestHitFunction
- = new DX12ShaderFunction("SimpleBlocksClosestHit",
- dynamic_cast<DX12ShaderSignature*>(
- simpleBlocksHitSignature->getThis()),
- DX12_SHADER_FUNCTION_TYPE_CLOSEST_HIT);
- simpleBlocksClosestHitShader->addFunction(
- simpleBlocksClosestHitFunction);
- pipeline->addShader(simpleBlocksClosestHitShader);
- simpleBlocksHitGroup = new DX12ShaderHitGroup("SimpleBlocksHitGroup");
- simpleBlocksHitGroup->setAnyHitShaderFunction(
- simpleBlocksAnyHitFunction);
- simpleBlocksHitGroup->setClosestHitShaderFunction(
- simpleBlocksClosestHitFunction);
- simpleBlocksHitGroup->setAttributeSize(8);
- simpleBlocksHitGroup->setPayloadSize(
- 40 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
- pipeline->addHitGroup(simpleBlocksHitGroup);
- pipeline->setMaxRecursionDepth(10);
- }
- pipeline->createPipelineState(device, pfnD3D12SerializeRootSignature);
- }
- void CustomDX12API::fillShaderBindingTable(
- Framework::DX12ShaderBindingTable* zShaderBindingTable,
- Framework::Model3D* zModel,
- int objectIndex,
- const Framework::DX12BLAS* zBLAS,
- int& lastHitGroupIndex)
- {
- DirectX12::fillShaderBindingTable(
- zShaderBindingTable, zModel, objectIndex, zBLAS, lastHitGroupIndex);
- FactoryCraftModel* fcmdl = dynamic_cast<FactoryCraftModel*>(zModel);
- if (fcmdl)
- {
- fcmdl->zLightBuffer()->copyToGPU();
- zShaderBindingTable->setHitGroupShaderInput(lastHitGroupIndex,
- sbtDefaultLightBufferOffset,
- dynamic_cast<DX12Buffer*>(fcmdl->zLightBuffer())
- ->zBuffer()
- ->GetGPUVirtualAddress());
- }
- else
- {
- zShaderBindingTable->setHitGroupShaderInput(lastHitGroupIndex,
- sbtDefaultLightBufferOffset,
- defaultLightBuffer->zBuffer()->GetGPUVirtualAddress());
- }
- }
- int CustomDX12API::fillGlobalShaderParams(
- Cam3D* zCam, DX12TLAS* zTLAS, DX12Texture* zTarget, int startIndex)
- {
- if (World::INSTANCE)
- {
- lightInfo.dayLightFactor = World::INSTANCE->getDayLightFactor();
- lightInfo.dayLightDirection = World::INSTANCE->getDayLightDirection();
- }
- else
- {
- lightInfo.dayLightFactor = Vec3<float>(1.f, 1.f, 1.f);
- lightInfo.dayLightDirection = Vec3<float>(0.f, 0.f, -1.f);
- }
- lightInfoBuffer->setChanged();
- lightInfoBuffer->copyToGPU();
- int result
- = DirectX12::fillGlobalShaderParams(zCam, zTLAS, zTarget, startIndex);
- directCommandQueue->zCommandList()->SetComputeRootConstantBufferView(
- *globalLightBufferOffset,
- lightInfoBuffer->zBuffer()->GetGPUVirtualAddress());
- return result;
- }
- void CustomDX12API::renderWorld(Framework::World3D* zWorld,
- DX12TLAS* zTLAS,
- DX12ShaderBindingTable* zSBT,
- int& objectIndex)
- {
- Mat4<float> identity = Mat4<float>::identity();
- for (const Model3DCollection* collection : zWorld->getCollections())
- {
- const Dimension* dim = dynamic_cast<const Dimension*>(collection);
- if (dim)
- {
- for (const Chunk* chunk : dim->getChunks())
- {
- DX12ChunkData* chunkData = chunk->zDX12Data();
- chunkData->updateBuffers(device, directCommandQueue);
- if (chunkData->hasCustomBlocks())
- {
- bool changed
- = chunkData->wasCustomBufferChanged()
- || chunkData->getLastCustomObjectIndex() != objectIndex;
- if (changed)
- {
- chunkData->setLastCustomObjectIndex(objectIndex);
- D3D12_RAYTRACING_INSTANCE_DESC* desc
- = zTLAS->nextInstanceDesc();
- desc->InstanceID = objectIndex;
- desc->InstanceContributionToHitGroupIndex = objectIndex;
- desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
- desc->InstanceMask = 0xFF;
- desc->AccelerationStructure
- = chunkData->zCustomBlocksBlasBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress();
- Framework::Mat4<float> transform
- = Framework::Mat4<float>::translation(
- Vec3<float>((float)chunk->getCenter().x,
- (float)chunk->getCenter().y,
- 0.f));
- memcpy(desc->Transform, &transform, sizeof(float) * 12);
- }
- else
- {
- zTLAS->nextInstanceDesc();
- }
- int hitGroupOffset = zSBT->addHitGroup(simpleBlocksHitGroup,
- chunkData->getLastCustomHitGroupIndex());
- if (chunkData->getLastCustomHitGroupIndex()
- != hitGroupOffset
- || chunkData->wasCustomBufferChanged())
- {
- chunkData->setLastCustomHitGroupIndex(hitGroupOffset);
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtSimpleBlocksTextureIdBufferOffset,
- chunkData->zCustomBlocksTextureBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtSimpleBlocksIndexBufferOffset,
- chunkData->zCustomBlocksCombinedIndexBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtSimpleBlocksVertexDataBufferOffset,
- chunkData->zCustomBlocksVertexDataBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtSimpleBlocksIndexOffsetBufferOffset,
- chunkData->zCustomBlocksIndexOffsetBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtDefaultLightBufferOffset,
- chunkData->zCustomBlocksLightBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- }
- chunkData->setCustomBufferChanged(0);
- ++objectIndex;
- }
- bool changed = chunkData->wasBufferChanged()
- || chunkData->getLastObjectIndex() != objectIndex;
- if (changed)
- {
- chunkData->setLastObjectIndex(objectIndex);
- D3D12_RAYTRACING_INSTANCE_DESC* desc
- = zTLAS->nextInstanceDesc();
- desc->InstanceID = objectIndex;
- desc->InstanceContributionToHitGroupIndex = objectIndex;
- desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
- desc->InstanceMask = 0xFF;
- desc->AccelerationStructure = chunkData->zBlasBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress();
- memcpy(desc->Transform, &identity, sizeof(float) * 12);
- }
- else
- {
- zTLAS->nextInstanceDesc();
- }
- int hitGroupOffset = zSBT->addHitGroup(
- chunkHitGroup, chunkData->getLastHitGroupIndex());
- if (chunkData->getLastHitGroupIndex() != hitGroupOffset
- || chunkData->wasBufferChanged())
- {
- chunkData->setLastHitGroupIndex(hitGroupOffset);
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtChunkIndexBufferOffset,
- chunkData->zBlockIndexBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtChunkTextureIdBufferOffset,
- chunkData->zTextureIdBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtChunkDataBufferOffset,
- chunkData->zChunkInfoBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- zSBT->setHitGroupShaderInput(hitGroupOffset,
- sbtChunkLightBufferOffset,
- chunkData->zLightBuffer()
- ->zBuffer()
- ->GetGPUVirtualAddress());
- }
- chunkData->setBufferChanged(0);
- ++objectIndex;
- }
- }
- }
- DirectX12::renderWorld(zWorld, zTLAS, zSBT, objectIndex);
- }
|