Sfoglia il codice sorgente

actually use raytracing in the default RayGen shader

Kolja Strohm 3 settimane fa
parent
commit
2c4bf53892
15 ha cambiato i file con 279 aggiunte e 81 eliminazioni
  1. 1 1
      Array.h
  2. 13 1
      Camera3D.cpp
  3. 11 4
      Camera3D.h
  4. 1 0
      DX11GraphicsApi.cpp
  5. 10 10
      DX12BLAS.cpp
  6. 2 0
      DX12BLASModel.cpp
  7. 1 1
      DX12CommandQueue.cpp
  8. 81 32
      DX12GraphicsApi.cpp
  9. 14 3
      DX12GraphicsApi.h
  10. 79 16
      DX12Shader.cpp
  11. 2 0
      DX12Shader.h
  12. 2 4
      DX12TLAS.cpp
  13. 14 0
      Model3D.cpp
  14. 3 0
      Model3D.h
  15. 45 9
      RayGen.hlsl

+ 1 - 1
Array.h

@@ -156,7 +156,7 @@ namespace Framework
 
         operator bool() override
         {
-            return current != 0;
+            return current != 0 && current->set;
         }
 
         ArrayIterator<TYP>& operator++() override //! prefix

+ 13 - 1
Camera3D.cpp

@@ -4,9 +4,9 @@
 #include <DirectXMath.h>
 
 #include "Globals.h"
+#include "KeyboardEvent.h"
 #include "MouseEvent.h"
 #include "Shader.h"
-#include "KeyboardEvent.h"
 #include "World3D.h"
 
 using namespace Framework;
@@ -52,8 +52,10 @@ void Cam3D::updateMatrix()
 {
     view = view.rotationX(-rotX) * view.rotationY(-rotY) * view.rotationZ(-rotZ)
          * view.translation(Vec3<float>(-pos.x, -pos.y, -pos.z));
+    inverseView = view.getInverse();
     proj = proj.projektion(
         openingAngle, viewport.width / viewport.height, minZ, maxZ);
+    inverseProj = proj.getInverse();
 }
 
 // Sets the position of the camera in the 3D world
@@ -394,6 +396,16 @@ const Mat4<float>& Cam3D::getViewMatrix() const
     return view;
 }
 
