瀏覽代碼

fix problems with direcx12 api

Kolja Strohm 3 周之前
父節點
當前提交
192983a3cb
共有 15 個文件被更改,包括 316 次插入100 次删除
  1. 9 3
      DX12BLASModel.cpp
  2. 16 5
      DX12Buffer.cpp
  3. 8 2
      DX12Buffer.h
  4. 64 15
      DX12GraphicsApi.cpp
  5. 6 2
      DX12GraphicsApi.h
  6. 105 24
      DX12Shader.cpp
  7. 5 1
      DX12Shader.h
  8. 33 9
      DX12TLAS.cpp
  9. 1 0
      DX12TLAS.h
  10. 43 30
      DX12Texture.cpp
  11. 1 0
      DX12Texture.h
  12. 6 1
      GraphicsApi.cpp
  13. 1 0
      GraphicsApi.h
  14. 15 8
      Screen.cpp
  15. 3 0
      Screen.h

+ 9 - 3
DX12BLASModel.cpp

@@ -1,5 +1,6 @@
 #include "DX12BLASModel.h"
 
+#include "DX12CommandQueue.h"
 #include "Model3D.h"
 
 Framework::DX12BLASModel::DX12BLASModel(Model3DData* zModelData,
@@ -125,14 +126,19 @@ void Framework::DX12BLASModel::calculateBuffers()
     {
         if (boneVertexCount[i] > 0 && boneIndexCount[i] > 0)
         {
-            DX12Buffer* vertexBuffer
-                = new DX12Buffer(sizeof(Vec3<float>), zDevice, 0);
+            DX12Buffer* vertexBuffer = new DX12Buffer(sizeof(Vec3<float>),
+                zDevice,
+                dynamic_cast<DX12CommandQueue*>(zDirectQueue->getThis()),
+                0);
             vertexBuffer->setData(boneVertexBuffers[i], true);
             vertexBuffer->setLength(boneVertexCount[i] * sizeof(Vec3<float>));
             vertexBuffer->copyToGPU();
             vertexBuffers->add(vertexBuffer);
 
-            DX12Buffer* indexBuffer = new DX12Buffer(sizeof(int), zDevice, 0);
+            DX12Buffer* indexBuffer = new DX12Buffer(sizeof(int),
+                zDevice,
+                dynamic_cast<DX12CommandQueue*>(zDirectQueue->getThis()),
+                0);
             indexBuffer->setData(boneIndexBuffers[i], true);
             indexBuffer->setLength(boneIndexCount[i] * sizeof(int));
             indexBuffer->copyToGPU();

+ 16 - 5
DX12Buffer.cpp

@@ -8,10 +8,12 @@ using namespace Framework;
 
 // Constructor
 // eSize: length of an element in bytes
-DX12Buffer::DX12Buffer(int eSize, ID3D12Device5* device, int flags)
+DX12Buffer::DX12Buffer(
+    int eSize, ID3D12Device5* zDevice, DX12CommandQueue* queue, int flags)
     : DXBuffer(eSize),
       buffer(0),
-      device(device)
+      zDevice(zDevice),
+      queue(queue)
 {
     description = new D3D12_RESOURCE_DESC();
     ZeroMemory(description, sizeof(D3D12_RESOURCE_DESC));
@@ -30,6 +32,7 @@ DX12Buffer::DX12Buffer(int eSize, ID3D12Device5* device, int flags)
 DX12Buffer::~DX12Buffer()
 {
     if (buffer) buffer->Release();
+    if (queue) queue->release();
     delete description;
 }
 
@@ -52,7 +55,7 @@ void DX12Buffer::copyToGPU(__int64 byteCount)
         hprop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
         hprop.CreationNodeMask = 1;
         hprop.VisibleNodeMask = 1;
-        device->CreateCommittedResource(&hprop,
+        zDevice->CreateCommittedResource(&hprop,
             D3D12_HEAP_FLAG_NONE,
             description,
             D3D12_RESOURCE_STATE_GENERIC_READ,
@@ -92,13 +95,21 @@ void Framework::DX12Buffer::createBufferWithoutData(
         hprop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
         hprop.CreationNodeMask = 0;
         hprop.VisibleNodeMask = 0;
-        device->CreateCommittedResource(&hprop,
+        zDevice->CreateCommittedResource(&hprop,
             D3D12_HEAP_FLAG_NONE,
             description,
-            states,
+            states & ~D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
             0,
             __uuidof(ID3D12Resource),
             (void**)&buffer);
+        if (states & D3D12_RESOURCE_STATE_UNORDERED_ACCESS)
+        {
+            // TODO: add state transition
+            CD3DX12_RESOURCE_BARRIER transition
+                = CD3DX12_RESOURCE_BARRIER::Transition(
+                    buffer, D3D12_RESOURCE_STATE_COMMON, states);
+            queue->zCommandList()->ResourceBarrier(1, &transition);
+        }
     }
 }
 

+ 8 - 2
DX12Buffer.h

@@ -5,18 +5,24 @@
 
 namespace Framework
 {
+    class DX12CommandQueue;
+
     //! A buffer with data in graphics memory
     class DX12Buffer : public DXBuffer
     {
     protected:
         D3D12_RESOURCE_DESC* description;
         ID3D12Resource* buffer;
-        ID3D12Device5* device;
+        ID3D12Device5* zDevice;
+        DX12CommandQueue* queue;
 
     public:
         //! Constructor
         //! eSize: The length of an element in bytes
-        DLLEXPORT DX12Buffer(int eSize, ID3D12Device5* device, int bindFlags);
+        DLLEXPORT DX12Buffer(int eSize,
+            ID3D12Device5* zDevice,
+            DX12CommandQueue* queue,
+            int bindFlags);
         //! Destructor
         DLLEXPORT virtual ~DX12Buffer();
         //! Copies the data into the buffer if it has changed

+ 64 - 15
DX12GraphicsApi.cpp

@@ -31,7 +31,6 @@ using namespace Framework;
 DirectX12::DirectX12()
     : GraphicsApi(DIRECTX12),
       debug(0),
-      device(0),
       infoQueue(0),
       directCommandQueue(0),
       swapChain(0),
@@ -48,9 +47,15 @@ DirectX12::DirectX12()
       lastTLASId(-1),
       lastModelId(-1),
       defaultRenderTarget(0),
+      defaultKamera(0),
+      cameraCount(0),
+      device(0),
+      pfnD3D12SerializeRootSignature(0),
+      pipeline(0),
       globalDescriptorHeap(0),
       defaultHitGroup(0),
-      defaultRayGenerationShaderFunction(0)
+      defaultRayGenerationShaderFunction(0),
+      tlasInputOffset(0)
 {
     for (int i = 0; i < 2; i++)
         backBuffer[i] = 0;
@@ -98,6 +103,7 @@ DirectX12::~DirectX12()
     }
     texturRegister->release();
     if (uiTexture) uiTexture->release();
+    if (defaultKamera) defaultKamera->release();
     if (defaultRenderTarget) defaultRenderTarget->release();
     if (signature) signature->Release();
     delete allowedRenderArea;
@@ -147,6 +153,10 @@ void DirectX12::updateBottomLevelAccelerationStructure()
 void Framework::DirectX12::renderKamera(
     Cam3D* zKamera, DX12Texture* zTarget, bool guiVisible)
 {
+    if (guiVisible)
+    {
+        uiTexture->updateTextur();
+    }
     if (!pipeline)
     {
         setPipeline(new DX12Pipeline());
@@ -219,16 +229,15 @@ void Framework::DirectX12::renderKamera(
     tlas->endUpdate();
     if (defaultRayGenerationShaderFunction)
     {
-        sbt->setShaderInput(defaultRayGenerationShaderFunction,
-            renderTargetInputOffset,
-            zTarget->zResource()->GetGPUVirtualAddress());
+        globalDescriptorHeap->updateTextureInput(
+            0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, zTarget);
         sbt->setShaderInput(defaultRayGenerationShaderFunction,
             tlasInputOffset,
             tlas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress());
     }
     sbt->setGlobalDescriptorHeap(dynamic_cast<DX12GlobalDescriptorHeap*>(
         globalDescriptorHeap->getThis()));
-    sbt->endUpdate(device);
+    sbt->endUpdate(device, directCommandQueue);
     ID3D12DescriptorHeap* heaps[] = {globalDescriptorHeap->zDescriptorHeap()};
     directCommandQueue->zCommandList()->SetDescriptorHeaps(1, heaps);
 
@@ -251,11 +260,10 @@ void Framework::DirectX12::initializePipeline()
                 sizeof(DX12DefaultRayGenerationShaderBytes));
         // RayGen from RayGen.hlsl
         DX12ShaderSignature* rayGenSignature = new DX12ShaderSignature();
-        renderTargetInputOffset
-            = rayGenSignature->addRegisterUsageLinkedToShaderBindingTable(
-                DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 0);
         rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
-            0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 1);
+            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);
@@ -282,15 +290,22 @@ void Framework::DirectX12::initializePipeline()
         pipeline->addShader(hitShader);
 
         defaultHitGroup = new DX12ShaderHitGroup("HitGroup");
+        defaultHitGroup->setAttributeSize(8);
+        defaultHitGroup->setPayloadSize(16);
         defaultHitGroup->setClosestHitShaderFunction(closestHitFunction);
         pipeline->addHitGroup(defaultHitGroup);
     }
+    pipeline->createPipelineState(device, pfnD3D12SerializeRootSignature);
 }
 
 void Framework::DirectX12::initializeGlobalDescriptorHeap()
 {
     globalDescriptorHeap->addTextureInput(
-        DX12_SHADER_REGISTER_T_SHADER_RESOURCE, uiTexture);
+        DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, defaultRenderTarget);
+    globalDescriptorHeap->addTextureInput(
+        DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, uiTexture);
+
+    globalDescriptorHeap->updateDescriptorHeap(device);
 }
 
 void Framework::DirectX12::fillShaderBindingTable(
@@ -338,6 +353,21 @@ void DirectX12::initialize(
             MB_ICONERROR);
         return;
     }
+    pfnD3D12SerializeRootSignature
+        = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(
+            d3d12DLL, "D3D12SerializeRootSignature");
+    if (!pfnD3D12SerializeRootSignature)
+    {
+        getDLLRegister()->releaseDLL("dxgi.dll");
+        getDLLRegister()->releaseDLL("d3d12.dll");
+        WMessageBox(fenster->getWindowHandle(),
+            new Text("Fehler"),
+            new Text(
+                "Der Einstiegspunkt D3D12SerializeRootSignature fon d3d12.dll "
+                "konnte nicht gefunden werden."),
+            MB_ICONERROR);
+        return;
+    }
     // CreateDXGIFactory2
     CreateDXGIFactory2Function createFactory
         = (CreateDXGIFactory2Function)GetProcAddress(
@@ -763,6 +793,7 @@ void DirectX12::initialize(
 
 void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor)
 {
+    cameraCount = 0;
     D3D12_RESOURCE_BARRIER barrier;
     ZeroMemory(&barrier, sizeof(barrier));
     barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
@@ -775,8 +806,6 @@ void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor)
 
     if (fill2D) uiTexture->zImage()->setColor(fillColor);
 
-    uiTexture->updateTextur();
-
     CD3DX12_RESOURCE_BARRIER transition
         = CD3DX12_RESOURCE_BARRIER::Transition(defaultRenderTarget->zResource(),
             D3D12_RESOURCE_STATE_COPY_SOURCE,
@@ -786,16 +815,28 @@ void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor)
 
 void DirectX12::renderKamera(Cam3D* zKamera)
 {
+    cameraCount++;
     renderKamera(zKamera, defaultRenderTarget, true);
 }
 
 void Framework::DirectX12::renderKamera(Cam3D* zKamera, Texture* zTarget)
 {
+    cameraCount++;
     renderKamera(zKamera, dynamic_cast<DX12Texture*>(zTarget), false);
 }
 
 void DirectX12::presentFrame()
 {
+    if (cameraCount == 0)
+    {
+        if (!defaultKamera)
+        {
+            defaultKamera = new Cam3D();
+            defaultKamera->setWorld(new World3D());
+            defaultKamera->setScreenSize(backBufferSize);
+        }
+        renderKamera(defaultKamera);
+    }
     CD3DX12_RESOURCE_BARRIER transition
         = CD3DX12_RESOURCE_BARRIER::Transition(defaultRenderTarget->zResource(),
             D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
@@ -859,7 +900,10 @@ Image* DirectX12::zUIRenderImage() const
 
 DXBuffer* DirectX12::createStructuredBuffer(int eSize)
 {
-    return new DX12Buffer(eSize, device, D3D12_RESOURCE_FLAG_NONE);
+    return new DX12Buffer(eSize,
+        device,
+        dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
+        D3D12_RESOURCE_FLAG_NONE);
 }
 
 void Framework::DirectX12::setPipeline(DX12Pipeline* pipeline)
@@ -967,4 +1011,9 @@ bool DirectX12::isAvailable()
     getDLLRegister()->releaseDLL("dxgi.dll");
     getDLLRegister()->releaseDLL("d3d12.dll");
     return 0;
-}
+}
+
+bool Framework::DirectX12::renderGuiBefore3D() const
+{
+    return true;
+}

+ 6 - 2
DX12GraphicsApi.h

@@ -43,12 +43,12 @@ namespace Framework
     class Model3D;
     class DX12ShaderHitGroup;
     class DX12ShaderFunction;
+    class Cam3D;
 
     class DirectX12 : public GraphicsApi
     {
     private:
         ID3D12Debug* debug;
-        ID3D12Device5* device;
         ID3D12InfoQueue* infoQueue;
         DX12DirectCommandQueue* directCommandQueue;
         IDXGISwapChain4* swapChain;
@@ -69,13 +69,16 @@ namespace Framework
         int lastTLASId;
         int lastModelId;
         DX12Texture* defaultRenderTarget;
+        Cam3D* defaultKamera;
+        int cameraCount;
 
     protected:
+        ID3D12Device5* device;
+        PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature;
         DX12Pipeline* pipeline;
         DX12GlobalDescriptorHeap* globalDescriptorHeap;
         DX12ShaderHitGroup* defaultHitGroup;
         DX12ShaderFunction* defaultRayGenerationShaderFunction;
-        int* renderTargetInputOffset;
         int* tlasInputOffset;
 
     public:
@@ -111,5 +114,6 @@ namespace Framework
         DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) override;
         DLLEXPORT void setPipeline(DX12Pipeline* pipeline);
         DLLEXPORT static bool isAvailable();
+        DLLEXPORT bool renderGuiBefore3D() const override;
     };
 } // namespace Framework

+ 105 - 24
DX12Shader.cpp

@@ -1,5 +1,6 @@
 #include "DX12Shader.h"
 
+#include "DX12CommandQueue.h"
 #include "DX12Texture.h"
 #include "DX12TLAS.h"
 #include "Logging.h"
@@ -160,9 +161,9 @@ void Framework::DX12ShaderSignature::createSignature(ID3D12Device5* zDevice,
     D3D12_DESCRIPTOR_RANGE* descriptorRanges = 0;
     if (descriptorHeapBindings.getEntryCount())
     {
-        descriptorTable[index].ParameterType
+        descriptorTable[0].ParameterType
             = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
-        descriptorTable[index].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+        descriptorTable[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
         descriptorRanges = new D3D12_DESCRIPTOR_RANGE[descriptorHeapBindings
                 .getEntryCount()];
         ArrayIterator<DX12ShaderRegisterUsage*> it
@@ -183,6 +184,9 @@ void Framework::DX12ShaderSignature::createSignature(ID3D12Device5* zDevice,
                 range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
                 break;
             }
+            range.BaseShaderRegister = it->registerIndex;
+            range.OffsetInDescriptorsFromTableStart = it->descriptorHeapIndex;
+            range.RegisterSpace = it->spaceIndex;
             ArrayIterator<DX12ShaderRegisterUsage*> next = it.next();
             int size = 1;
             while (
@@ -197,15 +201,11 @@ void Framework::DX12ShaderSignature::createSignature(ID3D12Device5* zDevice,
                 ++next;
             }
             range.NumDescriptors = size;
-            range.BaseShaderRegister = it->registerIndex;
-            range.RegisterSpace = it->spaceIndex;
-            range.OffsetInDescriptorsFromTableStart = it->descriptorHeapIndex;
             ++it;
             ++index;
         }
-        descriptorTable[index].DescriptorTable.pDescriptorRanges
-            = descriptorRanges;
-        descriptorTable[index].DescriptorTable.NumDescriptorRanges = index;
+        descriptorTable[0].DescriptorTable.pDescriptorRanges = descriptorRanges;
+        descriptorTable[0].DescriptorTable.NumDescriptorRanges = index;
         index = 1;
     }
     for (DX12ShaderRegisterUsage* usage : bindingTableBindings)
@@ -288,7 +288,11 @@ Framework::DX12ShaderFunction::DX12ShaderFunction(const Text& functionName,
       exportDesc(new D3D12_EXPORT_DESC())
 {
     wchar_t* wc = new wchar_t[functionName.getLength() + 1];
-    mbtowc(wc, functionName.getText(), functionName.getLength() + 1);
+    mbstowcs_s(0,
+        wc,
+        functionName.getLength() + 1,
+        functionName.getText(),
+        functionName.getLength() + 1);
     wc[functionName.getLength()] = 0;
     exportDesc->Name = wc;
     exportDesc->ExportToRename = 0;
@@ -393,7 +397,8 @@ Framework::DX12ShaderHitGroup::DX12ShaderHitGroup(const Text name)
       hitGroupDesc(new D3D12_HIT_GROUP_DESC())
 {
     wchar_t* wc = new wchar_t[name.getLength() + 1];
-    mbtowc(wc, name.getText(), name.getLength() + 1);
+    mbstowcs_s(
+        0, wc, name.getLength() + 1, name.getText(), name.getLength() + 1);
     wc[name.getLength()] = 0;
     hitGroupDesc->HitGroupExport = wc;
     hitGroupDesc->IntersectionShaderImport = 0;
@@ -714,7 +719,7 @@ void Framework::DX12Pipeline::createPipelineState(ID3D12Device5* zDevice,
                 pSigBlob->GetBufferPointer(),
                 pSigBlob->GetBufferSize(),
                 __uuidof(ID3D12RootSignature),
-                (void**)&emptyGlobalRootSignature);
+                (void**)&emptyLocalRootSignature);
             pSigBlob->Release();
         }
         if (pErrorBlob)
@@ -996,8 +1001,10 @@ const RCArray<DX12ShaderHitGroup>& Framework::DX12Pipeline::getHitGroups() const
 Framework::DX12GlobalDescriptorHeap::DX12GlobalDescriptorHeap(
     DX12Pipeline* pipeline)
     : ReferenceCounter(),
+      pipeline(pipeline),
       descriptorHeap(0),
-      lastDescriptorHeapSize(0)
+      lastDescriptorHeapSize(0),
+      zDevice(0)
 {}
 
 Framework::DX12GlobalDescriptorHeap::~DX12GlobalDescriptorHeap()
@@ -1069,6 +1076,70 @@ void Framework::DX12GlobalDescriptorHeap::addTextureInput(
     addInput(type, zTexture);
 }
 
+void Framework::DX12GlobalDescriptorHeap::updateTextureInput(
+    int heapIndex, DX12ShaderRegister type, Texture* zTexture)
+{
+    DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
+    if (registerInputs.get(heapIndex)->inputResource
+        != dynamic_cast<ReferenceCounter*>(zTexture))
+    {
+        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");
+        }
+        registerInputs.get(heapIndex)->inputResource->release();
+        registerInputs.get(heapIndex)->inputResource = zTexture->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_TEXTURE2D;
+                    srvDesc.Texture2D.MipLevels = 0;
+                    srvDesc.Texture2D.MostDetailedMip = 0;
+                    srvDesc.Texture2D.PlaneSlice = 0;
+                    srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
+                    srvDesc.Shader4ComponentMapping
+                        = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+                    zDevice->CreateShaderResourceView(
+                        ((DX12Texture*)zTexture)->zResource(),
+                        &srvDesc,
+                        descriptorHeapHandle);
+                    break;
+                }
+            case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
+                {
+                    D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
+                    uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
+                    uavDesc.Format = DXGI_FORMAT_UNKNOWN;
+                    uavDesc.Texture2D.MipSlice = 0;
+                    uavDesc.Texture2D.PlaneSlice = 0;
+                    zDevice->CreateUnorderedAccessView(
+                        ((DX12Texture*)zTexture)->zResource(),
+                        0,
+                        &uavDesc,
+                        descriptorHeapHandle);
+                    break;
+                }
+            }
+        }
+    }
+}
+
 void Framework::DX12GlobalDescriptorHeap::addBufferInput(
     DX12ShaderRegister type, DXBuffer* zBuffer)
 {
@@ -1084,6 +1155,7 @@ void Framework::DX12GlobalDescriptorHeap::addTLASInput(
 void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
     ID3D12Device5* zDevice)
 {
+    this->zDevice = zDevice;
     if (!descriptorHeap
         || lastDescriptorHeapSize != registerInputs.getEntryCount())
     {
@@ -1360,8 +1432,10 @@ void Framework::DX12ShaderBindingTable::startUpdate()
     hitGroupRecordSize = ROUND_UP_POWER_OF_2(
         D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + hitGroupRecordSize * 8,
         D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
-    nextHitGroupOffset
-        = rayGenRecordSize * rayGenCount + missRecordSize * missCount;
+    nextHitGroupOffset = ROUND_UP_POWER_OF_2(
+        rayGenRecordSize * rayGenCount + missRecordSize * missCount
+            + callableRecordSize * callableCount,
+        64);
 }
 
 void Framework::DX12ShaderBindingTable::set(int index, void* data, int size)
@@ -1374,12 +1448,12 @@ void Framework::DX12ShaderBindingTable::set(int index, void* data, int size)
     {
         index -= tableBufferSize;
         ArrayIterator<char*> it = tempBuffers.begin();
-        while (it && 2048 >= index + size)
+        while (it && 2048 < index + size)
         {
             index -= 2048;
             it++;
         }
-        while (2048 >= index + size)
+        while (2048 < index + size)
         {
             char* newBuffer = new char[2048];
             memset(newBuffer, 0, 2048);
@@ -1475,7 +1549,8 @@ void Framework::DX12ShaderBindingTable::setHitGroupShaderInput(
         sizeof(__int64));
 }
 
-void Framework::DX12ShaderBindingTable::endUpdate(ID3D12Device5* zDevice)
+void Framework::DX12ShaderBindingTable::endUpdate(
+    ID3D12Device5* zDevice, DX12CommandQueue* zQueue)
 {
     int rayTracingIndex = 0;
     int missIndex = 0;
@@ -1525,8 +1600,10 @@ void Framework::DX12ShaderBindingTable::endUpdate(ID3D12Device5* zDevice)
     }
     if (nextHitGroupOffset > tableBufferSize)
     {
-        DX12Buffer* newBuffer
-            = new DX12Buffer(1, zDevice, D3D12_RESOURCE_FLAG_NONE);
+        DX12Buffer* newBuffer = new DX12Buffer(1,
+            zDevice,
+            dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
+            D3D12_RESOURCE_FLAG_NONE);
         newBuffer->setLength(ROUND_UP_POWER_OF_2(nextHitGroupOffset, 256));
         newBuffer->createBufferWithoutData(
             D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD);
@@ -1584,16 +1661,20 @@ void Framework::DX12ShaderBindingTable::fillDispatchRaysDesc(
         = hitGroupCount * hitGroupRecordSize;
     dispatchRaysDesc->HitGroupTable.StartAddress
         = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
-        + rayGenCount * rayGenRecordSize + missCount * missRecordSize;
+        + ROUND_UP_POWER_OF_2(rayGenCount * rayGenRecordSize
+                                  + missCount * missRecordSize
+                                  + callableCount * callableRecordSize,
+            64);
     dispatchRaysDesc->HitGroupTable.StrideInBytes = hitGroupRecordSize;
 
     dispatchRaysDesc->CallableShaderTable.SizeInBytes
         = callableCount * callableRecordSize;
     dispatchRaysDesc->CallableShaderTable.StartAddress
-        = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
-        + rayGenCount * rayGenRecordSize + missCount * missRecordSize
-        + hitGroupCount * hitGroupRecordSize;
-    dispatchRaysDesc->CallableShaderTable.StrideInBytes = callableRecordSize;
+        = callableCount > 0 ? shaderBindingTableBuffer->zBuffer()
+              ->GetGPUVirtualAddress()
+        + rayGenCount * rayGenRecordSize + missCount * missRecordSize : 0;
+    dispatchRaysDesc->CallableShaderTable.StrideInBytes
+        = callableCount > 0 ? callableRecordSize : 0;
 }
 
 DX12Pipeline* Framework::DX12ShaderBindingTable::zPipeline() const

+ 5 - 1
DX12Shader.h

@@ -225,6 +225,7 @@ namespace Framework
         ID3D12DescriptorHeap* descriptorHeap;
         Array<DX12ShaderRegisterInput*> registerInputs;
         int lastDescriptorHeapSize;
+        ID3D12Device5* zDevice;
 
     public:
         DX12GlobalDescriptorHeap(DX12Pipeline* pipeline);
@@ -237,6 +238,8 @@ namespace Framework
     public:
         DLLEXPORT void addTextureInput(
             DX12ShaderRegister type, Texture* zTexture);
+        DLLEXPORT void updateTextureInput(
+            int heapIndex, DX12ShaderRegister type, Texture* zTexture);
         DLLEXPORT void addBufferInput(
             DX12ShaderRegister type, DXBuffer* zBuffer);
         DLLEXPORT void addTLASInput(DX12ShaderRegister type, DX12TLAS* zTLAS);
@@ -320,7 +323,8 @@ namespace Framework
          */
         DLLEXPORT void setHitGroupShaderInput(
             int hitGroupOffset, int* offsetPointer, __int64 gpuAddress);
-        DLLEXPORT void endUpdate(ID3D12Device5* zDevice);
+        DLLEXPORT void endUpdate(
+            ID3D12Device5* zDevice, DX12CommandQueue* zQueue);
         DLLEXPORT void fillDispatchRaysDesc(
             D3D12_DISPATCH_RAYS_DESC* dispatchRaysDesc);
         DLLEXPORT DX12Pipeline* zPipeline() const;

+ 33 - 9
DX12TLAS.cpp

@@ -13,6 +13,7 @@ Framework::DX12TLAS::DX12TLAS(
       zDirectQueue(zDirectQueue),
       overflowInstanceIterator(0, 0, 0, 0),
       currentInstanceIndex(0),
+      lastInstanceCount(0),
       mappedDescriptorBuffer(0)
 {}
 
@@ -78,14 +79,28 @@ D3D12_RAYTRACING_INSTANCE_DESC* Framework::DX12TLAS::nextInstanceDesc()
 
 void Framework::DX12TLAS::endUpdate()
 {
-    while (currentInstanceIndex < descriptorBuffer->getElementCount() - 1)
+    if (currentInstanceIndex < 0) // at least one instance ust be added
     {
         D3D12_RAYTRACING_INSTANCE_DESC* desc = nextInstanceDesc();
+        desc->InstanceContributionToHitGroupIndex = 0;
+        desc->InstanceID = 0;
+        desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
+        desc->AccelerationStructure = 0;
         desc->InstanceMask = 0; // Mark unused instances with a mask of 0
     }
-    descriptorBuffer->zBuffer()->Unmap(0, nullptr);
+    if (descriptorBuffer)
+    {
+        while (currentInstanceIndex < lastInstanceCount - 1)
+        {
+            D3D12_RAYTRACING_INSTANCE_DESC* desc = nextInstanceDesc();
+            desc->InstanceMask = 0; // Mark unused instances with a mask of 0
+        }
+        descriptorBuffer->zBuffer()->Unmap(0, nullptr);
+    }
     mappedDescriptorBuffer = 0;
-    if (currentInstanceIndex >= descriptorBuffer->getElementCount())
+    lastInstanceCount = currentInstanceIndex + 1;
+    if (!descriptorBuffer
+        || currentInstanceIndex >= descriptorBuffer->getElementCount())
     {
         // recalculate the size of the descriptor buffer and reallocate it
         D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS
@@ -111,21 +126,27 @@ void Framework::DX12TLAS::endUpdate()
             }
             previousResultBuffer = resultBuffer;
         }
-        resultBuffer = new DX12Buffer(
-            1, zDevice, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+        resultBuffer = new DX12Buffer(1,
+            zDevice,
+            dynamic_cast<DX12CommandQueue*>(zDirectQueue->getThis()),
+            D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
         resultBuffer->setLength(
             ROUND_UP_POWER_OF_2(info.ResultDataMaxSizeInBytes, 256));
         resultBuffer->createBufferWithoutData(
             D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
+        resultBuffer->zBuffer()->SetName(L"TLAS Result Buffer");
         if (!scratchBuffer)
         {
-            scratchBuffer = new DX12Buffer(
-                1, zDevice, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+            scratchBuffer = new DX12Buffer(1,
+                zDevice,
+                dynamic_cast<DX12CommandQueue*>(zDirectQueue->getThis()),
+                D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
         }
         scratchBuffer->setLength(
             ROUND_UP_POWER_OF_2(info.ScratchDataSizeInBytes, 256));
         scratchBuffer->createBufferWithoutData(
             D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
+        scratchBuffer->zBuffer()->SetName(L"TLAS Scratch Buffer");
         ID3D12Resource* oldDescriptorBuffer
             = descriptorBuffer ? descriptorBuffer->zBuffer() : 0;
         __int64 oldDescriptorBufferElementCount
@@ -140,13 +161,14 @@ void Framework::DX12TLAS::endUpdate()
             descriptorBuffer
                 = new DX12Buffer(sizeof(D3D12_RAYTRACING_INSTANCE_DESC),
                     zDevice,
+                    dynamic_cast<DX12CommandQueue*>(zDirectQueue->getThis()),
                     D3D12_RESOURCE_FLAG_NONE);
         }
         descriptorBuffer->setLength(ROUND_UP_POWER_OF_2(
             (currentInstanceIndex + 1) * sizeof(D3D12_RAYTRACING_INSTANCE_DESC),
             256));
         descriptorBuffer->createBufferWithoutData(
-            D3D12_RESOURCE_STATE_GENERIC_READ);
+            D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD);
         D3D12_RAYTRACING_INSTANCE_DESC* newMappedDescriptorBuffer = 0;
 
         // copy the old and new instance descriptions to the new buffer
@@ -190,7 +212,9 @@ void Framework::DX12TLAS::endUpdate()
             ? previousResultBuffer->zBuffer()->GetGPUVirtualAddress()
             : 0;
     buildDesc.Inputs.Flags
-        = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE;
+        = previousResultBuffer
+            ? D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE
+            : D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
 
     // Build the top-level AS
     zDirectQueue->zCommandList()->BuildRaytracingAccelerationStructure(

+ 1 - 0
DX12TLAS.h

@@ -19,6 +19,7 @@ namespace Framework
         Array<D3D12_RAYTRACING_INSTANCE_DESC*> overflowInstanceDescs;
         ArrayIterator<D3D12_RAYTRACING_INSTANCE_DESC*> overflowInstanceIterator;
         __int64 currentInstanceIndex;
+        __int64 lastInstanceCount;
         D3D12_RAYTRACING_INSTANCE_DESC* mappedDescriptorBuffer;
 
     public:

+ 43 - 30
DX12Texture.cpp

@@ -11,13 +11,15 @@ DX12Texture::DX12Texture(
     : Texture(dir),
       buffer(0),
       device(device),
-      direct(direct)
+      direct(direct),
+      upload(0)
 {}
 
 DX12Texture::~DX12Texture()
 {
 #ifdef WIN32
     if (buffer) buffer->Release();
+    if (upload) upload->Release();
 #endif
 }
 
@@ -39,9 +41,7 @@ bool DX12Texture::updateTextur()
         description.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
         description.SampleDesc.Count = 1;
         description.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
-        description.Flags = getDirection() == GPU_TO_RAM
-                              ? D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
-                              : D3D12_RESOURCE_FLAG_NONE;
+        description.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
         D3D12_HEAP_PROPERTIES hprop;
         hprop.Type = D3D12_HEAP_TYPE_DEFAULT;
         hprop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
@@ -56,35 +56,48 @@ bool DX12Texture::updateTextur()
             0,
             __uuidof(ID3D12Resource),
             (void**)&buffer);
-        // TODO: copy from image to texture or from texture to image
-
-        /* const UINT64 uploadBufferSize
-            = GetRequiredIntermediateSize(buffer, 0, 1);
-        D3D12_RESOURCE_DESC iDescription;
-        iDescription.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
-        iDescription.Alignment = 0;
-        iDescription.Width = uploadBufferSize;
-        iDescription.Height = 1;
-        iDescription.DepthOrArraySize = 1;
-        iDescription.MipLevels = 1;
-        iDescription.Format = DXGI_FORMAT_UNKNOWN;
-        iDescription.SampleDesc.Count = 1;
-        iDescription.SampleDesc.Quality = 0;
-        iDescription.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
-        iDescription.Flags = D3D12_RESOURCE_FLAG_NONE;
-        hprop.Type = D3D12_HEAP_TYPE_UPLOAD;
-        device->CreateCommittedResource(&hprop,
-            D3D12_HEAP_FLAG_NONE,
-            &iDescription,
-            D3D12_RESOURCE_STATE_GENERIC_READ,
-            0,
-            __uuidof(ID3D12Resource),
-            (void**)&intermediate);
-        shaderResource = 0;*/
+        if (getDirection() == RAM_TO_GPU)
+        {
+            const UINT64 uploadBufferSize
+                = GetRequiredIntermediateSize(buffer, 0, 1);
+            D3D12_RESOURCE_DESC iDescription;
+            iDescription.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+            iDescription.Alignment = 0;
+            iDescription.Width = uploadBufferSize;
+            iDescription.Height = 1;
+            iDescription.DepthOrArraySize = 1;
+            iDescription.MipLevels = 1;
+            iDescription.Format = DXGI_FORMAT_UNKNOWN;
+            iDescription.SampleDesc.Count = 1;
+            iDescription.SampleDesc.Quality = 0;
+            iDescription.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+            iDescription.Flags = D3D12_RESOURCE_FLAG_NONE;
+            hprop.Type = D3D12_HEAP_TYPE_UPLOAD;
+            device->CreateCommittedResource(&hprop,
+                D3D12_HEAP_FLAG_NONE,
+                &iDescription,
+                D3D12_RESOURCE_STATE_GENERIC_READ,
+                0,
+                __uuidof(ID3D12Resource),
+                (void**)&upload);
+        }
+    }
+    if (getDirection() == RAM_TO_GPU)
+    {
+        if (bild && (changed || bild->getNeedRender()))
+        {
+            changed = 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, upload, 0, 0, 1, &textureData);
     }
     /* if (bild && (changed || bild->getNeedRender()))
     {
-        changed = 0;
+            changed = 0;
         if (shaderResource)
         {
             D3D12_RESOURCE_BARRIER barrier;

+ 1 - 0
DX12Texture.h

@@ -14,6 +14,7 @@ namespace Framework
     {
     private:
         ID3D12Resource* buffer;
+        ID3D12Resource* upload;
         ID3D12Device* device;
         DX12DirectCommandQueue* direct;
 

+ 6 - 1
GraphicsApi.cpp

@@ -109,4 +109,9 @@ bool GraphicsApi::hasModel(const char* name)
     bool res = modelList->hasModel(name);
     rwLock.unlockRead();
     return res;
-}
+}
+
+bool Framework::GraphicsApi::renderGuiBefore3D() const
+{
+    return false;
+}

+ 1 - 0
GraphicsApi.h

@@ -71,5 +71,6 @@ namespace Framework
         //! be used as a shader resource
         //! \param eSize the size of one element of the buffer in bytes
         DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) = 0;
+        DLLEXPORT virtual bool renderGuiBefore3D() const;
     };
 } // namespace Framework

+ 15 - 8
Screen.cpp

@@ -545,6 +545,8 @@ void Screen3D::render() // Draws the image
     api->beginFrame(fill && (rend || !testRend),
         fill && (rend3D || !testRend || rend),
         fillColor);
+    bool rendGuiBefore3D = api->renderGuiBefore3D();
+    if (rendGuiBefore3D) renderGui();
     if (rend3D || !testRend || rend)
     {
         // Render 3d Objects
@@ -552,6 +554,19 @@ void Screen3D::render() // Draws the image
             api->renderKamera(k);
         rend3D = 0;
     }
+    if (!rendGuiBefore3D) renderGui();
+    api->presentFrame();
+    rwLock.unlockRead();
+    renderTime->measureEnd();
+#    ifdef _DEBUG
+    // Logging::trace() << renderTime->getSekunden() << "\n";
+#    endif
+    rendering = 0;
+    rend = 0;
+}
+
+void Framework::Screen3D::renderGui()
+{
     // render User Interface
     Image* ui = api->zUIRenderImage();
     if ((rend || !testRend) && ui)
@@ -581,13 +596,5 @@ void Screen3D::render() // Draws the image
         }
         if (renderOnTop && onTop) onTop->render(*ui);
     }
-    api->presentFrame();
-    rwLock.unlockRead();
-    renderTime->measureEnd();
-#    ifdef _DEBUG
-    // Logging::trace() << renderTime->getSekunden() << "\n";
-#    endif
-    rendering = 0;
-    rend = 0;
 }
 #endif

+ 3 - 0
Screen.h

@@ -235,6 +235,9 @@ namespace Framework
         DLLEXPORT void doKeyboardEvent(KeyboardEvent& te);
         //! Draws an image and presents it on the screen
         DLLEXPORT void render();
+
+    private:
+        void renderGui();
     };
 
     //! Finds the position and resolution of a monitor