Forráskód Böngészése

add generation of the shader descriptor heaps

Kolja Strohm 4 hete
szülő
commit
50353c03c5
23 módosított fájl, 832 hozzáadás és 421 törlés
  1. 127 71
      Array.h
  2. 7 7
      DX11GraphicsApi.cpp
  3. 1 1
      DX11GraphicsApi.h
  4. 199 0
      DX11Texture.cpp
  5. 41 0
      DX11Texture.h
  6. 12 11
      DX12GraphicsApi.cpp
  7. 3 2
      DX12GraphicsApi.h
  8. 271 16
      DX12Shader.cpp
  9. 50 13
      DX12Shader.h
  10. 1 1
      DX12TLAS.cpp
  11. 16 13
      DX12Texture.cpp
  12. 6 6
      DX12Texture.h
  13. 4 3
      DX9GraphicsApi.cpp
  14. 1 1
      DX9GraphicsApi.h
  15. 20 0
      DX9Texture.cpp
  16. 19 0
      DX9Texture.h
  17. 4 0
      Framework.vcxproj
  18. 18 6
      Framework.vcxproj.filters
  19. 2 1
      GraphicsApi.cpp
  20. 4 2
      GraphicsApi.h
  21. 9 1
      Iterator.h
  22. 5 212
      Texture.cpp
  23. 12 54
      Texture.h

+ 127 - 71
Array.h

@@ -88,15 +88,19 @@ namespace Framework
     {
     private:
         ArrayEntry<TYP>* current;
-        const std::function<ArrayEntry<TYP>*(ArrayEntry<TYP>* removed)>*
-            onRemove;
+        const std::function<void(TYP& removed)>* onRemove;
+        const std::function<void(int change)>* onSizeChanged;
+        const std::function<void(ArrayEntry<TYP>* last)>* onLastChanged;
 
     public:
         ArrayIterator(ArrayEntry<TYP>* start,
-            const std::function<ArrayEntry<TYP>*(ArrayEntry<TYP>* removed)>*
-                onRemove)
+            const std::function<void(TYP& removed)>* onRemove,
+            const std::function<void(int change)>* onSizeChanged,
+            const std::function<void(ArrayEntry<TYP>* last)>* onLastChanged)
         {
             this->onRemove = onRemove;
+            this->onSizeChanged = onSizeChanged;
+            this->onLastChanged = onLastChanged;
             current = start;
             while (current && !current->set)
             {
@@ -107,6 +111,8 @@ namespace Framework
         ArrayIterator(const ArrayIterator& it)
         {
             onRemove = it.onRemove;
+            onSizeChanged = it.onSizeChanged;
+            onLastChanged = it.onLastChanged;
             current = it.current;
         }
 
@@ -118,6 +124,8 @@ namespace Framework
         ArrayIterator<TYP>& operator=(ArrayIterator<TYP> r)
         {
             onRemove = r.onRemove;
+            onSizeChanged = r.onSizeChanged;
+            onLastChanged = r.onLastChanged;
             current = r.current;
             return *this;
         }
@@ -142,7 +150,8 @@ namespace Framework
                 err += __LINE__;
                 throw std::out_of_range(err);
             }
-            return ArrayIterator(current->next, onRemove);
+            return ArrayIterator(
+                current->next, onRemove, onSizeChanged, onLastChanged);
         }
 
         operator bool() override
@@ -184,10 +193,38 @@ namespace Framework
             return current->var;
         }
 
+        void addBefore(TYP val) override
+        {
+            if (current)
+            {
+                ArrayEntry<TYP>* newEntry = new ArrayEntry<TYP>();
+                newEntry->var = current->var;
+                newEntry->set = current->set;
+                newEntry->next = current->next;
+                if (!current->next)
+                {
+                    (*onLastChanged)(newEntry);
+                }
+                current->var = val;
+                current->set = true;
+                current->next = newEntry;
+                (*onSizeChanged)(1);
+            }
+            else
+            {
+                Text err = "Index out of Range Exception File: ";
+                err += __FILE__;
+                err += " Line: ";
+                err += __LINE__;
+                throw std::out_of_range(err);
+            }
+        }
+
         void set(TYP val) override
         {
             if (current)
             {
+                if (onRemove) (*onRemove)(current->var);
                 current->var = val;
                 current->set = true;
             }
@@ -206,9 +243,47 @@ namespace Framework
             return current != r.current;
         }
 
+        bool operator==(ArrayIterator<TYP>& r)
+        {
+            return current == r.current;
+        }
+
         void remove() override
         {
-            current = (*onRemove)(current);
+            if (!current)
+            {
+                Text err = "Index out of Range Exception File: ";
+                err += __FILE__;
+                err += " Line: ";
+                err += __LINE__;
+                throw std::out_of_range(err);
+            }
+            if (current->next)
+            {
+                if (onRemove) (*onRemove)(current->var);
+                current->var = current->next->var;
+                current->set = current->next->set;
+            }
+            else
+            {
+                if (onRemove) (*onRemove)(current->var);
+                current->set = 0;
+            }
+            ArrayEntry<TYP>* del = current->next;
+            if (current->next)
+                current->next = current->next->next;
+            else
+            {
+                (*onLastChanged)(current);
+                current->next = 0;
+            }
+            if (del)
+            {
+                del->set = 0;
+                del->next = 0;
+                delete del;
+            }
+            (*onSizeChanged)(-1);
         }
     };
 
@@ -222,7 +297,8 @@ namespace Framework
         ArrayEntry<TYP>* entries;
         ArrayEntry<TYP>* last;
         int count;
-        std::function<ArrayEntry<TYP>*(ArrayEntry<TYP>* removed)> onRemove;
+        std::function<void(int change)> onSizeChanged;
+        std::function<void(ArrayEntry<TYP>* last)> onLastChanged;
 
     public:
         //! Creates a new linked list
@@ -234,30 +310,9 @@ namespace Framework
             entries->next = 0;
             last = entries;
             count = 0;
-            onRemove = [this](ArrayEntry<TYP>* entry) {
-                if (!entry) return (ArrayEntry<TYP>*)0;
-                if (entry->next)
-                {
-                    entry->var = entry->next->var;
-                    entry->set = entry->next->set;
-                }
-                else
-                    entry->set = 0;
-                ArrayEntry<TYP>* del = entry->next;
-                if (entry->next)
-                    entry->next = entry->next->next;
-                else
-                    entry->next = 0;
-                if (del)
-                {
-                    del->set = 0;
-                    del->next = 0;
-                    if (last == del) last = entry;
-                    delete del;
-                }
-                count--;
-                return entry->set ? entry : 0;
-            };
+            onSizeChanged = [this](int change) { this->count += change; };
+            onLastChanged
+                = [this](ArrayEntry<TYP>* last) { this->last = last; };
         }
 
         //! Copies a linked list
@@ -359,7 +414,28 @@ namespace Framework
             ArrayEntry<TYP>* e = entries;
             for (int a = 0; a < i; ++a)
                 e = e->next;
-            onRemove(e);
+            if (e->next)
+            {
+                e->var = e->next->var;
+                e->set = e->next->set;
+            }
+            else
+
+                e->set = 0;
+
+            ArrayEntry<TYP>* del = e->next;
+            if (e->next)
+                e->next = e->next->next;
+            else
+                e->next = 0;
+            if (del)
+            {
+                del->set = 0;
+                del->next = 0;
+                if (last == del) last = e;
+                delete del;
+            }
+            count--;
         }
 
         //! Deletes a specific element by value
@@ -372,7 +448,6 @@ namespace Framework
                 if (!e->next) return;
                 e = e->next;
             }
-            if (!e) return;
             if (e->next)
             {
                 e->var = e->next->var;
@@ -425,12 +500,13 @@ namespace Framework
         //! Use ++ to iterate through the list
         ArrayIterator<TYP> begin() const
         {
-            return ArrayIterator<TYP>(entries, &onRemove);
+            return ArrayIterator<TYP>(
+                entries, 0, &onSizeChanged, &onLastChanged);
         }
 
         ArrayIterator<TYP> end() const
         {
-            return ArrayIterator<TYP>(0, &onRemove);
+            return ArrayIterator<TYP>(0, 0, &onSizeChanged, &onLastChanged);
         }
 
         //! Returns how many elements are in the list
@@ -514,8 +590,8 @@ namespace Framework
 
         Stream<TYP> stream()
         {
-            return Stream<TYP>(new IteratorSupplier<TYP>(
-                new ArrayIterator<TYP>(entries, &onRemove)));
+            return Stream<TYP>(new IteratorSupplier<TYP>(new ArrayIterator<TYP>(
+                entries, 0, &onSizeChanged, &onLastChanged)));
         }
     };
 