+const Mat4<float>& Framework::Cam3D::getInverseViewMatrix() const
+{
+    return inverseView;
+}
+
+const Mat4<float>& Framework::Cam3D::getInverseProjectionMatrix() const
+{
+    return inverseProj;
+}
+
 //! Returns the rotation around each axis
 const Vec3<float> Cam3D::getRotation() const
 {

+ 11 - 4
Camera3D.h

@@ -1,8 +1,8 @@
 #pragma once
 
+#include "Drawing3D.h"
 #include "Mat4.h"
 #include "Point.h"
-#include "Drawing3D.h"
 
 //! DirectX 11 Types
 
@@ -11,8 +11,8 @@ struct D3D11_VIEWPORT;
 namespace Framework
 {
     struct MouseEvent; //! MouseEvent.h
-    class Render3D;      //! Render3D.h
-    class World3D;        //! World3D.h
+    class Render3D;    //! Render3D.h
+    class World3D;     //! World3D.h
 
     struct ViewPort
     {
@@ -44,6 +44,8 @@ namespace Framework
     private:
         Mat4<float> view;
         Mat4<float> proj;
+        Mat4<float> inverseView;
+        Mat4<float> inverseProj;
 
         float openingAngle;
         float minZ;
@@ -116,7 +118,8 @@ namespace Framework
         DLLEXPORT void setMovementSpeed(float speed);
         //! Processes elapsed time
         //! \param tickval The time in seconds since the last call of this
-        //! function \return true if the image needs to be redrawn, false otherwise.
+        //! function \return true if the image needs to be redrawn, false
+        //! otherwise.
         DLLEXPORT virtual bool tick(double tv);
         //! Processes a mouse event
         //! \param me The mouse event to process
@@ -146,6 +149,10 @@ namespace Framework
         DLLEXPORT const Mat4<float>& getProjectionMatrix() const;
         //! Returns the view matrix of the camera
         DLLEXPORT const Mat4<float>& getViewMatrix() const;
+        //! Returns the inverse view matrix of the camera
+        DLLEXPORT const Mat4<float>& getInverseViewMatrix() const;
+        //! Returns the inverse projection matrix of the camera
+        DLLEXPORT const Mat4<float>& getInverseProjectionMatrix() const;
         //! Returns the rotation around individual axes
         DLLEXPORT const Vec3<float> getRotation() const;
         //! Returns the position of the camera on the screen

+ 1 - 0
DX11GraphicsApi.cpp

@@ -1223,6 +1223,7 @@ DXBuffer* DirectX11::createStructuredBuffer(int eSize)
 Model3DData* DirectX11::createModel(const char* name)
 {
     Model3DData* result = GraphicsApi::createModel(name);
+    lastModelId = result->getId();
     if (result)
     {
         DX11Buffer** newIndexBuffers = new DX11Buffer*[lastModelId + 1];

+ 10 - 10
DX12BLAS.cpp

@@ -6,8 +6,14 @@
 Framework::DX12BLAS::DX12BLAS(
     ID3D12Device5* zDevice, DX12DirectCommandQueue* zDirectQueue)
     : ReferenceCounter(),
-      scratchBuffer(0),
-      resultBuffer(0),
+      scratchBuffer(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)),
       zDevice(zDevice),
       zDirectQueue(zDirectQueue),
       geometryDesc(new D3D12_RAYTRACING_GEOMETRY_DESC())
@@ -15,14 +21,8 @@ Framework::DX12BLAS::DX12BLAS(
 
 Framework::DX12BLAS::~DX12BLAS()
 {
-    if (scratchBuffer)
-    {
-        scratchBuffer->release();
-    }
-    if (resultBuffer)
-    {
-        resultBuffer->release();
-    }
+    scratchBuffer->release();
+    resultBuffer->release();
     delete geometryDesc;
 }
 

+ 2 - 0
DX12BLASModel.cpp

@@ -38,6 +38,7 @@ void Framework::DX12BLASModel::calculateBuffers()
     {
         return;
     }
+    zModelData->lock();
     Skeleton* skeleton = zModelData->zSkeleton();
     const Vertex3D* vertexBuffer = zModelData->zVertexBuffer();
     const int* indexBuffer = zModelData->getIndexBuffer();
@@ -158,6 +159,7 @@ void Framework::DX12BLASModel::calculateBuffers()
     delete[] boneVertexCount;
     delete[] boneIndexBuffers;
     delete[] boneIndexCount;
+    zModelData->unlock();
 }
 
 int Framework::DX12BLASModel::getBufferCount() const

+ 1 - 1
DX12CommandQueue.cpp

@@ -18,7 +18,7 @@ DX12CommandQueue::DX12CommandQueue(int typ, ID3D12Device* zDevice)
     D3D12_COMMAND_QUEUE_DESC desc = {};
     desc.Type = (D3D12_COMMAND_LIST_TYPE)typ;
     desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
-    desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+    desc.Flags = D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT;
     desc.NodeMask = 0;
     HRESULT res = zDevice->CreateCommandQueue(
         &desc, __uuidof(ID3D12CommandQueue), (void**)&queue);

+ 81 - 32
DX12GraphicsApi.cpp

@@ -36,8 +36,6 @@ DirectX12::DirectX12()
       swapChain(0),
       backBufferIndex(0),
       tearing(0),
-      viewPort(0),
-      allowedRenderArea(0),
       signature(0),
       uiTexture(0),
       texturRegister(new TextureList()),
@@ -49,13 +47,13 @@ DirectX12::DirectX12()
       defaultRenderTarget(0),
       defaultKamera(0),
       cameraCount(0),
+      rayGenSettingsBuffer(0),
       device(0),
       pfnD3D12SerializeRootSignature(0),
       pipeline(0),
       globalDescriptorHeap(0),
       defaultHitGroup(0),
-      defaultRayGenerationShaderFunction(0),
-      tlasInputOffset(0)
+      defaultRayGenerationShaderFunction(0)
 {
     for (int i = 0; i < 2; i++)
         backBuffer[i] = 0;
@@ -101,13 +99,15 @@ DirectX12::~DirectX12()
         directCommandQueue->flush();
         directCommandQueue->release();
     }
+    if (rayGenSettingsBuffer)
+    {
+        rayGenSettingsBuffer->release();
+    }
     texturRegister->release();
     if (uiTexture) uiTexture->release();
     if (defaultKamera) defaultKamera->release();
     if (defaultRenderTarget) defaultRenderTarget->release();
     if (signature) signature->Release();
-    delete allowedRenderArea;
-    delete viewPort;
     for (int i = 0; i < 2; i++)
     {
         if (backBuffer[i]) backBuffer[i]->Release();
@@ -125,6 +125,7 @@ DirectX12::~DirectX12()
 
 void DirectX12::updateBottomLevelAccelerationStructure()
 {
+    cs.lock();
     bool updateRequired = 0;
     for (const Model3DData* model : *modelList->zModels())
     {
@@ -143,16 +144,14 @@ void DirectX12::updateBottomLevelAccelerationStructure()
             blasModels[id]->calculateBuffers();
             bufferCount += blasModels[id]->getBufferCount();
         }
-        directCommandQueue
-            ->execute(); // TODO: check if this is realy necessary
-                         // here, because maybe the command list is
-                         // executed in the render function anyway
     }
+    cs.unlock();
 }
 
 void Framework::DirectX12::renderKamera(
     Cam3D* zKamera, DX12Texture* zTarget, bool guiVisible)
 {
+    updateBottomLevelAccelerationStructure();
     if (guiVisible)
     {
         uiTexture->updateTextur();
@@ -166,7 +165,6 @@ void Framework::DirectX12::renderKamera(
     Mat4<float> identity = Mat4<float>::identity();
 
     World3D* w = zKamera->zWorld();
-
     if (w->getId() < 0)
     {
         w->setId(++lastTLASId);
@@ -207,6 +205,7 @@ void Framework::DirectX12::renderKamera(
         obj->calculateMatrices(identity, matrixBuffer);
         int modelId = obj->zModelData()->getId();
         DX12BLASModel* blasModel = blasModels[modelId];
+        blasModel->calculateBuffers();
         ArrayIterator<int> boneIds = blasModel->zBoneIds()->begin();
         for (const DX12BLAS* blas : *blasModel->zBLAS())
         {
@@ -227,13 +226,20 @@ void Framework::DirectX12::renderKamera(
         objectIndex++;
     });
     tlas->endUpdate();
+    settings.inverseProjection = zKamera->getInverseProjectionMatrix();
+    settings.inverseView = zKamera->getInverseViewMatrix();
+    settings.minDistance = zKamera->zViewPort()->front;
+    settings.maxDistance = zKamera->zViewPort()->back;
+    settings.useRays = 1;
+    settings.renderGui = (int)guiVisible;
+    rayGenSettingsBuffer->setData(&settings, 1);
+    rayGenSettingsBuffer->copyToGPU(sizeof(settings));
     if (defaultRayGenerationShaderFunction)
     {
         globalDescriptorHeap->updateTextureInput(
             0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, zTarget);
-        sbt->setShaderInput(defaultRayGenerationShaderFunction,
-            tlasInputOffset,
-            tlas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress());
+        globalDescriptorHeap->updateTLASInput(
+            3, DX12_SHADER_REGISTER_T_SHADER_RESOURCE, tlas);
     }
     sbt->setGlobalDescriptorHeap(dynamic_cast<DX12GlobalDescriptorHeap*>(
         globalDescriptorHeap->getThis()));
@@ -264,9 +270,10 @@ void Framework::DirectX12::initializePipeline()
             0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 0);
         rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
             1, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 1);
-        tlasInputOffset
-            = rayGenSignature->addRegisterUsageLinkedToShaderBindingTable(
-                DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 0);
+        rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
+            2, DX12_SHADER_REGISTER_B_CONST_BUFFER, 0);
+        rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
+            3, DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 0);
         defaultRayGenerationShaderFunction = new DX12ShaderFunction(
             "RayGen", rayGenSignature, DX12_SHADER_FUNCTION_TYPE_RAY_GEN);
         rayGenShader->addFunction(defaultRayGenerationShaderFunction);
@@ -294,6 +301,8 @@ void Framework::DirectX12::initializePipeline()
         defaultHitGroup->setPayloadSize(16);
         defaultHitGroup->setClosestHitShaderFunction(closestHitFunction);
         pipeline->addHitGroup(defaultHitGroup);
+
+        pipeline->setMaxRecursionDepth(10);
     }
     pipeline->createPipelineState(device, pfnD3D12SerializeRootSignature);
 }
@@ -304,6 +313,10 @@ void Framework::DirectX12::initializeGlobalDescriptorHeap()
         DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, defaultRenderTarget);
     globalDescriptorHeap->addTextureInput(
         DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, uiTexture);
+    globalDescriptorHeap->addBufferInput(
+        DX12_SHADER_REGISTER_B_CONST_BUFFER, rayGenSettingsBuffer);
+    globalDescriptorHeap->addTLASInput(
+        DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 0);
 
     globalDescriptorHeap->updateDescriptorHeap(device);
 }
@@ -334,6 +347,15 @@ void DirectX12::initialize(
 {
     GraphicsApi::initialize(fenster, backBufferSize, fullScreen);
 
+#ifdef _DEBUG
+    if (debugDX)
+    {
+        HINSTANCE pixDebugger = getDLLRegister()->loadDLL(
+            "WinPixGpuCapturer.dll",
+            "C:\\Program Files\\Microsoft PIX\\2603.25\\WinPixGpuCapturer.dll");
+    }
+#endif
+
     HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
     if (!dxgiDLL)
     {
@@ -572,6 +594,19 @@ void DirectX12::initialize(
 
     directCommandQueue = new DX12DirectCommandQueue(device);
 
+    settings.minDistance = 0.0f;
+    settings.maxDistance = 100000.f;
+    settings.renderGui = 0;
+    settings.useRays = 0;
+    rayGenSettingsBuffer = new DX12Buffer(1,
+        device,
+        dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
+        D3D12_RESOURCE_FLAG_NONE);
+    rayGenSettingsBuffer->setLength(
+        ROUND_UP_POWER_OF_2(sizeof(RayGenerationSettings), 256));
+    rayGenSettingsBuffer->setData(&settings, 1);
+    rayGenSettingsBuffer->copyToGPU(sizeof(RayGenerationSettings));
+
     IDXGIFactory5* fac5 = 0;
     factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&fac5);
     if (fac5)
@@ -653,20 +688,6 @@ void DirectX12::initialize(
         createOrGetTexture("_f_RenderTarget", renderTargetImage, GPU_TO_RAM));
     defaultRenderTarget->updateTextur();
 
-    viewPort = new D3D12_VIEWPORT();
-    viewPort->Width = (float)this->backBufferSize.x;
-    viewPort->Height = (float)this->backBufferSize.y;
-    viewPort->MinDepth = 0.0f;
-    viewPort->MaxDepth = 1.0f;
-    viewPort->TopLeftX = 0.0f;
-    viewPort->TopLeftY = 0.0f;
-
-    allowedRenderArea = new D3D12_RECT();
-    allowedRenderArea->left = 0;
-    allowedRenderArea->top = 0;
-    allowedRenderArea->right = LONG_MAX;
-    allowedRenderArea->bottom = LONG_MAX;
-
     Image* renderB = new Image(1);
     renderB->setAlpha3D(1);
     renderB->newImage(this->backBufferSize.x, this->backBufferSize.y, 0);
@@ -793,6 +814,7 @@ void DirectX12::initialize(
 
 void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor)
 {
+    cs.lock();
     cameraCount = 0;
     D3D12_RESOURCE_BARRIER barrier;
     ZeroMemory(&barrier, sizeof(barrier));
@@ -869,6 +891,8 @@ void DirectX12::presentFrame()
     swapChain->Present(0, 0);
 
     backBufferIndex = swapChain->GetCurrentBackBufferIndex();
+
+    cs.unlock();
 }
 
 Texture* DirectX12::createOrGetTexture(
@@ -885,11 +909,13 @@ Texture* DirectX12::createOrGetTexture(
         if (b) ret->setImageZ(b);
         return ret;
     }
+    cs.lock();
     Texture* ret = new DX12Texture(device, directCommandQueue, dir);
     if (b) ret->setImageZ(b);
     texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
     ret->updateTextur();
-    directCommandQueue->execute();
+    // directCommandQueue->execute();
+    cs.unlock();
     return ret;
 }
 
@@ -906,6 +932,29 @@ DXBuffer* DirectX12::createStructuredBuffer(int eSize)
         D3D12_RESOURCE_FLAG_NONE);
 }
 
+Model3DData* Framework::DirectX12::createModel(const char* name)
+{
+    cs.lock();
+    Model3DData* result = GraphicsApi::createModel(name);
+    lastModelId = result->getId();
+    if (result)
+    {
+        DX12BLASModel** newBlasModels = new DX12BLASModel*[lastModelId + 1];
+        if (lastModelId > 0)
+        {
+            memcpy(newBlasModels,
+                blasModels,
+                sizeof(DX12BLASModel*) * lastModelId);
+        }
+        newBlasModels[lastModelId]
+            = new DX12BLASModel(result, device, directCommandQueue);
+        delete[] blasModels;
+        blasModels = newBlasModels;
+    }
+    cs.unlock();
+    return result;
+}
+
 void Framework::DirectX12::setPipeline(DX12Pipeline* pipeline)
 {
     if (this->pipeline)

+ 14 - 3
DX12GraphicsApi.h

@@ -45,6 +45,16 @@ namespace Framework
     class DX12ShaderFunction;
     class Cam3D;
 
+    struct RayGenerationSettings
+    {
+        int renderGui;
+        int useRays;
+        float minDistance;
+        float maxDistance;
+        Mat4<float> inverseView;
+        Mat4<float> inverseProjection;
+    };
+
     class DirectX12 : public GraphicsApi
     {
     private:
@@ -55,8 +65,6 @@ namespace Framework
         ID3D12Resource* backBuffer[2];
         int backBufferIndex;
         int tearing;
-        D3D12_VIEWPORT* viewPort;
-        tagRECT* allowedRenderArea;
         ID3D12RootSignature* signature;
         Mat4<float> matrixBuffer[MAX_KNOCHEN_ANZ];
         Mat4<float> viewAndProj[2];
@@ -71,15 +79,17 @@ namespace Framework
         DX12Texture* defaultRenderTarget;
         Cam3D* defaultKamera;
         int cameraCount;
+        Critical cs;
 
     protected:
+        DX12Buffer* rayGenSettingsBuffer;
+        RayGenerationSettings settings;
         ID3D12Device5* device;
         PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature;
         DX12Pipeline* pipeline;
         DX12GlobalDescriptorHeap* globalDescriptorHeap;
         DX12ShaderHitGroup* defaultHitGroup;
         DX12ShaderFunction* defaultRayGenerationShaderFunction;
-        int* tlasInputOffset;
 
     public:
         DLLEXPORT DirectX12();
@@ -112,6 +122,7 @@ namespace Framework
             const char* name, Image* b, TextureDirection dir) override;
         DLLEXPORT Image* zUIRenderImage() const override;
         DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) override;
+        DLLEXPORT virtual Model3DData* createModel(const char* name);
         DLLEXPORT void setPipeline(DX12Pipeline* pipeline);
         DLLEXPORT static bool isAvailable();
         DLLEXPORT bool renderGuiBefore3D() const override;

+ 79 - 16
DX12Shader.cpp

@@ -121,7 +121,8 @@ void Framework::DX12ShaderSignature::addRegisterUsageLinkedToDescriptorHeap(
     }
     if (found)
     {
-        if (it->registerIndex == registerIndex)
+        if (it->registerIndex == registerIndex && it->spaceIndex == spaceIndex
+            && it->registerType == registerType)
         {
             Logging::error()
                 << "Duplicate register usage in root signature: "
@@ -957,14 +958,14 @@ void Framework::DX12Pipeline::createPipelineState(ID3D12Device5* zDevice,
         throw std::logic_error("Could not create the raytracing state object");
     }
 
-    delete[] functionAndHitGroupNames;
+    /* delete[] functionAndHitGroupNames;
     delete[] localRootSignatures;
     for (int i = 0; i < distinctSignatures.getEntryCount(); i++)
     {
         delete[] rootSignatureExports[i];
     }
     delete[] rootSignatureExports;
-    delete[] localRootAssociations;
+    delete[] localRootAssociations;*/
 }
 
 ID3D12StateObject* Framework::DX12Pipeline::zPipelineState() const
@@ -1066,8 +1067,8 @@ void Framework::DX12GlobalDescriptorHeap::addInput(
             break;
         }
     }
-    registerInputs.add(
-        new DX12ShaderRegisterInput{type, inputResource->getThis()});
+    registerInputs.add(new DX12ShaderRegisterInput{
+        type, inputResource ? inputResource->getThis() : 0});
 }
 
 void Framework::DX12GlobalDescriptorHeap::addTextureInput(
@@ -1152,6 +1153,58 @@ void Framework::DX12GlobalDescriptorHeap::addTLASInput(
     addInput(type, zTLAS);
 }
 
+void Framework::DX12GlobalDescriptorHeap::updateTLASInput(
+    int heapIndex, DX12ShaderRegister type, DX12TLAS* zTLAS)
+{
+    DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
+    if (registerInputs.get(heapIndex)->inputResource
+        != dynamic_cast<ReferenceCounter*>(zTLAS))
+    {
+        if (input->registerType != type)
+        {
+            Logging::error()
+                << "Register type mismatch for descriptor heap index "
+                << heapIndex
+                << ". Expected register type: " << input->registerType
+                << ", given register type: " << type << ".";
+            throw std::logic_error("Register type mismatch in descriptor heap");
+        }
+        if (registerInputs.get(heapIndex)->inputResource)
+        {
+            registerInputs.get(heapIndex)->inputResource->release();
+        }
+        registerInputs.get(heapIndex)->inputResource = zTLAS->getThis();
+        if (descriptorHeap)
+        {
+            D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
+                = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
+            descriptorHeapHandle.ptr
+                += zDevice->GetDescriptorHandleIncrementSize(
+                       D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
+                 * heapIndex;
+            switch (input->registerType)
+            {
+            case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
+                {
+                    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
+                    srvDesc.Format = DXGI_FORMAT_UNKNOWN;
+                    srvDesc.ViewDimension
+                        = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
+                    srvDesc.RaytracingAccelerationStructure.Location
+                        = zTLAS->zResultBuffer()
+                              ->zBuffer()
+                              ->GetGPUVirtualAddress();
+                    srvDesc.Shader4ComponentMapping
+                        = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+                    zDevice->CreateShaderResourceView(
+                        0, &srvDesc, descriptorHeapHandle);
+                    break;
+                }
+            }
+        }
+    }
+}
+
 void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
     ID3D12Device5* zDevice)
 {
@@ -1208,6 +1261,7 @@ void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
             {
                 D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
                 srvDesc.Format = DXGI_FORMAT_UNKNOWN;
+                bool doNothing = 0;
                 if (zTLAS)
                 {
                     srvDesc.ViewDimension
@@ -1235,13 +1289,20 @@ void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
                         = zBuffer->getElementLength();
                     srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
                 }
-                srvDesc.Shader4ComponentMapping
-                    = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
-                zDevice->CreateShaderResourceView(
-                    zTexture ? zTexture->zResource()
-                             : (zBuffer ? zBuffer->zBuffer() : 0),
-                    &srvDesc,
-                    descriptorHeapHandle);
+                else
+                {
+                    doNothing = 1;
+                }
+                if (!doNothing)
+                {
+                    srvDesc.Shader4ComponentMapping
+                        = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+                    zDevice->CreateShaderResourceView(
+                        zTexture ? zTexture->zResource()
+                                 : (zBuffer ? zBuffer->zBuffer() : 0),
+                        &srvDesc,
+                        descriptorHeapHandle);
+                }
                 break;
             }
         case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
@@ -1272,7 +1333,8 @@ void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
                            "register type "
                         << input->registerType;
                     throw std::logic_error(
-                        "Expected a texture or buffer resource for register "
+                        "Expected a texture or buffer resource for "
+                        "register "
                         "type "
                         + std::to_string(input->registerType));
                 }
@@ -1670,9 +1732,10 @@ void Framework::DX12ShaderBindingTable::fillDispatchRaysDesc(
     dispatchRaysDesc->CallableShaderTable.SizeInBytes
         = callableCount * callableRecordSize;
     dispatchRaysDesc->CallableShaderTable.StartAddress
-        = callableCount > 0 ? shaderBindingTableBuffer->zBuffer()
-              ->GetGPUVirtualAddress()
-        + rayGenCount * rayGenRecordSize + missCount * missRecordSize : 0;
+        = callableCount > 0
+            ? shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
+                  + rayGenCount * rayGenRecordSize + missCount * missRecordSize
+            : 0;
     dispatchRaysDesc->CallableShaderTable.StrideInBytes
         = callableCount > 0 ? callableRecordSize : 0;
 }

+ 2 - 0
DX12Shader.h

@@ -243,6 +243,8 @@ namespace Framework
         DLLEXPORT void addBufferInput(
             DX12ShaderRegister type, DXBuffer* zBuffer);
         DLLEXPORT void addTLASInput(DX12ShaderRegister type, DX12TLAS* zTLAS);
+        DLLEXPORT void updateTLASInput(
+            int heapIndex, DX12ShaderRegister type, DX12TLAS* zTLAS);
         DLLEXPORT void updateDescriptorHeap(ID3D12Device5* zDevice);
         DLLEXPORT DX12Pipeline* zPipeline() const;
         DLLEXPORT ID3D12DescriptorHeap* zDescriptorHeap() const;

+ 2 - 4
DX12TLAS.cpp

@@ -61,8 +61,7 @@ D3D12_RAYTRACING_INSTANCE_DESC* Framework::DX12TLAS::nextInstanceDesc()
     if (mappedDescriptorBuffer
         && currentInstanceIndex < descriptorBuffer->getElementCount())
     {
-        return mappedDescriptorBuffer
-             + currentInstanceIndex * sizeof(D3D12_RAYTRACING_INSTANCE_DESC);
+        return mappedDescriptorBuffer + currentInstanceIndex;
     }
     else if (overflowInstanceIterator)
     {
@@ -178,8 +177,7 @@ void Framework::DX12TLAS::endUpdate()
         {
             memcpy(newMappedDescriptorBuffer,
                 mappedDescriptorBuffer,
-                oldDescriptorBufferElementCount
-                    * sizeof(D3D12_RAYTRACING_INSTANCE_DESC));
+                oldDescriptorBufferElementCount);
             D3D12_RANGE range = {0, 0}; // do not write to the old buffer
             oldDescriptorBuffer->Unmap(0, &range);
             oldDescriptorBuffer->Release();

+ 14 - 0
Model3D.cpp

@@ -381,6 +381,7 @@ void Model3DData::calculateNormals()
 //! Creates a buffer for all polygon indices
 void Model3DData::buildIndexBuffer()
 {
+    cs.lock();
     int indexCount = 0;
     for (Polygon3D* p : *polygons)
         indexCount += p->indexAnz;
@@ -404,6 +405,7 @@ void Model3DData::buildIndexBuffer()
         }
         current += p->indexAnz;
     }
+    cs.unlock();
 }
 
 // Sets the pointer to a default skeleton
@@ -419,6 +421,7 @@ void Model3DData::setSkeletonZ(Skeleton* s)
 //  anz: The number of vertices in the array
 void Model3DData::setVertecies(Vertex3D* vertexList, int anz)
 {
+    cs.lock();
     delete[] this->vertexList;
     this->vertexList = vertexList;
     vertexCount = anz;
@@ -438,6 +441,7 @@ void Model3DData::setVertecies(Vertex3D* vertexList, int anz)
         vertexList[i].id = i;
     }
     vertexBufferChanged = 1;
+    cs.unlock();
 }
 
 // Adds a polygon to the model
