2017-05-29 2 views
1

Sagen wir, ichWie kann ich in den Puffer meiner ID3D11UnorderedAccessView schreiben, bevor ich meinen Shader abschicke?

ID3D11UnorderedAccessView* pDataView 

haben, und ich habe

byte* pRawData 

wie kann ich pDataView Puffer mit pRawData eingestellt?

HINWEIS: FAILED und CHR sind Fehlerprüfmakros.

UPDATE: Soonts gab eine Antwort, die den Trick zu erstellen scheint, wenn ich das UAV erstelle, aber im Interesse der Vollständigkeit möchte ich auch in der Lage sein, seinen Puffer erfolgreich von der CPU zu aktualisieren erstellt. Ich war nicht so erfolgreich, das zu versuchen. Wenn ich habe:

 template <typename T> 
     static inline void CreateUnorderedAccessViewFromFile(
      _In_ ID3D11Device* pDevice, 
      _In_ ID3D11DeviceContext* pDeviceContext, 
      _In_ HANDLE dataFile, 
      _Out_ ID3D11Buffer** ppBuffer, 
      _Out_ ID3D11UnorderedAccessView** ppUav) 
     { 
      uint64_t fileSize; 

      //CBR(::GetFileSizeEx(handle, &fileSize)); 
      //Custom size for testing purposes 
      fileSize = 0x800; 

      D3D11_BUFFER_DESC bufferDesc = 
      { 
       fileSize, // ByteWidth 
       D3D11_USAGE_DEFAULT, // Usage 
       D3D11_BIND_UNORDERED_ACCESS, // BindFlags 
       D3D11_CPU_ACCESS_WRITE, // CPUAccessFlags 
       D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, // MiscFlags 
       sizeof(T), // StructureByteStride 
      }; 

      CHR(pDevice->CreateBuffer(
       &bufferDesc, 
       nullptr, 
       ppBuffer)); 


      D3D11_MAPPED_SUBRESOURCE mappedResource; 

      HRESULT hr = pDeviceContext->Map(
       *ppBuffer, 
       0, 
       D3D11_MAP_WRITE_DISCARD, 
       0, 
       &mappedResource); 

      byte* ppData = reinterpret_cast<byte*>(mappedResource.pData); 

      for (uint64_t i = 0; i < fileSize; i += 0x10000) 
      { 
       DWORD readSize = min(fileSize - i, 0x10000); 

       if (!ReadFile(
        dataFile, 
        ppData, 
        readSize, 
        NULL, 
        NULL)) 
       { 
        uint32_t lastError = ::GetLastError(); 

        CBR(lastError != ERROR_IO_PENDING); 
       } 
      } 

      pDeviceContext->Unmap(
       *ppBuffer, 
       0); 

      D3D11_UNORDERED_ACCESS_VIEW_DESC uaView = 
      { 
       DXGI_FORMAT_UNKNOWN, // Format 
       D3D11_UAV_DIMENSION_BUFFER, // ViewDimension 
      }; 

      uaView.Buffer.FirstElement = 0; 
      uaView.Buffer.Flags = 0; 
      uaView.Buffer.NumElements = fileSize/sizeof(T); 

      CHR(pDevice->CreateUnorderedAccessView(
       *ppBuffer, 
       &uaView, 
       ppUav)); 
     } 

Warum könnte ich hr E_INVALIDARG auf der Karte sein?

Hinweis: FAILED und CHR sind Fehlerprüfungsmakros.

Antwort

1

Zuerst müssen Sie einen Puffer mit Ihren Daten erstellen. Wenn Ihre Daten eine 2D-Textur sind, rufen Sie ID3D11Device::CreateTexture2D an. D3D11_BIND_UNORDERED_ACCESS im Feld D3D11_TEXTURE2D_DESC :: BindFlags nicht vergessen. Und Sie können Ihre byte* pRawData im zweiten Argument in dieser D3D11_SUBRESOURCE_DATA-Struktur übergeben.

Wenn Ihre Daten 1D Array von Strukturen sind, rufen Sie ID3D11Device::CreateBuffer, erneut sollten Sie D3D11_BIND_UNORDERED_ACCESS und Ihre Ausgangsdaten übergeben.

Es gibt andere Arten von Ressourcen, die von UAVs unterstützt werden: 1D-Texturen, 1D-Textur-Arrays, 2D-Textur-Arrays, 3D-Texturen. Alles hängt von Ihren Daten und Ihren Shadern ab, die das verarbeiten.

Schließlich Anruf ID3D11Device::CreateUnorderedAccessView übergeben ID3D11Texture2D oder ID3D11Buffer oder eine andere Ressource. Sowohl ID3D11Texture2D als auch ID3D11Buffer und andere erben von ID3D11Resource, sodass Sie beide übergeben können.

Aktualisierung: Wenn Sie beide bereits erstellt haben und nur aktualisieren müssen, rufen Sie GetResource auf Ihrem pDataView auf, um die Ressource aus der Ansicht abzurufen. Dann, um den Puffer ID3D11DeviceContext :: Map, memcpy, ID3D11DeviceContext :: Unmap zu aktualisieren. Stellen Sie nur sicher, dass Sie die entsprechende Ressource erstellt haben, d. H. D3D11_CPU_ACCESS_WRITE.

Aktualisierung: Wie vom Kommentator erwähnt, können Sie eine UAV-Ressource nicht direkt von der CPU aktualisieren. Die Lösung? Erstellen Sie eine D3D11_USAGE_STAGING-Ressource mit D3D11_CPU_ACCESS_WRITE des gleichen Formats und der gleichen Abmessungen, aktualisieren Sie sie von der CPU, indem Sie z. Map/Unmap, und dann ID3D11DeviceContext::CopyResource aufrufen, um von der Staging-Ressource zur UA-Ressource zu kopieren.

+0

Eine beschreibbare CPU-Ressource kann die uav-Bindung nicht verwenden, da sie auf dem PC in Konflikt stehen. Sie müssen einen separaten Puffer behalten und eine Kopie verwenden – galop1n

+0

@Soonts Ich konnte es so machen, wie Sie beim Erstellen der UAV mit Daten beschrieben, aber war nicht so erfolgreich bei der Aktualisierung der UAV-Puffer, nachdem es erstellt wurde. Könnten Sie einen Blick darauf werfen und vorschlagen, was schief gehen könnte? – MNagy

+0

@MNagy ein anderes Update sehen – Soonts

Verwandte Themen