@@ -527,7 +603,9 @@ namespace Framework
         ArrayEntry<TYP*>* entries;
         ArrayEntry<TYP*>* last;
         int count;
-        std::function<ArrayEntry<TYP*>*(ArrayEntry<TYP*>* removed)> onRemove;
+        std::function<void(TYP*& removed)> onRemove;
+        std::function<void(int change)> onSizeChanged;
+        std::function<void(ArrayEntry<TYP*>* last)> onLastChanged;
 
     public:
         //! Creates a new linked list
@@ -540,35 +618,10 @@ namespace Framework
             entries->next = 0;
             last = entries;
             count = 0;
-            onRemove = [this](ArrayEntry<TYP*>* entry) {
-                if (!entry) return (ArrayEntry<TYP*>*)0;
-                if (entry->next)
-                {
-                    if (entry->set && entry->var) entry->var->release();
-                    entry->var = entry->next->var;
-                    entry->set = entry->next->set;
-                }
-                else
-                {
-                    if (entry->set && entry->var) entry->var->release();
-                    entry->set = 0;
-                }
-                ArrayEntry<TYP*>* del = entry->next;
-                if (entry->next)
-                    entry->next = entry->next->next;
-                else
-                    entry->next = 0;
-                if (del)
-                {
-                    del->var = 0;
-                    del->set = 0;
-                    del->next = 0;
-                    if (last == del) last = entry;
-                    delete del;
-                }
-                count--;
-                return entry->set ? entry : 0;
-            };
+            onRemove = [](TYP*& removed) { removed->release(); };
+            onSizeChanged = [this](int change) { this->count += change; };
+            onLastChanged
+                = [this](ArrayEntry<TYP*>* last) { this->last = last; };
         }
 
         //! Copies a linked list
@@ -727,12 +780,14 @@ namespace Framework
         //! Use ++ to iterate through the list
         ArrayIterator<TYP*> begin() const
         {
-            return ArrayIterator<TYP*>(entries, &onRemove);
+            return ArrayIterator<TYP*>(
+                entries, &onRemove, &onSizeChanged, &onLastChanged);
         }
 
         ArrayIterator<TYP*> end() const
         {
-            return ArrayIterator<TYP*>(0, &onRemove);
+            return ArrayIterator<TYP*>(
+                0, &onRemove, &onSizeChanged, &onLastChanged);
         }
 
         //! Returns how many elements are in the list
@@ -836,8 +891,9 @@ namespace Framework
 
         Stream<TYP*> stream()
         {
-            return Stream<TYP*>(new IteratorSupplier<TYP*>(
-                new ArrayIterator<TYP*>(entries, &onRemove)));
+            return Stream<TYP*>(
+                new IteratorSupplier<TYP*>(new ArrayIterator<TYP*>(
+                    entries, &onRemove, &onSizeChanged, &onLastChanged)));
         }
     };
 } // namespace Framework

+ 7 - 7
DX11GraphicsApi.cpp

@@ -7,11 +7,11 @@
 #include "DLLRegister.h"
 #include "DX11Buffer.h"
 #include "DX11Shader.h"
+#include "DX11Texture.h"
 #include "Globals.h"
 #include "Image.h"
 #include "Logging.h"
 #include "Screen.h"
-#include "Texture.h"
 #include "TextureList.h"
 #include "TextureModel.h"
 #include "UIPixelShader.h"