@@ -674,6 +678,16 @@ void Framework::Model3DData::setVertexBufferChanged(bool changed)
     vertexBufferChanged = changed;
 }
 
+void Framework::Model3DData::lock()
+{
+    cs.lock();
+}
+
+void Framework::Model3DData::unlock()
+{
+    cs.unlock();
+}
+
 // Contents of the Model3DTexture class
 
 // Constructor

+ 3 - 0
Model3D.h

@@ -172,6 +172,7 @@ namespace Framework
         Vec3<float> maxPos;
         bool vertexBufferChanged;
         bool indexBufferChanged;
+        Critical cs;
         int id;
 
     public:
@@ -271,6 +272,8 @@ namespace Framework
         DLLEXPORT bool wasVertexBufferChanged() const;
         //! Sets the flag indicating that the vertex buffer has changed
         DLLEXPORT void setVertexBufferChanged(bool changed);
+        DLLEXPORT void lock();
+        DLLEXPORT void unlock();
     };
 
     //! Stores a list of textures and which texture to use for which polygon

+ 45 - 9
RayGen.hlsl

@@ -6,19 +6,55 @@ RWTexture2D<float4> gOutput : register(u0);
 RWTexture2D<float4> guiTexture : register(u1);
 
 // Raytracing acceleration structure, accessed as a SRV
