Explorar el Código

fix crashes when new objects are added to the world

Kolja Strohm hace 3 semanas
padre
commit
89895d6ea1
Se han modificado 8 ficheros con 106 adiciones y 82 borrados
  1. 1 1
      DX12GraphicsApi.cpp
  2. 7 3
      DX12Shader.cpp
  3. 51 16
      DX12TLAS.cpp
  4. 5 1
      DX12TLAS.h
  5. 2 40
      DX12Texture.cpp
  6. 23 20
      Framework Tests/Camera3D.cpp
  7. 12 1
      Texture.cpp
  8. 5 0
      Texture.h

+ 1 - 1
DX12GraphicsApi.cpp

@@ -213,7 +213,7 @@ void Framework::DirectX12::renderKamera(
             desc->InstanceID = objectIndex;
             desc->InstanceID = objectIndex;
             desc->InstanceContributionToHitGroupIndex = objectIndex;
             desc->InstanceContributionToHitGroupIndex = objectIndex;
             desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
             desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
-            desc->InstanceMask = 0xFF;
+            desc->InstanceMask = 0xFF * (obj->getSize() > 0);
             desc->AccelerationStructure
             desc->AccelerationStructure
                 = blas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress();
                 = blas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress();
             memcpy(desc->Transform,
             memcpy(desc->Transform,

+ 7 - 3
DX12Shader.cpp

@@ -1082,8 +1082,10 @@ void Framework::DX12GlobalDescriptorHeap::updateTextureInput(
 {
 {
     DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
     DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
     if (registerInputs.get(heapIndex)->inputResource
     if (registerInputs.get(heapIndex)->inputResource
-        != dynamic_cast<ReferenceCounter*>(zTexture))
+            != dynamic_cast<ReferenceCounter*>(zTexture)
+        || zTexture->hasBufferChanged())
     {
     {
+        zTexture->setBufferChanged(0);
         if (input->registerType != type)
         if (input->registerType != type)
         {
         {
             Logging::error()
             Logging::error()
@@ -1158,8 +1160,10 @@ void Framework::DX12GlobalDescriptorHeap::updateTLASInput(
 {
 {
     DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
     DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
     if (registerInputs.get(heapIndex)->inputResource
     if (registerInputs.get(heapIndex)->inputResource
-        != dynamic_cast<ReferenceCounter*>(zTLAS))
+            != dynamic_cast<ReferenceCounter*>(zTLAS)
+        || zTLAS->hasBufferChanged())
     {
     {
+        zTLAS->setBufferChanged(0);
         if (input->registerType != type)
         if (input->registerType != type)
         {
         {
             Logging::error()
             Logging::error()
@@ -1492,7 +1496,6 @@ void Framework::DX12ShaderBindingTable::startUpdate()
         {
         {
             hitGroupRecordSize = signature->gerShaderBindingTableParamCount();
             hitGroupRecordSize = signature->gerShaderBindingTableParamCount();
         }
         }
-        hitGroupCount++;
     }
     }
     hitGroupRecordSize = ROUND_UP_POWER_OF_2(
     hitGroupRecordSize = ROUND_UP_POWER_OF_2(
         D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + hitGroupRecordSize * 8,
         D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + hitGroupRecordSize * 8,
@@ -1602,6 +1605,7 @@ int Framework::DX12ShaderBindingTable::addHitGroup(
             &gpuAddress.ptr,
             &gpuAddress.ptr,
             sizeof(__int64));
             sizeof(__int64));
     }
     }
+    hitGroupCount++;
     nextHitGroupOffset += hitGroupRecordSize;
     nextHitGroupOffset += hitGroupRecordSize;
     return index + D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
     return index + D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
 }
 }

+ 51 - 16
DX12TLAS.cpp

@@ -1,6 +1,7 @@
 #include "DX12TLAS.h"
 #include "DX12TLAS.h"
 
 
 #include "DX12CommandQueue.h"
 #include "DX12CommandQueue.h"
+#include "Logging.h"
 
 
 Framework::DX12TLAS::DX12TLAS(
 Framework::DX12TLAS::DX12TLAS(
     ID3D12Device5* zDevice, Framework::DX12DirectCommandQueue* zDirectQueue)
     ID3D12Device5* zDevice, Framework::DX12DirectCommandQueue* zDirectQueue)
@@ -8,13 +9,15 @@ Framework::DX12TLAS::DX12TLAS(
       scratchBuffer(0),
       scratchBuffer(0),
       resultBuffer(0),
       resultBuffer(0),
       descriptorBuffer(0),
       descriptorBuffer(0),
-      previousResultBuffer(0),
       zDevice(zDevice),
       zDevice(zDevice),
       zDirectQueue(zDirectQueue),
       zDirectQueue(zDirectQueue),
       overflowInstanceIterator(0, 0, 0, 0),
       overflowInstanceIterator(0, 0, 0, 0),
       currentInstanceIndex(0),
       currentInstanceIndex(0),
       lastInstanceCount(0),
       lastInstanceCount(0),
-      mappedDescriptorBuffer(0)
+      mappedDescriptorBuffer(0),
+      lastResultBuffer(0),
+      lastScratchBuffer(0),
+      bufferChanged(0)
 {}
 {}
 
 
 Framework::DX12TLAS::~DX12TLAS()
 Framework::DX12TLAS::~DX12TLAS()
@@ -31,9 +34,13 @@ Framework::DX12TLAS::~DX12TLAS()
     {
     {
         descriptorBuffer->release();
         descriptorBuffer->release();
     }
     }
-    if (previousResultBuffer)
+    if (lastResultBuffer)
     {
     {
-        previousResultBuffer->release();
+        lastResultBuffer->Release();
+    }
+    if (lastScratchBuffer)
+    {
+        lastScratchBuffer->Release();
     }
     }
     for (const D3D12_RAYTRACING_INSTANCE_DESC* desc : overflowInstanceDescs)
     for (const D3D12_RAYTRACING_INSTANCE_DESC* desc : overflowInstanceDescs)
     {
     {
@@ -115,18 +122,22 @@ void Framework::DX12TLAS::endUpdate()
             &prebuildDesc, &info);
             &prebuildDesc, &info);
 
 
         // create new buffers witch fit the TLAS
         // create new buffers witch fit the TLAS
-        if (resultBuffer)
+        if (scratchBuffer)
         {
         {
-            if (previousResultBuffer)
+            if (lastScratchBuffer)
             {
             {
-                previousResultBuffer->release();
+                lastScratchBuffer->Release();
             }
             }
-            previousResultBuffer = resultBuffer;
+            lastScratchBuffer = scratchBuffer->zBuffer();
+            lastScratchBuffer->AddRef();
+        }
+        if (!resultBuffer)
+        {
+            resultBuffer = new DX12Buffer(1,
+                zDevice,
+                dynamic_cast<DX12CommandQueue*>(zDirectQueue->getThis()),
+                D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
         }
         }
-        resultBuffer = new DX12Buffer(1,
-            zDevice,
-            dynamic_cast<DX12CommandQueue*>(zDirectQueue->getThis()),
-            D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
         resultBuffer->setLength(
         resultBuffer->setLength(
             ROUND_UP_POWER_OF_2(info.ResultDataMaxSizeInBytes, 256));
             ROUND_UP_POWER_OF_2(info.ResultDataMaxSizeInBytes, 256));
         resultBuffer->createBufferWithoutData(
         resultBuffer->createBufferWithoutData(
@@ -175,7 +186,8 @@ void Framework::DX12TLAS::endUpdate()
         {
         {
             memcpy(newMappedDescriptorBuffer,
             memcpy(newMappedDescriptorBuffer,
                 mappedDescriptorBuffer,
                 mappedDescriptorBuffer,
-                oldDescriptorBufferElementCount);
+                oldDescriptorBufferElementCount
+                    * sizeof(D3D12_RAYTRACING_INSTANCE_DESC));
             D3D12_RANGE range = {0, 0}; // do not write to the old buffer
             D3D12_RANGE range = {0, 0}; // do not write to the old buffer
             oldDescriptorBuffer->Unmap(0, &range);
             oldDescriptorBuffer->Unmap(0, &range);
             oldDescriptorBuffer->Release();
             oldDescriptorBuffer->Release();
@@ -191,6 +203,19 @@ void Framework::DX12TLAS::endUpdate()
             overflowInstanceIterator++;
             overflowInstanceIterator++;
         }
         }
         descriptorBuffer->zBuffer()->Unmap(0, nullptr);
         descriptorBuffer->zBuffer()->Unmap(0, nullptr);
+        bufferChanged = 1;
+    }
+    else
+    {
+        if (resultBuffer)
+        {
+            if (lastResultBuffer)
+            {
+                lastResultBuffer->Release();
+            }
+            lastResultBuffer = resultBuffer->zBuffer();
+            lastResultBuffer->AddRef();
+        }
     }
     }
     D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc = {};
     D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc = {};
     buildDesc.Inputs.Type
     buildDesc.Inputs.Type
@@ -204,11 +229,11 @@ void Framework::DX12TLAS::endUpdate()
     buildDesc.ScratchAccelerationStructureData
     buildDesc.ScratchAccelerationStructureData
         = {scratchBuffer->zBuffer()->GetGPUVirtualAddress()};
         = {scratchBuffer->zBuffer()->GetGPUVirtualAddress()};
     buildDesc.SourceAccelerationStructureData
     buildDesc.SourceAccelerationStructureData
-        = previousResultBuffer
-            ? previousResultBuffer->zBuffer()->GetGPUVirtualAddress()
+        = lastResultBuffer && currentInstanceIndex < lastInstanceCount
+            ? lastResultBuffer->GetGPUVirtualAddress()
             : 0;
             : 0;
     buildDesc.Inputs.Flags
     buildDesc.Inputs.Flags
-        = previousResultBuffer
+        = lastResultBuffer && currentInstanceIndex < lastInstanceCount
             ? D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE
             ? D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE
             : D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
             : D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
 
 
@@ -231,3 +256,13 @@ Framework::DX12Buffer* Framework::DX12TLAS::zResultBuffer() const
 {
 {
     return resultBuffer;
     return resultBuffer;
 }
 }
+
+bool Framework::DX12TLAS::hasBufferChanged() const
+{
+    return bufferChanged;
+}
+
+void Framework::DX12TLAS::setBufferChanged(bool changed)
+{
+    bufferChanged = changed;
+}

+ 5 - 1
DX12TLAS.h

@@ -13,7 +13,6 @@ namespace Framework
         DX12Buffer* scratchBuffer;
         DX12Buffer* scratchBuffer;
         DX12Buffer* resultBuffer;
         DX12Buffer* resultBuffer;
         DX12Buffer* descriptorBuffer;
         DX12Buffer* descriptorBuffer;
-        DX12Buffer* previousResultBuffer;
         ID3D12Device5* zDevice;
         ID3D12Device5* zDevice;
         DX12DirectCommandQueue* zDirectQueue;
         DX12DirectCommandQueue* zDirectQueue;
         Array<D3D12_RAYTRACING_INSTANCE_DESC*> overflowInstanceDescs;
         Array<D3D12_RAYTRACING_INSTANCE_DESC*> overflowInstanceDescs;
@@ -21,6 +20,9 @@ namespace Framework
         __int64 currentInstanceIndex;
         __int64 currentInstanceIndex;
         __int64 lastInstanceCount;
         __int64 lastInstanceCount;
         D3D12_RAYTRACING_INSTANCE_DESC* mappedDescriptorBuffer;
         D3D12_RAYTRACING_INSTANCE_DESC* mappedDescriptorBuffer;
+        ID3D12Resource* lastResultBuffer;
+        ID3D12Resource* lastScratchBuffer;
+        bool bufferChanged;
 
 
     public:
     public:
         DLLEXPORT DX12TLAS(
         DLLEXPORT DX12TLAS(
@@ -30,5 +32,7 @@ namespace Framework
         DLLEXPORT D3D12_RAYTRACING_INSTANCE_DESC* nextInstanceDesc();
         DLLEXPORT D3D12_RAYTRACING_INSTANCE_DESC* nextInstanceDesc();
         DLLEXPORT void endUpdate();
         DLLEXPORT void endUpdate();
         DLLEXPORT DX12Buffer* zResultBuffer() const;
         DLLEXPORT DX12Buffer* zResultBuffer() const;
+        DLLEXPORT bool hasBufferChanged() const;
+        DLLEXPORT void setBufferChanged(bool changed);
     };
     };
 } // namespace Framework
 } // namespace Framework

+ 2 - 40
DX12Texture.cpp

@@ -56,6 +56,7 @@ bool DX12Texture::updateTextur()
             0,
             0,
             __uuidof(ID3D12Resource),
             __uuidof(ID3D12Resource),
             (void**)&buffer);
             (void**)&buffer);
+        bufferChanged = 1;
         if (getDirection() == RAM_TO_GPU)
         if (getDirection() == RAM_TO_GPU)
         {
         {
             const UINT64 uploadBufferSize
             const UINT64 uploadBufferSize
@@ -95,46 +96,7 @@ bool DX12Texture::updateTextur()
         UpdateSubresources(
         UpdateSubresources(
             direct->zCommandList(), buffer, upload, 0, 0, 1, &textureData);
             direct->zCommandList(), buffer, upload, 0, 0, 1, &textureData);
     }
     }
-    /* if (bild && (changed || bild->getNeedRender()))
-    {
-            changed = 0;
-        if (shaderResource)
-        {
-            D3D12_RESOURCE_BARRIER barrier;
-            barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
-            barrier.Transition.pResource = buffer;
-            barrier.Transition.StateBefore
-                = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
-                | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
-            barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
-            barrier.Transition.Subresource = 0;
-            barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
-            direct->zCommandList()->ResourceBarrier(1, &barrier);
-            shaderResource = 0;
-        }
-        D3D12_SUBRESOURCE_DATA textureData = {};
-        textureData.pData = bild->getBuffer();
-        textureData.RowPitch = bild->getWidth() * sizeof(int);
-        textureData.SlicePitch = textureData.RowPitch * bild->getHeight();
-        UpdateSubresources(direct->zCommandList(),
-            buffer,
-            intermediate,
-            0,
-            0,
-            1,
-            &textureData);
-        D3D12_RESOURCE_BARRIER barrier;
-        barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
-        barrier.Transition.pResource = buffer;
-        barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
-        barrier.Transition.StateAfter
-            = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
-            | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
-        barrier.Transition.Subresource = 0;
-        barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
-        direct->zCommandList()->ResourceBarrier(1, &barrier);
-        shaderResource = 1;
-    }*/
+    // TODO: Implement GPU_TO_RAM direction
 #endif
 #endif
     return 1;
     return 1;
 }
 }

+ 23 - 20
Framework Tests/Camera3D.cpp

@@ -48,6 +48,8 @@ namespace FrameworkTests
         TEST_METHOD (TestRaytracing)
         TEST_METHOD (TestRaytracing)
         {
         {
             Framework::initFramework();
             Framework::initFramework();
+            Framework::Logging::zLoggingHandler()->addChannel(
+                new Framework::Logging::OutputDebugStringLoggingChannel());
             Framework::setDebugDX(1);
             Framework::setDebugDX(1);
             Framework::NativeWindow window;
             Framework::NativeWindow window;
             WNDCLASS wc = Framework::F_Normal(GetModuleHandle(0));
             WNDCLASS wc = Framework::F_Normal(GetModuleHandle(0));
@@ -248,7 +250,7 @@ namespace FrameworkTests
                       world.addDrawable(cube);
                       world.addDrawable(cube);
                       cubes.add(cube);
                       cubes.add(cube);
                   };
                   };
-            for (int i = 0; i < 10000; i++)
+            for (int i = 0; i < 10; i++)
             {
             {
                 addCube(rand() % 1000 - 500,
                 addCube(rand() % 1000 - 500,
                     rand() % 1000 - 500,
                     rand() % 1000 - 500,
@@ -269,25 +271,26 @@ namespace FrameworkTests
             rTh.setMaxFps(-1);
             rTh.setMaxFps(-1);
             rTh.setScreen(dynamic_cast<Framework::Screen*>(screen.getThis()));
             rTh.setScreen(dynamic_cast<Framework::Screen*>(screen.getThis()));
             double sum = 0;
             double sum = 0;
-            rTh.setTickFunktion(
-                [&cubes, &sum, &addCube](void* p, void* f, double tick) {
-                    for (Framework::Model3D* cube : cubes)
-                    {
-                        cube->setRotationX(cube->getXRotation() + tick * 2);
-                        cube->setRotationY(cube->getXRotation() + tick / 5);
-                        cube->setRotationZ(cube->getXRotation() + tick / 25);
-                        cube->setSize(
-                            cube->getSize() + tick * 5 * (sum > 2.5 ? 1 : -1));
-                    }
-                    sum += tick;
-                    if (sum > 5)
-                    {
-                        sum -= 5;
-                        /* addCube(rand() % 1000 - 500,
-                            rand() % 1000 - 500,
-                            rand() % 1000 - 500);*/
-                    }
-                });
+            rTh.setTickFunktion([&cubes, &sum, &addCube, &api, &screen](
+                                    void* p, void* f, double tick) {
+                for (Framework::Model3D* cube : cubes)
+                {
+                    cube->setRotationX(cube->getXRotation() + tick * 2);
+                    cube->setRotationY(cube->getXRotation() + tick / 5);
+                    cube->setRotationZ(cube->getXRotation() + tick / 25);
+                    cube->setSize(
+                        cube->getSize() + tick * 5 * (sum > 2.5 ? 1 : -1));
+                }
+                sum += tick;
+                if (sum > 10)
+                {
+                    sum -= 10;
+                    screen.render();
+                    addCube(rand() % 1000 - 500,
+                        rand() % 1000 - 500,
+                        rand() % 1000 - 500);
+                }
+            });
 
 
             rTh.beginn();
             rTh.beginn();
             Framework::StartMessageLoop();
             Framework::StartMessageLoop();

+ 12 - 1
Texture.cpp

@@ -7,7 +7,8 @@ using namespace Framework;
 // Constructor
 // Constructor
 Texture::Texture(TextureDirection dir)
 Texture::Texture(TextureDirection dir)
     : ReferenceCounter(),
     : ReferenceCounter(),
-      direction(dir)
+      direction(dir),
+      bufferChanged(0)
 {
 {
     bild = 0;
     bild = 0;
     lastGr = Point(0, 0);
     lastGr = Point(0, 0);
@@ -69,3 +70,13 @@ TextureDirection Framework::Texture::getDirection() const
 {
 {
     return direction;
     return direction;
 }
 }
+
+bool Framework::Texture::hasBufferChanged() const
+{
+    return bufferChanged;
+}
+
+void Framework::Texture::setBufferChanged(bool changed)
+{
+    bufferChanged = changed;
+}

+ 5 - 0
Texture.h

@@ -27,6 +27,7 @@ namespace Framework
         Point lastGr;
         Point lastGr;
         int id;
         int id;
         TextureDirection direction;
         TextureDirection direction;
+        bool bufferChanged;
 
 
     public:
     public:
         //! Constructor
         //! Constructor
@@ -53,6 +54,10 @@ namespace Framework
         DLLEXPORT int getId() const;
         DLLEXPORT int getId() const;
         //! Returns the direction of the texture
         //! Returns the direction of the texture
         DLLEXPORT TextureDirection getDirection() const;
         DLLEXPORT TextureDirection getDirection() const;
+        //! Returns true if the texture has changed since the last update
+        DLLEXPORT bool hasBufferChanged() const;
+        // Sets whether the texture has changed since the last update
+        DLLEXPORT void setBufferChanged(bool changed);
 
 
         friend TextureList;
         friend TextureList;
     };
     };