@@ -515,7 +515,7 @@ void DirectX11::initialize(
     renderB->setAlpha3D(1);
     renderB->newImage(this->backBufferSize.x, this->backBufferSize.y, 0);
 
-    uiTexture = createOrGetTexture("_f_Render_Image", renderB);
+    uiTexture = createOrGetTexture("_f_Render_Image", renderB, RAM_TO_GPU);
     ((DX11Texture*)uiTexture)->setUseMips(0);
 
     texturModel = new TextureModel(this, "_framework_gui_");
@@ -582,7 +582,7 @@ void DirectX11::initialize(
 
     Image* b = new Image();
     b->newImage(10, 10, 0xFFFFFFFF);
-    defaultTexture = createOrGetTexture("_default_textur", b);
+    defaultTexture = createOrGetTexture("_default_textur", b, RAM_TO_GPU);
 
     diffuseLights = new DX11StructuredBuffer(
         sizeof(DiffuseLight), d3d11Device, d3d11Context, deviceLock);
@@ -873,10 +873,9 @@ void DirectX11::renderKamera(Cam3D* zKamera, Texture* zTarget)
 {
     ID3D11RenderTargetView* texturRtView;
     DX11Texture* d11Textur = dynamic_cast<DX11Texture*>(zTarget);
-    if (!d11Textur)
+    if (!d11Textur || d11Textur->getDirection() != GPU_TO_RAM)
         throw "incompatible textur object was passed to renderKamera of "
               "DirectX11 GPU API";
-    d11Textur->setRenderTarget(1);
     if (d11Textur->needsUpdate()) d11Textur->updateTextur();
 
     D3D11_TEXTURE2D_DESC depthBufferDesc;
@@ -988,7 +987,8 @@ Image* DirectX11::zUIRenderImage() const
     return uiTexture->zImage();
 }
 
-Texture* DirectX11::createOrGetTexture(const char* name, Image* b)
+Texture* DirectX11::createOrGetTexture(
+    const char* name, Image* b, TextureDirection dir)
 {
     if (!d3d11Device)
     {
@@ -1001,7 +1001,7 @@ Texture* DirectX11::createOrGetTexture(const char* name, Image* b)
         if (b) ret->setImageZ(b);
         return ret;
     }
-    Texture* ret = new DX11Texture(d3d11Device, d3d11Context, deviceLock);
+    Texture* ret = new DX11Texture(d3d11Device, d3d11Context, deviceLock, dir);
     if (b) ret->setImageZ(b);
     texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
     return ret;

+ 1 - 1
DX11GraphicsApi.h

@@ -84,7 +84,7 @@ namespace Framework
         DLLEXPORT void renderKamera(Cam3D* zKamera, Texture* zTarget) override;
         DLLEXPORT void presentFrame() override;
         DLLEXPORT Texture* createOrGetTexture(
-            const char* name, Image* b) override;
+            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) override;

+ 199 - 0
DX11Texture.cpp

@@ -0,0 +1,199 @@
+#include "DX11Texture.h"
+
+#include "Image.h"
+#ifdef WIN32
+#    include <d3d11.h>
+#endif
+
+using namespace Framework;
+
+DX11Texture::DX11Texture(ID3D11Device* device,
+    ID3D11DeviceContext* context,
+    Critical& deviceLock,
+    TextureDirection dir)
+    : Texture(dir),
+      txt(0),
+      view(0),
+      device(device),
+      context(context),
+      useMips(dir == RAM_TO_GPU),
+      deviceLock(deviceLock),
+      readAccessTexture(0)
+{}
+
+DX11Texture::~DX11Texture()
+{
+#ifdef WIN32
+    if (txt) txt->Release();
+    if (view) view->Release();
+    if (readAccessTexture) readAccessTexture->Release();
+#endif
+}
+
+// Updates the texture. The pixels of the current image are copied into
+// the graphics memory
+bool DX11Texture::updateTextur()
+{
+    if (!bild) return 0;
+#ifdef WIN32
+    if (!txt || lastGr != bild->getSize())
+    {
+        if (txt) txt->Release();
+        txt = 0;
+        D3D11_TEXTURE2D_DESC bufferDesc;
+        memset(&bufferDesc, 0, sizeof(D3D11_TEXTURE2D_DESC));
+        bufferDesc.ArraySize = 1;
+        bufferDesc.Width = bild->getWidth();
+        bufferDesc.Height = bild->getHeight();
+        bufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+        bufferDesc.BindFlags = (getDirection() == GPU_TO_RAM || useMips
+                                       ? D3D11_BIND_RENDER_TARGET
+                                       : 0)
+                             | D3D11_BIND_SHADER_RESOURCE;
+        bufferDesc.CPUAccessFlags = getDirection() == GPU_TO_RAM || useMips
+                                      ? 0
+                                      : D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.SampleDesc.Count = 1;
+        bufferDesc.MipLevels = useMips ? 0 : 1;
+        bufferDesc.Usage = getDirection() == GPU_TO_RAM || useMips
+                             ? D3D11_USAGE_DEFAULT
+                             : D3D11_USAGE_DYNAMIC;
+        bufferDesc.MiscFlags = useMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;
+        deviceLock.lock();
+        HRESULT r = device->CreateTexture2D(&bufferDesc, 0, &txt);
+        deviceLock.unlock();
+        if (r != S_OK) return 0;
+    }
+    if (getDirection() == RAM_TO_GPU && (bild->getNeedRender() || changed))
+    {
+        changed = 0;
+        if (useMips)
+        {
+            deviceLock.lock();
+            context->UpdateSubresource(txt,
+                0,
+                0,
+                bild->getBuffer(),
+                4 * bild->getWidth(),
+                4 * bild->getWidth() * bild->getHeight());
+            deviceLock.unlock();
+        }
+        else
+        {
+            D3D11_MAPPED_SUBRESOURCE buffer;
+            deviceLock.lock();
+            context->Map(
+                txt, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &buffer);
+            int* bgBuff = bild->getBuffer();
+            int tmpBr = 4 * bild->getWidth();
+            for (int y = 0, pitch = 0, bry = 0; y < bild->getHeight();
+                ++y, pitch += buffer.RowPitch, bry += bild->getWidth())
+            {
+                memcpy(&((BYTE*)buffer.pData)[pitch],
+                    (void*)&(bgBuff[bry]),
+                    tmpBr);
+            }
+            context->Unmap(txt, 0);
+            deviceLock.unlock();
+        }
+    }
+    else if (getDirection() == GPU_TO_RAM)
+    {
+        if (!readAccessTexture || lastGr != bild->getSize())
+        {
+            if (readAccessTexture) readAccessTexture->Release();
+            readAccessTexture = 0;
+            D3D11_TEXTURE2D_DESC tempBufferDesc;
+            memset(&tempBufferDesc, 0, sizeof(D3D11_TEXTURE2D_DESC));
+            tempBufferDesc.ArraySize = 1;
+            tempBufferDesc.Width = bild->getWidth();
+            tempBufferDesc.Height = bild->getHeight();
+            tempBufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+            tempBufferDesc.BindFlags = 0;
+            tempBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+            tempBufferDesc.SampleDesc.Count = 1;
+            tempBufferDesc.MipLevels = 1;
+            tempBufferDesc.Usage = D3D11_USAGE_STAGING;
+            deviceLock.lock();
+            HRESULT r = device->CreateTexture2D(
+                &tempBufferDesc, 0, &readAccessTexture);
+            deviceLock.unlock();
+            if (r != S_OK) return 0;
+        }
+        else
+        {
+            deviceLock.lock();
+            context->CopyResource(readAccessTexture, txt);
+            deviceLock.unlock();
+            D3D11_MAPPED_SUBRESOURCE buffer;
+            deviceLock.lock();
+            HRESULT r = context->Map(
+                readAccessTexture, 0, D3D11_MAP::D3D11_MAP_READ, 0, &buffer);
+            deviceLock.unlock();
+            if (r != S_OK) return 0;
+            int* bgBuff = bild->getBuffer();
+            int tmpBr = 4 * bild->getWidth();
+            for (int y = 0, pitch = 0, bry = 0; y < bild->getHeight();
+                ++y, pitch += buffer.RowPitch, bry += bild->getWidth())
+            {
+                memcpy((void*)&(bgBuff[bry]),
+                    &((BYTE*)buffer.pData)[pitch],
+                    tmpBr);
+            }
+            for (int i = 0; i < bild->getWidth() * bild->getHeight(); i++)
+            {
+                if (bgBuff[i]) bgBuff[i] |= 0xFF000000;
+            }
+            deviceLock.lock();
+            context->Unmap(readAccessTexture, 0);
+            deviceLock.unlock();
+        }
+    }
+    if (!view || lastGr != bild->getSize())
+    {
+        if (view) view->Release();
+        view = 0;
+        D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesk;
+        memset(&resourceDesk, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
+        resourceDesk.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+        resourceDesk.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+        resourceDesk.Texture2D.MipLevels = useMips ? -1 : 1;
+        deviceLock.lock();
+        HRESULT r = device->CreateShaderResourceView(txt, &resourceDesk, &view);
+        deviceLock.unlock();
+        if (r != S_OK) return 0;
+        if (context && useMips)
+        {
+            deviceLock.lock();
+            context->GenerateMips(view);
+            deviceLock.unlock();
+        }
+    }
+    lastGr = bild->getSize();
+#endif
+    return 1;
+}
+
+// Returns true if updateTextur needs to be called
+bool DX11Texture::needsUpdate() const
+{
+    return !view;
+}
+
+// Returns the used shader resource view
+DX11Texture::operator ID3D11ShaderResourceView*() const
+{
+    return view;
+}
+
+//! Returns the used texture
+DX11Texture::operator ID3D11Texture2D*() const
+{
+    return txt;
+}
+
+//! specifies if a mip map should be generated
+void DX11Texture::setUseMips(bool useMips)
+{
+    this->useMips = useMips;
+}

+ 41 - 0
DX11Texture.h

@@ -0,0 +1,41 @@
+#pragma once
+
+#include "Texture.h"
+
+struct ID3D11Texture2D;
+struct ID3D11ShaderResourceView;
+struct ID3D11Device;
+struct ID3D11DeviceContext;
+
+namespace Framework
+{
+    class DX11Texture : public Texture
+    {
+    private:
+        ID3D11Texture2D* txt;
+        ID3D11ShaderResourceView* view;
+        ID3D11Device* device;
+        ID3D11DeviceContext* context;
+        bool useMips;
+        Critical& deviceLock;
+        ID3D11Texture2D* readAccessTexture;
+
+    public:
+        DLLEXPORT DX11Texture(ID3D11Device* device,
+            ID3D11DeviceContext* context,
+            Critical& deviceLock,
+            TextureDirection dir);
+        DLLEXPORT ~DX11Texture();
+        //! Updates the texture. The pixels of the current image are copied
+        //! to graphics memory
+        DLLEXPORT bool updateTextur() override;
+        //! Returns true if updateTextur needs to be called
+        DLLEXPORT bool needsUpdate() const override;
+        //! Returns the used shader resource view
+        DLLEXPORT operator ID3D11ShaderResourceView*() const;
+        //! Returns the used texture
+        DLLEXPORT operator ID3D11Texture2D*() const;
+        //! specifies if a mip map should be generated
+        DLLEXPORT void setUseMips(bool useMips);
+    };
+} // namespace Framework

+ 12 - 11
DX12GraphicsApi.cpp

@@ -44,13 +44,13 @@ DirectX12::DirectX12()
       vertexBufferView(0),
       indexBufferView(0),
       signature(0),
-      texturModel(0),
       uiTexture(0),
       texturRegister(new TextureList()),
       blasModels(0),
       worldTLAS(0),
       lastTLASId(-1),
-      lastModelId(-1)
+      lastModelId(-1),
+      defaultRenderTarget(0)
 {
     for (int i = 0; i < 2; i++)
         backBuffer[i] = 0;
@@ -93,7 +93,7 @@ DirectX12::~DirectX12()
     if (dsvHeap) dsvHeap->Release();
     texturRegister->release();
     if (uiTexture) uiTexture->release();
-    if (texturModel) texturModel->release();
+    if (defaultRenderTarget) defaultRenderTarget->release();
     if (signature) signature->Release();
     delete indexBufferView;
     delete vertexBufferView;
@@ -484,6 +484,11 @@ void DirectX12::initialize(
         rtvHandle.ptr += rtvDescriptorSize;
     }
 
+    Image* renderTargetImage = new Image();
+    renderTargetImage->newImage(backBufferSize.x, backBufferSize.y, 0);
+    defaultRenderTarget = dynamic_cast<DX12Texture*>(
+        createOrGetTexture("_f_RenderTarget", renderTargetImage, GPU_TO_RAM));
+
     viewPort = new D3D12_VIEWPORT();
     viewPort->Width = (float)this->backBufferSize.x;
     viewPort->Height = (float)this->backBufferSize.y;
@@ -498,15 +503,10 @@ void DirectX12::initialize(
     allowedRenderArea->right = LONG_MAX;
     allowedRenderArea->bottom = LONG_MAX;
 
-    texturModel = new TextureModel(this, "_framework_gui_");
-
     Image* renderB = new Image(1);
     renderB->setAlpha3D(1);
     renderB->newImage(this->backBufferSize.x, this->backBufferSize.y, 0);
-    uiTexture = createOrGetTexture("_f_Render_Image", renderB);
-
-    texturModel->setSize(Vec2<float>(2.f, 2.f));
-    texturModel->setTexture(dynamic_cast<Texture*>(uiTexture->getThis()));
+    uiTexture = createOrGetTexture("_f_Render_Image", renderB, RAM_TO_GPU);
 
     vertexBufferView = new D3D12_VERTEX_BUFFER_VIEW();
     vertexBufferView->StrideInBytes = sizeof(Vertex3D);
@@ -818,7 +818,8 @@ void DirectX12::presentFrame()
     backBufferIndex = swapChain->GetCurrentBackBufferIndex();
 }
 
-Texture* DirectX12::createOrGetTexture(const char* name, Image* b)
+Texture* DirectX12::createOrGetTexture(
+    const char* name, Image* b, TextureDirection dir)
 {
     if (!device)
     {
@@ -832,7 +833,7 @@ Texture* DirectX12::createOrGetTexture(const char* name, Image* b)
         return ret;
     }
     Texture* ret
-        = new DX12Texture(device, copyCommandQueue, directCommandQueue);
+        = new DX12Texture(device, copyCommandQueue, directCommandQueue, dir);
     if (b) ret->setImageZ(b);
     texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
     ret->updateTextur();

+ 3 - 2
DX12GraphicsApi.h

@@ -36,6 +36,7 @@ namespace Framework
     class TextureList;
     class TextureModel;
     class DX12TLAS;
+    class DX12Texture;
 
     class DirectX12 : public GraphicsApi
     {
@@ -61,13 +62,13 @@ namespace Framework
         Mat4<float> matrixBuffer[MAX_KNOCHEN_ANZ];
         Mat4<float> viewAndProj[2];
         Vec3<float> kamPos;
-        TextureModel* texturModel;
         Texture* uiTexture;
         TextureList* texturRegister;
         DX12BLASModel** blasModels;
         DX12TLAS** worldTLAS;
         int lastTLASId;
         int lastModelId;
+        DX12Texture* defaultRenderTarget;
 
         DLLEXPORT void updateBottomLevelAccelerationStructure();
 
@@ -86,7 +87,7 @@ namespace Framework
         //! ) override;
         DLLEXPORT void presentFrame() override;
         DLLEXPORT Texture* createOrGetTexture(
-            const char* name, Image* b) override;
+            const char* name, Image* b, TextureDirection dir) override;
         DLLEXPORT Image* zUIRenderImage() const override;
         DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) override;
 

+ 271 - 16
DX12Shader.cpp

@@ -1,5 +1,7 @@
 #include "DX12Shader.h"
 
+#include "DX12Texture.h"
+#include "DX12TLAS.h"
 #include "Logging.h"
 
 using namespace Framework;
@@ -18,16 +20,47 @@ Framework::DX12ShaderSignature::~DX12ShaderSignature()
     }
 }
 
-void Framework::DX12ShaderSignature::addRegisterUsage(
-    DX12ShaderRegister registerType, int registerIndex)
-{
-    addRegisterUsage(registerType, registerIndex, 0);
-}
-
 void Framework::DX12ShaderSignature::addRegisterUsage(
     DX12ShaderRegister registerType, int registerIndex, int spaceIndex)
 {
-    registerUsages.add({registerType, registerIndex, spaceIndex});
+    // register usages sould be sorted by registerType -> spaceIndex ->
+    // registerIndex
+    ArrayIterator<DX12ShaderRegisterUsage> it = registerUsages.begin();
+    bool found = 0;
+    while (it)
+    {
+        const DX12ShaderRegisterUsage& usage = it.val();
+        if (usage.registerType > registerType)
+        {
+            found = 1;
+            break;
+        }
+        if (usage.registerType == registerType)
+        {
+            if (usage.spaceIndex > spaceIndex)
+            {
+                found = 1;
+                break;
+            }
+            if (usage.spaceIndex == spaceIndex)
+            {
+                if (usage.registerIndex >= registerIndex)
+                {
+                    found = 1;
+                    break;
+                }
+            }
+        }
+        ++it;
+    }
+    if (found)
+    {
+        it.addBefore({registerType, registerIndex, spaceIndex});
+    }
+    else
+    {
+        registerUsages.add({registerType, registerIndex, spaceIndex});
+    }
     changed = 1;
 }
 
@@ -52,8 +85,10 @@ void Framework::DX12ShaderSignature::createSignature(ID3D12Device5* zDevice,
     D3D12_DESCRIPTOR_RANGE* descriptorRanges
         = new D3D12_DESCRIPTOR_RANGE[registerUsages.getEntryCount()];
     int index = 0;
-    for (const auto& usage : registerUsages)
+    ArrayIterator<DX12ShaderRegisterUsage> it = registerUsages.begin();
+    while (it)
     {
+        const auto& usage = it.val();
         D3D12_DESCRIPTOR_RANGE* range = &descriptorRanges[index];
         switch (usage.registerType)
         {
@@ -71,13 +106,21 @@ void Framework::DX12ShaderSignature::createSignature(ID3D12Device5* zDevice,
                              << usage.registerType;
             range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
         }
-        range->NumDescriptors
-            = 1; // TODO: optimize when multiple descriptors are used in a row
-                 // e.g. u0, u1, u2 with the same range then NumDescriptors can
-                 // be 3 for u0 and u1 and u2 would not be needed in this array
+        ArrayIterator<DX12ShaderRegisterUsage> next = it.next();
+        int size = 1;
+        while (next && next.val().registerType == usage.registerType
+               && next.val().spaceIndex == usage.spaceIndex
+               && next.val().registerIndex == usage.registerIndex + size)
+        {
+            ++size;
+            it = next;
+            ++next;
+        }
+        range->NumDescriptors = size;
         range->BaseShaderRegister = usage.registerIndex;
         range->RegisterSpace = usage.spaceIndex;
         range->OffsetInDescriptorsFromTableStart = index;
+        ++it;
         index++;
     }
     descriptorTable.DescriptorTable.pDescriptorRanges = descriptorRanges;
@@ -115,6 +158,17 @@ ID3D12RootSignature* Framework::DX12ShaderSignature::zSignature() const
     return signature;
 }
 
+const Array<DX12ShaderRegisterUsage>&
+Framework::DX12ShaderSignature::getRegisterUsagesOrder() const
+{
+    return registerUsages;
+}
+
+ShaderHeap* Framework::DX12ShaderSignature::createShaderHeap()
+{
+    return new ShaderHeap(dynamic_cast<DX12ShaderSignature*>(getThis()));
+}
+
 Framework::DX12ShaderFunction::DX12ShaderFunction(
     const Text& functionName, DX12ShaderSignature* signature)
     : ReferenceCounter(),
@@ -611,9 +665,9 @@ void Framework::DX12Pipeline::createPipelineState(ID3D12Device5* zDevice,
             }
         }
     }
-    wchar_t** functionAndHitGroupNames
-        = new wchar_t*[functionsWithoutHitGroups.getEntryCount()
-                       + hitGroups.getEntryCount()];
+    const wchar_t** functionAndHitGroupNames
+        = new const wchar_t*[functionsWithoutHitGroups.getEntryCount()
+                             + hitGroups.getEntryCount()];
     int nameIndex = 0;
     for (const DX12ShaderFunction* function : functionsWithoutHitGroups)
     {
@@ -776,4 +830,205 @@ void Framework::DX12Pipeline::createPipelineState(ID3D12Device5* zDevice,
 ID3D12StateObject* Framework::DX12Pipeline::zPipelineState() const
 {
     return pipelineState;
-}
+}
+
+Framework::ShaderHeap::ShaderHeap(DX12ShaderSignature* signature)
+    : ReferenceCounter(),
+      signature(signature),
+      descriptorHeap(0),
+      lastDescriptorHeapSize(0)
+{}
+
+Framework::ShaderHeap::~ShaderHeap()
+{
+    signature->release();
+    if (descriptorHeap)
+    {
+        descriptorHeap->Release();
+    }
+    for (const DX12ShaderRegisterInput* input : registerInputs)
+    {
+        input->inputResource->release();
+        delete input;
+    }
+}
+
+void Framework::ShaderHeap::setRegisterInput(DX12ShaderRegister registerType,
+    int registerIndex,
+    int spaceIndex,
+    ReferenceCounter* inputResource)
+{
+    for (DX12ShaderRegisterInput* input : registerInputs)
+    {
+        if (input->registerIndex == registerIndex
+            && input->spaceIndex == spaceIndex
+            && input->registerType == registerType)
+        {
+            input->inputResource->release();
+            input->inputResource = inputResource->getThis();
+            return;
+        }
+    }
+    bool found = 0;
+    for (const DX12ShaderRegisterUsage& usage :
+        signature->getRegisterUsagesOrder())
+    {
+        if (usage.registerIndex == registerIndex
+            && usage.spaceIndex == spaceIndex
+            && usage.registerType == registerType)
+        {
+            found = 1;
+            break;
+        }
+    }
+    if (found)
+    {
+        registerInputs.add(new DX12ShaderRegisterInput{
+            registerType, registerIndex, spaceIndex, inputResource->getThis()});
+    }
+    else
+    {
+        Logging::error() << "Register type " << registerType
+                         << ", register index " << registerIndex
+                         << ", space index " << spaceIndex
+                         << " is not used in the shader signature. The given "
+                            "input will be ignored.";
+    }
+}
+
+void Framework::ShaderHeap::setRegisterInput(
+    Texture* zTexture, int registerIndex, int spaceIndex)
+{
+    setRegisterInput(DX12_SHADER_REGISTER_U_UNORDERED_ACCESS,
+        registerIndex,
+        spaceIndex,
+        zTexture);
+}
+
+void Framework::ShaderHeap::setRegisterInput(
+    DXBuffer* zBuffer, int registerIndex, int spaceIndex)
+{
+    setRegisterInput(DX12_SHADER_REGISTER_B_CONST_BUFFER,
+        registerIndex,
+        spaceIndex,
+        zBuffer);
+}
+
+void Framework::ShaderHeap::setRegisterInput(
+    DX12TLAS* zTLAS, int registerIndex, int spaceIndex)
+{
+    setRegisterInput(DX12_SHADER_REGISTER_T_SHADER_RESOURCE,
+        registerIndex,
+        spaceIndex,
+        zTLAS);
+}
+
+void Framework::ShaderHeap::updateDescriptorHeap(ID3D12Device5* zDevice)
+{
+    const Array<DX12ShaderRegisterUsage>& registerUsages
+        = signature->getRegisterUsagesOrder();
+    if (!descriptorHeap
+        || lastDescriptorHeapSize
+               != signature->getRegisterUsagesOrder().getEntryCount())
+    {
+        if (descriptorHeap)
+        {
+            descriptorHeap->Release();
+        }
+        D3D12_DESCRIPTOR_HEAP_DESC desc = {};
+        desc.NumDescriptors = registerUsages.getEntryCount();
+        desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
+        desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
+        desc.NodeMask = 0;
+
+        HRESULT r = zDevice->CreateDescriptorHeap(
+            &desc, __uuidof(ID3D12DescriptorHeap), (void**)&descriptorHeap);
+        lastDescriptorHeapSize = registerUsages.getEntryCount();
+    }
+
+    D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
+        = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
+    ArrayIterator<DX12ShaderRegisterUsage> it = registerUsages.begin();
+    while (it)
+    {
+        const DX12ShaderRegisterUsage& usage = it.val();
+        ArrayIterator<DX12ShaderRegisterInput*> inputIt
+            = registerInputs.begin();
+        bool found = 0;
+        while (inputIt)
+        {
+            if (inputIt->registerType == usage.registerType
+                && inputIt->registerIndex == usage.registerIndex
+                && inputIt->spaceIndex == usage.spaceIndex)
+            {
+                switch (inputIt->registerType)
+                {
+                case DX12_SHADER_REGISTER_B_CONST_BUFFER:
+                    D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
+                    DX12Buffer* buffer
+                        = dynamic_cast<DX12Buffer*>(inputIt->inputResource);
+                    cbvDesc.BufferLocation
+                        = buffer->zBuffer()->GetGPUVirtualAddress();
+                    cbvDesc.SizeInBytes = buffer->getElementCount()
+                                        * buffer->getElementLength();
+                    zDevice->CreateConstantBufferView(
+                        &cbvDesc, descriptorHeapHandle);
+                    break;
+                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.Shader4ComponentMapping
+                        = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+                    srvDesc.RaytracingAccelerationStructure.Location
+                        = dynamic_cast<DX12TLAS*>(inputIt->inputResource)
+                              ->zResultBuffer()
+                              ->zBuffer()
+                              ->GetGPUVirtualAddress();
+                    zDevice->CreateShaderResourceView(
+                        0, &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(
+                        dynamic_cast<DX12Texture*>(inputIt->inputResource)
+                            ->zResource(),
+                        0,
+                        &uavDesc,
+                        descriptorHeapHandle);
+                    break;
+                default:
+                    Logging::error()
+                        << "Unknown register type for descriptor heap: "
+                        << inputIt->registerType;
+                }
+                found = 1;
+                break;
+            }
+            ++inputIt;
+        }
+        if (!found)
+        {
+            Logging::error()
+                << "No input resource found for register type "
+                << usage.registerType << ", register index "
+                << usage.registerIndex << ", space index " << usage.spaceIndex
+                << ". This will result in an uninitialized descriptor in the "
+                   "descriptor heap. Access to the register in the shader "
+                   "might lead to undefined behaviour.";
+        }
+        descriptorHeapHandle.ptr += zDevice->GetDescriptorHandleIncrementSize(
+            D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+        ++it;
+    }
+}
+
+ID3D12DescriptorHeap* Framework::ShaderHeap::zDescriptorHeap() const
+{
+    return descriptorHeap;
+}

+ 50 - 13
DX12Shader.h

@@ -11,6 +11,9 @@ struct D3D12_CONSTANT_BUFFER_VIEW_DESC;
 
 namespace Framework
 {
+    class Texture;
+    class DX12TLAS;
+
     enum DX12ShaderRegister
     {
         DX12_SHADER_REGISTER_B_CONST_BUFFER = 0,
@@ -26,6 +29,8 @@ namespace Framework
         int spaceIndex;
     };
 
+    class ShaderHeap;
+
     class DX12ShaderSignature : public ReferenceCounter
     {
     private:
@@ -42,26 +47,20 @@ namespace Framework
          * \param registerType the register type e.g.
          * DX12_SHADER_REGISTER_B_CONST_BUFFER for : register(b0)
          * \param registerIndex the register index e.g. 1 for : register(b1)
+         * \param spaceIndex the optional space index e.g. 3 for : register(b1,
+         * space3)
          */
-        void addRegisterUsage(
-            DX12ShaderRegister registerType, int registerIndex);
-        /**
-         * needs to be called for each datastructure with : register(...)
-         *
-         * \param registerType the register type e.g.
-         * DX12_SHADER_REGISTER_B_CONST_BUFFER for : register(b0, space1)
-         * \param registerIndex the register index e.g. 1 for : register(b1,
-         * space2)
-         * \param spaceIndex the space index e.g. 3 for : register(b1, space3)
-         */
-        void addRegisterUsage(
-            DX12ShaderRegister registerType, int registerIndex, int spaceIndex);
+        void addRegisterUsage(DX12ShaderRegister registerType,
+            int registerIndex,
+            int spaceIndex = 0);
         /**
          * Creates the root signature.
          */
         void createSignature(ID3D12Device5* zDevice,
             PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature);
         ID3D12RootSignature* zSignature() const;
+        const Array<DX12ShaderRegisterUsage>& getRegisterUsagesOrder() const;
+        ShaderHeap* createShaderHeap();
     };
 
     class DX12ShaderFunction : public ReferenceCounter
@@ -148,4 +147,42 @@ namespace Framework
             PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature);
         ID3D12StateObject* zPipelineState() const;
     }; // namespace Framework
+
+    struct DX12ShaderRegisterInput
+    {
+        DX12ShaderRegister registerType;
+        int registerIndex;
+        int spaceIndex;
+        ReferenceCounter*
+            inputResource; // Can be Texture*, DXBuffer*, or DX12TLAS*
+    };
+
+    class ShaderHeap : public ReferenceCounter
+    {
+    private:
+        DX12ShaderSignature* signature;
+        ID3D12DescriptorHeap* descriptorHeap;
+        Array<DX12ShaderRegisterInput*> registerInputs;
+        int lastDescriptorHeapSize;
+
+    public:
+        ShaderHeap(DX12ShaderSignature* signature);
+        ~ShaderHeap();
+
+    private:
+        void setRegisterInput(DX12ShaderRegister registerType,
+            int registerIndex,
+            int spaceIndex,
+            ReferenceCounter* inputResource);
+
+    public:
+        void setRegisterInput(
+            Texture* zTexture, int registerIndex, int spaceIndex = 0);
+        void setRegisterInput(
+            DXBuffer* zBuffer, int registerIndex, int spaceIndex = 0);
+        void setRegisterInput(
+            DX12TLAS* zTLAS, int registerIndex, int spaceIndex = 0);
+        void updateDescriptorHeap(ID3D12Device5* zDevice);
+        ID3D12DescriptorHeap* zDescriptorHeap() const;
+    };
 } // namespace Framework

+ 1 - 1
DX12TLAS.cpp

@@ -11,7 +11,7 @@ Framework::DX12TLAS::DX12TLAS(
       previousResultBuffer(0),
       zDevice(zDevice),
       zDirectQueue(zDirectQueue),
-      overflowInstanceIterator(0, 0),
+      overflowInstanceIterator(0, 0, 0, 0),
       currentInstanceIndex(0),
       mappedDescriptorBuffer(0)
 {}

+ 16 - 13
DX12Texture.cpp

@@ -8,21 +8,19 @@ using namespace Framework;
 
 DX12Texture::DX12Texture(ID3D12Device* device,
     DX12CopyCommandQueue* copy,
-    DX12DirectCommandQueue* direct)
-    : Texture(),
+    DX12DirectCommandQueue* direct,
+    TextureDirection dir)
+    : Texture(dir),
       buffer(0),
-      intermediate(0),
       device(device),
       copy(copy),
-      direct(direct),
-      shaderResource(0)
+      direct(direct)
 {}
 
 DX12Texture::~DX12Texture()
 {
 #ifdef WIN32
     if (buffer) buffer->Release();
-    if (intermediate) intermediate->Release();
 #endif
 }
 
@@ -44,7 +42,9 @@ bool DX12Texture::updateTextur()
         description.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
         description.SampleDesc.Count = 1;
         description.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
-        description.Flags = D3D12_RESOURCE_FLAG_NONE;
+        description.Flags = getDirection() == GPU_TO_RAM
+                              ? D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
+                              : D3D12_RESOURCE_FLAG_NONE;
         D3D12_HEAP_PROPERTIES hprop;
         hprop.Type = D3D12_HEAP_TYPE_DEFAULT;
         hprop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
@@ -54,11 +54,14 @@ bool DX12Texture::updateTextur()
         device->CreateCommittedResource(&hprop,
             D3D12_HEAP_FLAG_NONE,
             &description,
-            D3D12_RESOURCE_STATE_COPY_DEST,
+            getDirection() == RAM_TO_GPU ? D3D12_RESOURCE_STATE_COPY_DEST
+                                         : D3D12_RESOURCE_STATE_COPY_SOURCE,
             0,
             __uuidof(ID3D12Resource),
             (void**)&buffer);
-        const UINT64 uploadBufferSize
+        // 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;
@@ -80,9 +83,9 @@ bool DX12Texture::updateTextur()
             0,
             __uuidof(ID3D12Resource),
             (void**)&intermediate);
-        shaderResource = 0;
+        shaderResource = 0;*/
     }