-RaytracingAccelerationStructure SceneBVH : register(t0);
+RaytracingAccelerationStructure TLAS : register(t0);
+
+cbuffer RayGenerationSettings : register(b0)
+{
+    int renderGui;
+    int useRays;
+    float minDistance;
+    float maxDistance;
+    float4x4 inverseView;
+    float4x4 inverseProjection;
+}
 
 [shader("raygeneration")]
 void RayGen()
 {
   // Initialize the ray payload
-    HitInfo payload;
-    payload.colorAndDistance = float4(0.9, 0.6, 0.2, 1.0);
+    HitInfo rayPayload;
+    rayPayload.colorAndDistance = float4(0, 0, 0, 1.0);
+
+    // Get the location within the dispatched 2D grid of work items
+    // (often maps to pixels, so this could represent a pixel coordinate).
+    float2 dispatchDimensions = float2(DispatchRaysDimensions().xy);
+    uint2 dispatchIndex = DispatchRaysIndex().xy;
+    float2 dispatchPercentage = dispatchIndex / dispatchDimensions;
+    
+    if (useRays)
+    {
+        float2 d = (((dispatchIndex.xy + 0.5f) / dispatchDimensions.xy) * 2.f - 1.f);
+        RayDesc ray;
+        ray.Origin = mul(inverseView, float4(0, 0, 0, 1)).xyz;
+        float4 target = mul(inverseProjection, float4(d.x, -d.y, 1, 1));
+        ray.Direction = mul(inverseView, float4(target.xyz, 0)).xyz;
+        ray.TMin = minDistance;
+        ray.TMax = maxDistance;
+        TraceRay(TLAS, /*RayFlags*/0, /*InstanceInclusionMask*/0xFF, /*RayContributionToHitGroupIndex*/0,
+            /*MultiplierForGeometryContributionToHitGroupIndex*/0, /*MissShaderIndex*/0, ray, rayPayload);
+    }
+    
+    uint outWidth, outHeight;
+    gOutput.GetDimensions(outWidth, outHeight);
+    uint2 outputIndex = uint2(dispatchPercentage * float2(outWidth, outHeight));
+    if (renderGui)
+    {
+        uint guiWidth, guiHeight;
+        guiTexture.GetDimensions(guiWidth, guiHeight);
+        uint2 guiIndex = uint2(dispatchPercentage * float2(guiWidth, guiHeight));
+        float4 guiColor = guiTexture[guiIndex];
+        rayPayload.colorAndDistance.rgb = rayPayload.colorAndDistance.rgb * (1 - guiColor.a) + guiColor.rgb * guiColor.a;
+    }
+    gOutput[outputIndex] = float4(rayPayload.colorAndDistance.rgb, 1.f);
 
-  // Get the location within the dispatched 2D grid of work items
-  // (often maps to pixels, so this could represent a pixel coordinate).
-    uint2 launchIndex = DispatchRaysIndex().xy;
-  
-    float4 guiColor = guiTexture[launchIndex];
-    gOutput[launchIndex] = float4(payload.colorAndDistance.rgb * (1 - guiColor.a) + guiColor.rgb * guiColor.a, 1.f);
 }