Texture Arrays and Resource Cache

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Texture Arrays and Resource Cache

      Hello guys, I am new here. I bought your book last month and it is pretty amazing! Currently I am in the Resource Cache chapter. I have created a small world(only terrain and some actors). Now I'm reading your book and I try to implement systems which are described in the book(I don't use just ctrl+c and ctrl+v, I'm trying to understand it and come with my own solution). But now I'm sticking. I've implemented a resource cache system based on yours, but I have a problem with creating texture arrays from textures which are saved as resources(I have saved it as ID3D11ShaderResourceView). First I load a texture data, then I create SRV. Then I release memory. Is there any way to create texture arrays with your and my design or is here only one way and it is: Don't release memory?
    • I'll try to chip in but I'm an OpenGL user myself. I am assuming that the texture array you are speaking of is a GPU texture array and not something else, in my experience textures of all types can reside either entirely in the GPU, where you can immediately release the client side memory as before the upload was initiated it was copied into 'pinned' memory. You can also however have a (albeit very slow) client side allocation for your texture. I'm not sure if this is what is happening or if this is the case why Direct3D would make this the default behaviour.

      Possibly it's something to do with Direct3D, but I would assume immediately after uploading your texture data you may freely release the data. Post some source code as well.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • Ok, thanks for advice.

      First I load data from a file(I have developed my own file format, where I have saved many files), before every file I saved a loader code, name etc. Based on loader code I choose a right loader:

      Source Code

      1. bool ResourceCache::PreLoadResources(const std::string &ResourceFilename)
      2. {
      3. auto pMemory = LoadRawDataFromFile(ResourceFilename);
      4. UINT *pNumResources = reinterpret_cast<UINT*>(pMemory);
      5. UINT traveledMemory = sizeof(UINT);
      6. for (UINT i = 0; i < *pNumResources; i++)
      7. {
      8. WORD *pNameSize = reinterpret_cast<WORD*>(pMemory + traveledMemory);
      9. traveledMemory += sizeof(WORD);
      10. std::string name(reinterpret_cast<char*>(pMemory + traveledMemory), *pNameSize);
      11. traveledMemory += *pNameSize;
      12. UINT *pLoaderType = reinterpret_cast<UINT*>(pMemory + traveledMemory);
      13. traveledMemory += sizeof(UINT);
      14. UINT *pBufferSize = reinterpret_cast<UINT*>(pMemory + traveledMemory);
      15. traveledMemory += sizeof(UINT);
      16. BYTE *pBuffer = pMemory + traveledMemory;
      17. traveledMemory += *pBufferSize;
      18. std::shared_ptr<IResourceHandle> pResource;
      19. if (m_ResourceLoadersMap[*pLoaderType]->VCreateResource(pBuffer, *pBufferSize, pResource))
      20. {
      21. m_ResourcesMap.emplace(name, pResource);
      22. m_ResourcesList.push_front(pResource);
      23. }
      24. }
      25. delete[] pMemory;
      26. return true;
      27. }
      Display All


      Here is my code for Texture Loader:

      Source Code

      1. bool VCreateResource(BYTE *pRawMemory, UINT MemorySize, std::shared_ptr<IResourceHandle> &pResource) override
      2. {
      3. Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> pTextureSRV;
      4. D3D_ETEST(DirectX::CreateDDSTextureFromMemory(m_pDevice3D.Get(), pRawMemory, MemorySize, nullptr, &pTextureSRV), "Cannot load texture");
      5. pResource = std::make_shared<TextureResourceHandle>(pTextureSRV, MemorySize + sizeof(pTextureSRV));
      6. return true;
      7. }


      I don't copy data and I don't save a pointer to data. After the function PreloadResources, data are destroyed. But in the DirectX I can't touch to memory from ID3D11ShaderResourceView, I can touch only if I specify flag in the creation(but this will be probably a lot slower)

      Here is code for creating texture arrays:

      Source Code

      1. bool Terrain::CreateTextureArray(std::shared_ptr<Renderer> &pRenderer)
      2. {
      3. std::vector<Microsoft::WRL::ComPtr<ID3D11Texture2D> > pLayerTextures(m_Info.LayerMapFilenames.size());
      4. for (UINT i = 0; i < pLayerTextures.size(); i++)
      5. {
      6. D3D_ETEST(DirectX::CreateDDSTextureFromFileEx(pRenderer->GetDevice3D().Get(), ToWstring(m_Info.LayerMapFilenames[i]).c_str(),
      7. 0, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0, false, reinterpret_cast<ID3D11Resource**>(pLayerTextures[i].GetAddressOf()), nullptr),
      8. "Cannot Load Texture: " + m_Info.LayerMapFilenames[i]);
      9. }
      10. D3D11_TEXTURE2D_DESC layerTextureDesc;
      11. pLayerTextures[0]->GetDesc(&layerTextureDesc);
      12. CD3D11_TEXTURE2D_DESC layerTextureArrayDesc(layerTextureDesc.Format, layerTextureDesc.Width, layerTextureDesc.Height, pLayerTextures.size(),
      13. layerTextureDesc.MipLevels, D3D11_BIND_SHADER_RESOURCE);
      14. Microsoft::WRL::ComPtr<ID3D11Texture2D> pLayerTextureArray;
      15. D3D_ETEST(pRenderer->GetDevice3D()->CreateTexture2D(&layerTextureArrayDesc, nullptr, &pLayerTextureArray), "Creating Texture Array Failed");
      16. for (UINT i = 0; i < pLayerTextures.size(); i++)
      17. {
      18. for (UINT j = 0; j < layerTextureArrayDesc.MipLevels; j++)
      19. {
      20. D3D11_MAPPED_SUBRESOURCE mappedData;
      21. D3D_ETEST(pRenderer->GetContext3D()->Map(pLayerTextures[i].Get(), j, D3D11_MAP_READ, 0, &mappedData), "Mapping Texture Failed");
      22. pRenderer->GetContext3D()->UpdateSubresource(pLayerTextureArray.Get(), D3D11CalcSubresource(j, i, layerTextureArrayDesc.MipLevels),
      23. nullptr, mappedData.pData, mappedData.RowPitch, mappedData.DepthPitch);
      24. pRenderer->GetContext3D()->Unmap(pLayerTextures[i].Get(), j);
      25. }
      26. }
      27. D3D11_SHADER_RESOURCE_VIEW_DESC layerTextureArraySRVDesc;
      28. layerTextureArraySRVDesc.Format = layerTextureArrayDesc.Format;
      29. layerTextureArraySRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
      30. layerTextureArraySRVDesc.Texture2DArray.ArraySize = layerTextureArrayDesc.ArraySize;
      31. layerTextureArraySRVDesc.Texture2DArray.FirstArraySlice = 0;
      32. layerTextureArraySRVDesc.Texture2DArray.MipLevels = layerTextureArrayDesc.MipLevels;
      33. layerTextureArraySRVDesc.Texture2DArray.MostDetailedMip = 0;
      34. D3D_ETEST(pRenderer->GetDevice3D()->CreateShaderResourceView(pLayerTextureArray.Get(), &layerTextureArraySRVDesc, &m_pLayerTextureArraySRV),
      35. "Creating Texture Array SRV Failed");
      36. return true;
      37. }
      Display All


      EDIT: I've found solution. You can close

      The post was edited 1 time, last by Xperience ().