-    if (bild && (changed || bild->getNeedRender()))
+    /* if (bild && (changed || bild->getNeedRender()))
     {
         changed = 0;
         if (shaderResource)
@@ -121,7 +124,7 @@ bool DX12Texture::updateTextur()
         barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
         direct->zCommandList()->ResourceBarrier(1, &barrier);
         shaderResource = 1;
-    }
+    }*/
 #endif
     return 1;
 }
@@ -133,7 +136,7 @@ bool DX12Texture::needsUpdate() const
 }
 
 // Returns the DX12 resource
-ID3D12Resource* DX12Texture::getResource()
+ID3D12Resource* DX12Texture::zResource()
 {
     return buffer;
 }

+ 6 - 6
DX12Texture.h

@@ -3,26 +3,26 @@
 #include "Texture.h"
 
 struct ID3D12Device;
-struct D3D12_RESOURCE_DESC;
 struct ID3D12Resource;
-struct ID3D12GraphicsCommandList;
 
 namespace Framework
 {
+    class DX12CopyCommandQueue;
+    class DX12DirectCommandQueue;
+
     class DX12Texture : public Texture
     {
     private:
         ID3D12Resource* buffer;
-        ID3D12Resource* intermediate;
         ID3D12Device* device;
         DX12CopyCommandQueue* copy;
         DX12DirectCommandQueue* direct;
-        bool shaderResource;
 
     public:
         DLLEXPORT DX12Texture(ID3D12Device* device,
             DX12CopyCommandQueue* copy,
-            DX12DirectCommandQueue* direct);
+            DX12DirectCommandQueue* direct,
+            TextureDirection dir);
         DLLEXPORT ~DX12Texture();
         //! Updates the texture. The pixels of the current image are copied
         //! to graphics memory
@@ -30,6 +30,6 @@ namespace Framework
         //! Returns true if updateTextur needs to be called
         DLLEXPORT bool needsUpdate() const override;
         //! Returns the DX12 resource
-        DLLEXPORT ID3D12Resource* getResource();
+        DLLEXPORT ID3D12Resource* zResource();
     };
 } // namespace Framework

