|
@@ -32,6 +32,26 @@
|
|
|
|
|
|
|
|
using namespace Framework;
|
|
using namespace Framework;
|
|
|
|
|
|
|
|
|
|
+class DX12RenderingData : public Framework::ReferenceCounter
|
|
|
|
|
+{
|
|
|
|
|
+public:
|
|
|
|
|
+ int lastObjectIndex;
|
|
|
|
|
+ int lastBlasCount;
|
|
|
|
|
+ int* lastHitGroupIndices;
|
|
|
|
|
+
|
|
|
|
|
+ DX12RenderingData()
|
|
|
|
|
+ : Framework::ReferenceCounter(),
|
|
|
|
|
+ lastObjectIndex(-1),
|
|
|
|
|
+ lastBlasCount(0),
|
|
|
|
|
+ lastHitGroupIndices(0)
|
|
|
|
|
+ {}
|
|
|
|
|
+
|
|
|
|
|
+ ~DX12RenderingData()
|
|
|
|
|
+ {
|
|
|
|
|
+ if (lastHitGroupIndices) delete[] lastHitGroupIndices;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
DirectX12::DirectX12()
|
|
DirectX12::DirectX12()
|
|
|
: GraphicsApi(DIRECTX12),
|
|
: GraphicsApi(DIRECTX12),
|
|
|
debug(0),
|
|
debug(0),
|
|
@@ -240,26 +260,68 @@ void Framework::DirectX12::renderKamera(
|
|
|
sbt->setSamplerDescriptorHeap(samplerDescriptorHeap);
|
|
sbt->setSamplerDescriptorHeap(samplerDescriptorHeap);
|
|
|
w->render([this, &tlas, &objectIndex, &instanceIndex, &identity, &sbt](
|
|
w->render([this, &tlas, &objectIndex, &instanceIndex, &identity, &sbt](
|
|
|
Model3D* obj) {
|
|
Model3D* obj) {
|
|
|
- obj->calculateMatrices(identity, matrixBuffer);
|
|
|
|
|
|
|
+ DX12RenderingData* renderingData
|
|
|
|
|
+ = dynamic_cast<DX12RenderingData*>(obj->zRenderingData());
|
|
|
|
|
+ if (!renderingData)
|
|
|
|
|
+ {
|
|
|
|
|
+ renderingData = new DX12RenderingData();
|
|
|
|
|
+ obj->setRenderingData(renderingData);
|
|
|
|
|
+ }
|
|
|
int modelId = obj->zModelData()->getId();
|
|
int modelId = obj->zModelData()->getId();
|
|
|
DX12BLASModel* blasModel = blasModels[modelId];
|
|
DX12BLASModel* blasModel = blasModels[modelId];
|
|
|
- blasModel->calculateBuffers();
|
|
|
|
|
|
|
+ bool changed
|
|
|
|
|
+ = obj->getLastTickReturn()
|
|
|
|
|
+ || renderingData->lastObjectIndex != objectIndex
|
|
|
|
|
+ || renderingData->lastBlasCount != blasModel->getBufferCount()
|
|
|
|
|
+ || obj->zModelData()->wasIndexBufferChanged()
|
|
|
|
|
+ || obj->zModelData()->wasVertexBufferChanged();
|
|
|
|
|
+ renderingData->lastObjectIndex = objectIndex;
|
|
|
|
|
+ if (changed)
|
|
|
|
|
+ {
|
|
|
|
|
+ obj->calculateMatrices(identity, matrixBuffer);
|
|
|
|
|
+ blasModel->calculateBuffers();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (renderingData->lastBlasCount < blasModel->getBufferCount())
|
|
|
|
|
+ {
|
|
|
|
|
+ if (renderingData->lastHitGroupIndices)
|
|
|
|
|
+ {
|
|
|
|
|
+ delete[] renderingData->lastHitGroupIndices;
|
|
|
|
|
+ }
|
|
|
|
|
+ renderingData->lastHitGroupIndices
|
|
|
|
|
+ = new int[blasModel->getBufferCount()];
|
|
|
|
|
+ memset(renderingData->lastHitGroupIndices,
|
|
|
|
|
+ -1,
|
|
|
|
|
+ sizeof(int) * blasModel->getBufferCount());
|
|
|
|
|
+ renderingData->lastBlasCount = blasModel->getBufferCount();
|
|
|
|
|
+ }
|
|
|
ArrayIterator<int> boneIds = blasModel->zBoneIds()->begin();
|
|
ArrayIterator<int> boneIds = blasModel->zBoneIds()->begin();
|
|
|
|
|
+ instanceIndex = 0;
|
|
|
for (const DX12BLAS* blas : *blasModel->zBLAS())
|
|
for (const DX12BLAS* blas : *blasModel->zBLAS())
|
|
|
{
|
|
{
|
|
|
- D3D12_RAYTRACING_INSTANCE_DESC* desc = tlas->nextInstanceDesc();
|
|
|
|
|
- desc->InstanceID = objectIndex;
|
|
|
|
|
- desc->InstanceContributionToHitGroupIndex = objectIndex;
|
|
|
|
|
- desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
|
|
|
|
|
- desc->InstanceMask = 0xFF * (obj->getSize() > 0);
|
|
|
|
|
- desc->AccelerationStructure
|
|
|
|
|
- = blas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress();
|
|
|
|
|
- memcpy(desc->Transform,
|
|
|
|
|
- &matrixBuffer[boneIds.val()],
|
|
|
|
|
- sizeof(float) * 12);
|
|
|
|
|
|
|
+ if (changed)
|
|
|
|
|
+ {
|
|
|
|
|
+ D3D12_RAYTRACING_INSTANCE_DESC* desc = tlas->nextInstanceDesc();
|
|
|
|
|
+ desc->InstanceID = objectIndex;
|
|
|
|
|
+ desc->InstanceContributionToHitGroupIndex = objectIndex;
|
|
|
|
|
+ desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
|
|
|
|
|
+ desc->InstanceMask = 0xFF * (obj->getSize() > 0);
|
|
|
|
|
+ desc->AccelerationStructure
|
|
|
|
|
+ = blas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress();
|
|
|
|
|
+ memcpy(desc->Transform,
|
|
|
|
|
+ &matrixBuffer[boneIds.val()],
|
|
|
|
|
+ sizeof(float) * 12);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ tlas->nextInstanceDesc();
|
|
|
|
|
+ }
|
|
|
boneIds++;
|
|
boneIds++;
|
|
|
|
|
+ fillShaderBindingTable(sbt,
|
|
|
|
|
+ obj,
|
|
|
|
|
+ objectIndex,
|
|
|
|
|
+ blas,
|
|
|
|
|
+ renderingData->lastHitGroupIndices[instanceIndex]);
|
|
|
instanceIndex++;
|
|
instanceIndex++;
|
|
|
- fillShaderBindingTable(sbt, obj, objectIndex, blas);
|
|
|
|
|
objectIndex++;
|
|
objectIndex++;
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
@@ -427,26 +489,34 @@ void Framework::DirectX12::fillShaderBindingTable(
|
|
|
DX12ShaderBindingTable* zShaderBindingTable,
|
|
DX12ShaderBindingTable* zShaderBindingTable,
|
|
|
Model3D* zModel,
|
|
Model3D* zModel,
|
|
|
int instanceIndex,
|
|
int instanceIndex,
|
|
|
- const DX12BLAS* zBLAS)
|
|
|
|
|
|
|
+ const DX12BLAS* zBLAS,
|
|
|
|
|
+ int& lastHitGroupIndex)
|
|
|
{
|
|
{
|
|
|
if (defaultHitGroup)
|
|
if (defaultHitGroup)
|
|
|
{
|
|
{
|
|
|
- int hitGroupOffset = zShaderBindingTable->addHitGroup(defaultHitGroup);
|
|
|
|
|
- zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
- sbtIndexBufferOffset,
|
|
|
|
|
- zBLAS->zIndexBuffer()->zBuffer()->GetGPUVirtualAddress());
|
|
|
|
|
- zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
- sbtVertexDataBufferOffset,
|
|
|
|
|
- zBLAS->zVertexDataBuffer()->zBuffer()->GetGPUVirtualAddress());
|
|
|
|
|
- zModel->zTexture()->updateTextureIndexBuffer(this);
|
|
|
|
|
- zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
- sbtTextureIdBufferOffset,
|
|
|
|
|
- dynamic_cast<DX12Buffer*>(zModel->zTexture()->zTextureIndexBuffer())
|
|
|
|
|
- ->zBuffer()
|
|
|
|
|
- ->GetGPUVirtualAddress());
|
|
|
|
|
- zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
- sbtPolygonSizeBufferOffset,
|
|
|
|
|
- zBLAS->zPolygonSizeBuffer()->zBuffer()->GetGPUVirtualAddress());
|
|
|
|
|
|
|
+ int hitGroupOffset = zShaderBindingTable->addHitGroup(
|
|
|
|
|
+ defaultHitGroup, lastHitGroupIndex);
|
|
|
|
|
+ bool changed = hitGroupOffset != lastHitGroupIndex;
|
|
|
|
|
+ lastHitGroupIndex = hitGroupOffset;
|
|
|
|
|
+ if (changed)
|
|
|
|
|
+ { // TODO: check if the buffers are valid and have been recreated
|
|
|
|
|
+ zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
+ sbtIndexBufferOffset,
|
|
|
|
|
+ zBLAS->zIndexBuffer()->zBuffer()->GetGPUVirtualAddress());
|
|
|
|
|
+ zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
+ sbtVertexDataBufferOffset,
|
|
|
|
|
+ zBLAS->zVertexDataBuffer()->zBuffer()->GetGPUVirtualAddress());
|
|
|
|
|
+ zModel->zTexture()->updateTextureIndexBuffer(this);
|
|
|
|
|
+ zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
+ sbtTextureIdBufferOffset,
|
|
|
|
|
+ dynamic_cast<DX12Buffer*>(
|
|
|
|
|
+ zModel->zTexture()->zTextureIndexBuffer())
|
|
|
|
|
+ ->zBuffer()
|
|
|
|
|
+ ->GetGPUVirtualAddress());
|
|
|
|
|
+ zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
|
|
|
|
|
+ sbtPolygonSizeBufferOffset,
|
|
|
|
|
+ zBLAS->zPolygonSizeBuffer()->zBuffer()->GetGPUVirtualAddress());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1008,6 +1078,10 @@ void DirectX12::presentFrame()
|
|
|
|
|
|
|
|
swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
|
swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
|
|
|
|
|
|
|
|
|
+ globalDescriptorHeap->setHeapChanged(0);
|
|
|
|
|
+ textureDescriptorHeap->setHeapChanged(0);
|
|
|
|
|
+ samplerDescriptorHeap->setHeapChanged(0);
|
|
|
|
|
+
|
|
|
backBufferIndex = swapChain->GetCurrentBackBufferIndex();
|
|
backBufferIndex = swapChain->GetCurrentBackBufferIndex();
|
|
|
|
|
|
|
|
cs.unlock();
|
|
cs.unlock();
|