+ 4 - 3
DX9GraphicsApi.cpp

@@ -4,10 +4,10 @@
 
 #include "Camera3D.h"
 #include "DLLRegister.h"
+#include "DX9Texture.h"
 #include "Globals.h"
 #include "Image.h"
 #include "Screen.h"
-#include "Texture.h"
 #include "Timer.h"
 #include "Window.h"
 #include "World3D.h"
@@ -193,9 +193,10 @@ void DirectX9::presentFrame()
     }
 }
 
-Texture* DirectX9::createOrGetTexture(const char* name, Image* b)
+Texture* DirectX9::createOrGetTexture(
+    const char* name, Image* b, TextureDirection dir)
 {
-    Texture* ret = new DX9Texture();
+    Texture* ret = new DX9Texture(dir);
     ret->setImageZ(b);
     return ret;
 }

+ 1 - 1
DX9GraphicsApi.h

@@ -39,7 +39,7 @@ namespace Framework
         DLLEXPORT void renderKamera(Cam3D* zKamera) override;
         DLLEXPORT void presentFrame() override;
         DLLEXPORT Texture* createOrGetTexture(
-            const char* name, Image* b) override;
+            const char* name, Image* b, TextureDirection dir) override;
         DLLEXPORT Image* zUIRenderImage() const override;
 
         DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) override;

+ 20 - 0
DX9Texture.cpp

@@ -0,0 +1,20 @@
+#include "DX9Texture.h"
+
+using namespace Framework;
+
+Framework::DX9Texture::DX9Texture(TextureDirection dir)
+    : Texture(dir)
+{}
+
+// Updates the texture. The pixels of the current image are copied into
+// the graphics memory
+bool DX9Texture::updateTextur()
+{
+    return 1;
+}
+
+// Returns true if updateTextur needs to be called
+bool DX9Texture::needsUpdate() const
+{
+    return 0;
+}

+ 19 - 0
DX9Texture.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "Texture.h"
+
+namespace Framework
+{
+    //! Converts an image to a texture that can be passed to the graphics
+    //! card for rendering
+    class DX9Texture : public Texture
+    {
+    public:
+        DX9Texture(TextureDirection dir);
+        //! Updates the texture. The pixels of the current image are copied
+        //! to graphics memory
+        DLLEXPORT virtual bool updateTextur() override;
+        //! Returns true if updateTextur needs to be called
+        DLLEXPORT virtual bool needsUpdate() const override;
+    };
+} // namespace Framework

+ 4 - 0
Framework.vcxproj

@@ -208,11 +208,13 @@ copy "x64\Release\Framework.dll" "..\..\Spiele Platform\SMP\Fertig\x64\framework
     <ClInclude Include="DX11Buffer.h" />
     <ClInclude Include="DX11GraphicsApi.h" />
     <ClInclude Include="DX11Shader.h" />
+    <ClInclude Include="DX11Texture.h" />
     <ClInclude Include="DX12BLAS.h" />
     <ClInclude Include="DX12BLASModel.h" />
     <ClInclude Include="DX12GraphicsApi.h" />
     <ClInclude Include="DX12TLAS.h" />
     <ClInclude Include="DX9GraphicsApi.h" />
+    <ClInclude Include="DX9Texture.h" />
     <ClInclude Include="SelectionBox.h" />
     <ClInclude Include="Console.h" />
     <ClInclude Include="DataValidator.h" />
@@ -323,9 +325,11 @@ copy "x64\Release\Framework.dll" "..\..\Spiele Platform\SMP\Fertig\x64\framework
     <ClCompile Include="AsynchronCall.cpp" />
     <ClCompile Include="DX11Buffer.cpp" />
     <ClCompile Include="DX11Shader.cpp" />
+    <ClCompile Include="DX11Texture.cpp" />
     <ClCompile Include="DX12BLAS.cpp" />
     <ClCompile Include="DX12BLASModel.cpp" />
     <ClCompile Include="DX12TLAS.cpp" />
+    <ClCompile Include="DX9Texture.cpp" />
     <ClCompile Include="SelectionBox.cpp" />
     <ClCompile Include="Console.cpp" />
     <ClCompile Include="DataValidator.cpp" />

+ 18 - 6
Framework.vcxproj.filters

@@ -217,9 +217,6 @@
     <ClInclude Include="World3D.h">
       <Filter>Framework\Graphics\3D</Filter>
     </ClInclude>
-    <ClInclude Include="Texture.h">
-      <Filter>Framework\Graphics\3D</Filter>
-    </ClInclude>
     <ClInclude Include="DXBuffer.h">
       <Filter>Framework\Graphics\DX</Filter>
     </ClInclude>
@@ -421,6 +418,15 @@
     <ClInclude Include="DX12TLAS.h">
       <Filter>Framework\Graphics\DX\DX12</Filter>
     </ClInclude>
+    <ClInclude Include="Texture.h">
+      <Filter>Framework\Graphics\DX</Filter>
+    </ClInclude>
+    <ClInclude Include="DX9Texture.h">
+      <Filter>Framework\Graphics\DX\DX9</Filter>
+    </ClInclude>
+    <ClInclude Include="DX11Texture.h">
+      <Filter>Framework\Graphics\DX\DX11</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Model3DCollection.h">
@@ -450,9 +456,6 @@
     <ClCompile Include="Model3DList.cpp">
       <Filter>Framework\Graphics\3D</Filter>
     </ClCompile>
-    <ClCompile Include="Texture.cpp">
-      <Filter>Framework\Graphics\3D</Filter>
-    </ClCompile>
     <ClCompile Include="TextureList.cpp">
       <Filter>Framework\Graphics\3D</Filter>
     </ClCompile>
@@ -699,6 +702,15 @@
     <ClCompile Include="DX12TLAS.cpp">
       <Filter>Framework\Graphics\DX\DX12</Filter>
     </ClCompile>
+    <ClCompile Include="Texture.cpp">
+      <Filter>Framework\Graphics\DX</Filter>
+    </ClCompile>
+    <ClCompile Include="DX9Texture.cpp">
+      <Filter>Framework\Graphics\DX\DX9</Filter>
+    </ClCompile>
+    <ClCompile Include="DX11Texture.cpp">
+      <Filter>Framework\Graphics\DX\DX11</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <FxCompile Include="DX11VertexShader.hlsl">

+ 2 - 1
GraphicsApi.cpp

@@ -45,7 +45,8 @@ void GraphicsApi::renderKamera(Cam3D* zKamera) {}
 
 void GraphicsApi::renderKamera(Cam3D* zKamera, Texture* zTarget) {}
 
-Texture* GraphicsApi::createOrGetTexture(const char* name, Image* b)
+Texture* GraphicsApi::createOrGetTexture(
+    const char* name, Image* b, TextureDirection dir)
 {
     if (b) b->release();
     return 0;

+ 4 - 2
GraphicsApi.h

@@ -14,6 +14,7 @@ namespace Framework
     class Model3DData;
 
     enum GraphicApiType;
+    enum TextureDirection;
 
     struct DiffuseLight
     {
@@ -50,8 +51,9 @@ namespace Framework
         DLLEXPORT virtual void renderKamera(Cam3D* zKamera);
         DLLEXPORT virtual void renderKamera(Cam3D* zKamera, Texture* zTarget);
         DLLEXPORT virtual void presentFrame() = 0;
-        DLLEXPORT virtual Texture* createOrGetTexture(
-            const char* name, Image* b = 0);
+        DLLEXPORT virtual Texture* createOrGetTexture(const char* name,
+            Image* b = 0,
+            TextureDirection dir = (TextureDirection)0);
         DLLEXPORT GraphicApiType getTyp() const;
         DLLEXPORT Vec2<int> getBackBufferSize() const;
         DLLEXPORT bool isFullScreen() const;

+ 9 - 1
Iterator.h

@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
 
 namespace Framework
 {
@@ -53,6 +53,14 @@ namespace Framework
             return tmp;
         }
 
+        /**
+         * adds a value before the current element.
+         * after executing this function, the current element is the new value.
+         *
+         * \param val the new value to add
+         */
+        virtual void addBefore(T val) = 0;
+
         virtual void set(T val) = 0;
 
         virtual void remove() = 0;

+ 5 - 212
Texture.cpp

@@ -1,19 +1,13 @@
 #include "Texture.h"
 
 #include "Image.h"
-#ifdef WIN32
-#    include <d3d11.h>
-#    include <d3d12.h>
-
-#    include "d3dx12.h"
-#endif
-
 using namespace Framework;
 
 // Contents of the Texture class
 // Constructor
-Texture::Texture()
-    : ReferenceCounter()
+Texture::Texture(TextureDirection dir)
+    : ReferenceCounter(),
+      direction(dir)
 {
     bild = 0;
     lastGr = Point(0, 0);
@@ -71,208 +65,7 @@ int Texture::getId() const
     return id;
 }
 
-// Updates the texture. The pixels of the current image are copied into
-// the graphics memory
-bool DX9Texture::updateTextur()
-{
-    return 1;
-}
-
-// Returns true if updateTextur needs to be called
-bool DX9Texture::needsUpdate() const
-{
-    return 0;
-}
-
-DX11Texture::DX11Texture(
-    ID3D11Device* device, ID3D11DeviceContext* context, Critical& deviceLock)
-    : Texture(),
-      txt(0),
-      view(0),
-      device(device),
-      context(context),
-      renderTarget(0),
-      useMips(1),
-      deviceLock(deviceLock)
-{}
-
-DX11Texture::~DX11Texture()
-{
-#ifdef WIN32
-    if (txt) txt->Release();
-    if (view) view->Release();
-#endif
-}
-
-// Updates the texture. The pixels of the current image are copied into
-// the graphics memory
-bool DX11Texture::updateTextur()
+TextureDirection Framework::Texture::getDirection() const
 {
-    if (!bild) return 0;
-#ifdef WIN32
-    if (!txt || lastGr != bild->getSize())
-    {
-        if (txt) txt->Release();
-        txt = 0;
-        D3D11_TEXTURE2D_DESC bufferDesc;
-        memset(&bufferDesc, 0, sizeof(D3D11_TEXTURE2D_DESC));
-        bufferDesc.ArraySize = 1;
-        bufferDesc.Width = bild->getWidth();
-        bufferDesc.Height = bild->getHeight();
-        bufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
-        bufferDesc.BindFlags
-            = (renderTarget || useMips ? D3D11_BIND_RENDER_TARGET : 0)
-            | D3D11_BIND_SHADER_RESOURCE;
-        bufferDesc.CPUAccessFlags
-            = renderTarget || useMips ? 0 : D3D11_CPU_ACCESS_WRITE;
-        bufferDesc.SampleDesc.Count = 1;
-        bufferDesc.MipLevels = useMips ? 0 : 1;
-        bufferDesc.Usage = renderTarget || useMips ? D3D11_USAGE_DEFAULT
-                                                   : D3D11_USAGE_DYNAMIC;
-        bufferDesc.MiscFlags = useMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;
-        deviceLock.lock();
-        HRESULT r = device->CreateTexture2D(&bufferDesc, 0, &txt);
-        deviceLock.unlock();
-        if (r != S_OK) return 0;
-    }
-    if (!renderTarget && (bild->getNeedRender() || changed))
-    {
-        changed = 0;
-        if (useMips)
-        {
-            deviceLock.lock();
-            context->UpdateSubresource(txt,
-                0,
-                0,
-                bild->getBuffer(),
-                4 * bild->getWidth(),
-                4 * bild->getWidth() * bild->getHeight());
-            deviceLock.unlock();
-        }
-        else
-        {
-            D3D11_MAPPED_SUBRESOURCE buffer;
-            deviceLock.lock();
-            context->Map(
-                txt, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &buffer);
-            int* bgBuff = bild->getBuffer();
-            int tmpBr = 4 * bild->getWidth();
-            for (int y = 0, pitch = 0, bry = 0; y < bild->getHeight();
-                ++y, pitch += buffer.RowPitch, bry += bild->getWidth())
-            {
-                memcpy(&((BYTE*)buffer.pData)[pitch],
-                    (void*)&(bgBuff[bry]),
-                    tmpBr);
-            }
-            context->Unmap(txt, 0);
-            deviceLock.unlock();
-        }
-    }
-    if (!view || lastGr != bild->getSize())
-    {
-        if (view) view->Release();
-        view = 0;
-        D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesk;
-        memset(&resourceDesk, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
-        resourceDesk.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
-        resourceDesk.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
-        resourceDesk.Texture2D.MipLevels = useMips ? -1 : 1;
-        deviceLock.lock();
-        HRESULT r = device->CreateShaderResourceView(txt, &resourceDesk, &view);
-        deviceLock.unlock();
-        if (r != S_OK) return 0;
-        if (context && useMips)
-        {
-            deviceLock.lock();
-            context->GenerateMips(view);
-            deviceLock.unlock();
-        }
-    }
-    lastGr = bild->getSize();
-#endif
-    return 1;
+    return direction;
 }
-
-// Returns true if updateTextur needs to be called
-bool DX11Texture::needsUpdate() const
-{
-    return !view;
-}
-
-// Returns the used shader resource view
-DX11Texture::operator ID3D11ShaderResourceView*() const
-{
-    return view;
-}
-
-//! Returns the used texture
-DX11Texture::operator ID3D11Texture2D*() const
-{
-    return txt;
-}
-
-//! specifies that this texture is used as a render target
-void DX11Texture::setRenderTarget(bool rt)
-{
-    if (rt) useMips = 0;
-    renderTarget = rt;
-}
-
-//! specifies if a mip map should be generated
-void DX11Texture::setUseMips(bool useMips)
-{
-    this->useMips = useMips;
-}
-
-//! copy the texture to an image
-void DX11Texture::copyToImage(Image* zB)
-{
-#ifdef WIN32
-    D3D11_TEXTURE2D_DESC tempBufferDesc;
-    memset(&tempBufferDesc, 0, sizeof(D3D11_TEXTURE2D_DESC));
-    tempBufferDesc.ArraySize = 1;
-    tempBufferDesc.Width = bild->getWidth();
-    tempBufferDesc.Height = bild->getHeight();
-    tempBufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
-    tempBufferDesc.BindFlags = 0;
-    tempBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
-    tempBufferDesc.SampleDesc.Count = 1;
-    tempBufferDesc.MipLevels = 1;
-    tempBufferDesc.Usage = D3D11_USAGE_STAGING;
-    ID3D11Texture2D* tmpTxt;
-    deviceLock.lock();
-    HRESULT r = device->CreateTexture2D(&tempBufferDesc, 0, &tmpTxt);
-    deviceLock.unlock();
-    if (r != S_OK)
-    {
-        throw "could not create resource copy with cpu read access";
-    }
-    deviceLock.lock();
-    context->CopyResource(tmpTxt, txt);
-    deviceLock.unlock();
-    zB->newImage(bild->getWidth(), bild->getHeight(), 0);
-    D3D11_MAPPED_SUBRESOURCE buffer;
-    deviceLock.lock();
-    r = context->Map(tmpTxt, 0, D3D11_MAP::D3D11_MAP_READ, 0, &buffer);
-    deviceLock.unlock();
-    if (r != S_OK)
-    {
-        throw "could not access recource copy";
-    }
-    int* bgBuff = zB->getBuffer();
-    int tmpBr = 4 * zB->getWidth();
-    for (int y = 0, pitch = 0, bry = 0; y < zB->getHeight();
-        ++y, pitch += buffer.RowPitch, bry += zB->getWidth())
-    {
-        memcpy((void*)&(bgBuff[bry]), &((BYTE*)buffer.pData)[pitch], tmpBr);
-    }
-    for (int i = 0; i < zB->getWidth() * zB->getHeight(); i++)
-    {
-        if (bgBuff[i]) bgBuff[i] |= 0xFF000000;
-    }
-    deviceLock.lock();
-    context->Unmap(tmpTxt, 0);
-    deviceLock.unlock();
-    tmpTxt->Release();
-#endif
-}

+ 12 - 54
Texture.h

@@ -4,18 +4,18 @@
 #include "Point.h"
 #include "ReferenceCounter.h"
 
-struct ID3D11Texture2D;
-struct ID3D11ShaderResourceView;
-struct ID3D11Device;
-struct ID3D11DeviceContext;
-
 namespace Framework
 {
     class Image;       //! Image.h
-    class Render3D;    //! Render3D.h
     class TextureList; //! TextureList.h
-    class DX12CopyCommandQueue;
-    class DX12DirectCommandQueue;
+
+    enum TextureDirection
+    {
+        RAM_TO_GPU = 0, //! The texture is copied from an Image to GPU and then
+                        //! used in shaders
+        GPU_TO_RAM = 1, //! The texture is created by a shader and then copied
+                        //! to an Image
+    };
 
     //! Converts an image to a texture that can be passed to the graphics
     //! card for rendering
@@ -26,10 +26,11 @@ namespace Framework
         bool changed;
         Point lastGr;
         int id;
+        TextureDirection direction;
 
     public:
         //! Constructor
-        DLLEXPORT Texture();
+        DLLEXPORT Texture(TextureDirection dir);
         //! Destructor
         DLLEXPORT virtual ~Texture();
         //! Sets a pointer to the image that contains the texture
@@ -50,52 +51,9 @@ namespace Framework
         //! Returns the id of the texture if it was registered in a TextureList.
         //! (see Framework::zTextureRegister())
         DLLEXPORT int getId() const;
+        //! Returns the direction of the texture
+        DLLEXPORT TextureDirection getDirection() const;
 
         friend TextureList;
     };
-
-    //! Converts an image to a texture that can be passed to the graphics
-    //! card for rendering
-    class DX9Texture : public Texture
-    {
-    public:
-        //! Updates the texture. The pixels of the current image are copied
-        //! to graphics memory
-        DLLEXPORT virtual bool updateTextur() override;
-        //! Returns true if updateTextur needs to be called
-        DLLEXPORT virtual bool needsUpdate() const override;
-    };
-
-    class DX11Texture : public Texture
-    {
-    private:
-        ID3D11Texture2D* txt;
-        ID3D11ShaderResourceView* view;
-        ID3D11Device* device;
-        ID3D11DeviceContext* context;
-        bool renderTarget;
-        bool useMips;
-        Critical& deviceLock;
-
-    public:
-        DLLEXPORT DX11Texture(ID3D11Device* device,
-            ID3D11DeviceContext* context,
-            Critical& deviceLock);
-        DLLEXPORT ~DX11Texture();
-        //! Updates the texture. The pixels of the current image are copied
-        //! to graphics memory
-        DLLEXPORT bool updateTextur() override;
-        //! Returns true if updateTextur needs to be called
-        DLLEXPORT bool needsUpdate() const override;
-        //! Returns the used shader resource view
-        DLLEXPORT operator ID3D11ShaderResourceView*() const;
-        //! Returns the used texture
-        DLLEXPORT operator ID3D11Texture2D*() const;
-        //! specifies that this texture is used as a render target
-        DLLEXPORT void setRenderTarget(bool rt);
-        //! specifies if a mip map should be generated
-        DLLEXPORT void setUseMips(bool useMips);
-        //! copy the texture to an image
-        DLLEXPORT void copyToImage(Image* zB);
-    };
 } // namespace Framework