git.s-ol.nu ~forks/DiligentTools / 18c0c9d
GLTF loader: reworked initial texture data to be stored as user data in the texture/allocation to make sure that GPU data is always initialized before the first use assiduous 10 months ago
7 changed file(s) with 194 addition(s) and 100 deletion(s). Raw diff Collapse all Expand all
7777 RefCntAutoPtr<ITextureAtlasSuballocation> AllocateTextureSpace(TEXTURE_FORMAT Fmt,
7878 Uint32 Width,
7979 Uint32 Height,
80 const char* CacheId = nullptr);
80 const char* CacheId = nullptr,
81 IObject* pUserData = nullptr);
8182
8283 RefCntAutoPtr<ITextureAtlasSuballocation> FindAllocation(const char* CacheId);
8384
115116 return cache_it->second->GetTexture(pDevice, pContext);
116117 }
117118
119 // NB: can't return reference here!
120 TextureDesc GetAtlasDesc(TEXTURE_FORMAT Fmt)
121 {
122 {
123 std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
124
125 auto cache_it = m_Atlases.find(Fmt);
126 if (cache_it != m_Atlases.end())
127 return cache_it->second->GetAtlasDesc();
128 }
129
130 // Atlas is not present in the map - use default description
131 TextureDesc Desc = m_DefaultAtlasDesc.Desc;
132 Desc.Format = Fmt;
133 return Desc;
134 }
135
118136 private:
119137 template <typename AllocatorType, typename ObjectType>
120138 friend class Diligent::MakeNewRCObj;
5656 namespace
5757 {
5858
59 struct TextureInitData
60 {
59 struct TextureInitData : public ObjectBase<IObject>
60 {
61 TextureInitData(IReferenceCounters* pRefCounters) :
62 ObjectBase<IObject>{pRefCounters}
63 {}
64
6165 struct LevelData
6266 {
6367 std::vector<unsigned char> Data;
6468
6569 Uint32 Stride = 0;
66 Box UpdateBox;
70 Uint32 Width = 0;
71 Uint32 Height = 0;
6772 };
6873 std::vector<LevelData> Levels;
6974
7479
7580 struct Model::ResourceInitData
7681 {
77 std::vector<TextureInitData> Textures;
78
7982 std::vector<Uint32> IndexData;
8083 std::vector<VertexBasicAttribs> VertexBasicData;
8184 std::vector<VertexSkinAttribs> VertexSkinData;
8285 };
8386
8487
85 static TextureInitData PrepareGLTFTextureInitData(
88 static RefCntAutoPtr<TextureInitData> PrepareGLTFTextureInitData(
8689 const tinygltf::Image& gltfimage,
8790 float AlphaCutoff,
88 Uint32 DstX,
89 Uint32 DstY,
9091 Uint32 NumMipLevels)
9192 {
9293 VERIFY_EXPR(!gltfimage.image.empty());
9394 VERIFY_EXPR(gltfimage.width > 0 && gltfimage.height > 0 && gltfimage.component > 0);
9495
95 TextureInitData UpdateInfo;
96
97 auto& Levels = UpdateInfo.Levels;
96 RefCntAutoPtr<TextureInitData> UpdateInfo{MakeNewRCObj<TextureInitData>()()};
97
98 auto& Levels = UpdateInfo->Levels;
9899 Levels.resize(NumMipLevels);
99100
100 auto& Level0 = Levels[0];
101 Level0.Stride = gltfimage.width * 4;
102 Level0.UpdateBox.MinX = DstX;
103 Level0.UpdateBox.MaxX = DstX + static_cast<Uint32>(gltfimage.width);
104 Level0.UpdateBox.MinY = DstY;
105 Level0.UpdateBox.MaxY = DstY + static_cast<Uint32>(gltfimage.height);
101 auto& Level0 = Levels[0];
102 Level0.Width = static_cast<Uint32>(gltfimage.width);
103 Level0.Height = static_cast<Uint32>(gltfimage.height);
104 Level0.Stride = Level0.Width * 4;
106105
107106 if (gltfimage.component == 3)
108107 {
177176 const auto MipHeight = std::max(FineMipHeight / 2u, 1u);
178177
179178 Level.Stride = MipWidth * 4;
179 Level.Width = MipWidth;
180 Level.Height = MipHeight;
180181 Level.Data.resize(Level.Stride * MipHeight);
181 Level.UpdateBox.MinX = DstX >> mip;
182 Level.UpdateBox.MaxX = Level.UpdateBox.MinX + MipWidth;
183 Level.UpdateBox.MinY = DstY >> mip;
184 Level.UpdateBox.MaxY = Level.UpdateBox.MinY + MipHeight;
185182
186183 ComputeMipLevel(FineMipWidth, FineMipHeight, TEX_FORMAT_RGBA8_UNORM, FineLevel.Data.data(), FineLevel.Stride,
187184 Level.Data.data(), Level.Stride);
769766 }
770767 }
771768
772 TextureInitData TexInitData;
773
774769 if (!TexInfo.IsValid())
775770 {
776771 RefCntAutoPtr<ISampler> pSampler;
785780 }
786781
787782 // Check if the texture is used in an alpha-cut material
788 float AlphaCutoff = GetTextureAlphaCutoffValue(gltf_model, static_cast<int>(Textures.size()));
783 const float AlphaCutoff = GetTextureAlphaCutoffValue(gltf_model, static_cast<int>(Textures.size()));
789784
790785 if (gltf_image.width > 0 && gltf_image.height > 0)
791786 {
792787 if (pResourceMgr != nullptr)
793788 {
789 // No reference
790 const TextureDesc AtlasDesc = pResourceMgr->GetAtlasDesc(TEX_FORMAT_RGBA8_UNORM);
791
792 auto pInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, AtlasDesc.MipLevels);
793
794 // Init data will be atomically set in the allocation before any other thread may be able to
795 // get access to it.
796 // Note that it is possible that more than one thread prepares pInitData for the same allocation.
797 // It it also possible that multiple instances of the same allocation are created before the first
798 // is added to the cache. This is all OK though.
794799 TexInfo.pAtlasSuballocation =
795 pResourceMgr->AllocateTextureSpace(TEX_FORMAT_RGBA8_UNORM, gltf_image.width, gltf_image.height, CacheId.c_str());
800 pResourceMgr->AllocateTextureSpace(TEX_FORMAT_RGBA8_UNORM, gltf_image.width, gltf_image.height, CacheId.c_str(), pInitData);
801
802 VERIFY_EXPR(TexInfo.pAtlasSuballocation->GetAtlas()->GetAtlasDesc().MipLevels == AtlasDesc.MipLevels);
796803 }
797804 else
798805 {
810817 pDevice->CreateTexture(TexDesc, nullptr, &TexInfo.pTexture);
811818 TexInfo.pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)->SetSampler(pSampler);
812819
813 TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, 0, 0, 1);
820 auto pTexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, 1);
821 TexInfo.pTexture->SetUserData(pTexInitData);
814822 }
815823 }
816824 else if (gltf_image.pixel_type == IMAGE_FILE_FORMAT_DDS || gltf_image.pixel_type == IMAGE_FILE_FORMAT_KTX)
817825 {
818826 // Create the texture from raw bits
819 RefCntAutoPtr<DataBlobImpl> pRawData(MakeNewRCObj<DataBlobImpl>()(gltf_image.image.size()));
820 memcpy(pRawData->GetDataPtr(), gltf_image.image.data(), gltf_image.image.size());
827
828 RefCntAutoPtr<ITexture> pStagingTex;
829
830 RefCntAutoPtr<TextureInitData> pTexInitData{MakeNewRCObj<TextureInitData>()()};
831
821832 TextureLoadInfo LoadInfo;
822833 if (pResourceMgr != nullptr)
823834 {
829840 switch (gltf_image.pixel_type)
830841 {
831842 case IMAGE_FILE_FORMAT_DDS:
832 CreateTextureFromDDS(pRawData, LoadInfo, pDevice, pResourceMgr != nullptr ? &TexInitData.pStagingTex : &TexInfo.pTexture);
843 CreateTextureFromDDS(gltf_image.image.data(), gltf_image.image.size(), LoadInfo, pDevice, pResourceMgr != nullptr ? &pStagingTex : &TexInfo.pTexture);
833844 break;
834845
835846 case IMAGE_FILE_FORMAT_KTX:
836 CreateTextureFromKTX(pRawData, LoadInfo, pDevice, &TexInfo.pTexture);
847 CreateTextureFromKTX(gltf_image.image.data(), gltf_image.image.size(), LoadInfo, pDevice, pResourceMgr != nullptr ? &pStagingTex : &TexInfo.pTexture);
837848 break;
838849
839850 default:
840851 UNEXPECTED("Unknown raw image format");
841852 }
842 if (pResourceMgr != nullptr && TexInitData.pStagingTex)
843 {
844 const auto& TexDesc = TexInitData.pStagingTex->GetDesc();
845 TexInfo.pAtlasSuballocation = pResourceMgr->AllocateTextureSpace(TexDesc.Format, TexDesc.Width, TexDesc.Height, CacheId.c_str());
846 }
847 }
848
849 if (TexInfo.pAtlasSuballocation)
850 {
851 const auto& AtlasDesc = TexInfo.pAtlasSuballocation->GetAtlas()->GetAtlasDesc();
852 const auto& Origin = TexInfo.pAtlasSuballocation->GetOrigin();
853
854 if (!TexInitData.pStagingTex)
855 {
856 TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, Origin.x, Origin.y, AtlasDesc.MipLevels);
857 }
858 }
859
860 if (!InitData)
853 if (TexInfo.pTexture)
854 {
855 // Set empty init data to inidicate that the texture needs to be transitioned to correct state
856 TexInfo.pTexture->SetUserData(pTexInitData);
857 }
858 else if (pResourceMgr != nullptr && pStagingTex)
859 {
860 const auto& TexDesc = pStagingTex->GetDesc();
861
862 pTexInitData->pStagingTex = std::move(pStagingTex);
863
864 // Init data will be atomically set in the allocation before any other thread may be able to
865 // get access to it.
866 // Note that it is possible that more than one thread prepares pInitData for the same allocation.
867 // It it also possible that multiple instances of the same allocation are created before the first
868 // is added to the cache. This is all OK though.
869 TexInfo.pAtlasSuballocation = pResourceMgr->AllocateTextureSpace(TexDesc.Format, TexDesc.Width, TexDesc.Height, CacheId.c_str(), pTexInitData);
870 }
871 }
872
873 if (pResourceMgr == nullptr && !TexInfo.pTexture)
861874 {
862875 // Create stub texture
863876 TextureDesc TexDesc;
885898 }
886899
887900 Textures.emplace_back(std::move(TexInfo));
888 InitData->Textures.emplace_back(std::move(TexInitData));
889901 }
890902 }
891903
896908
897909 std::vector<StateTransitionDesc> Barriers;
898910
899 VERIFY_EXPR(InitData->Textures.size() == Textures.size());
900911 for (Uint32 i = 0; i < Textures.size(); ++i)
901912 {
902 auto& TexInfo = Textures[i];
903 ITexture* pTexture = TexInfo.pAtlasSuballocation ?
904 TexInfo.pAtlasSuballocation->GetAtlas()->GetTexture(pDevice, pCtx) :
905 TexInfo.pTexture;
913 auto& DstTexInfo = Textures[i];
914
915 ITexture* pTexture = nullptr;
916 TextureInitData* pInitData = nullptr;
917 if (DstTexInfo.pAtlasSuballocation)
918 {
919 pTexture = DstTexInfo.pAtlasSuballocation->GetAtlas()->GetTexture(pDevice, pCtx);
920 pInitData = ValidatedCast<TextureInitData>(DstTexInfo.pAtlasSuballocation->GetUserData());
921 }
922 else if (DstTexInfo.pTexture)
923 {
924 pTexture = DstTexInfo.pTexture;
925 pInitData = ValidatedCast<TextureInitData>(pTexture->GetUserData());
926 }
927
906928 if (!pTexture)
907929 continue;
908930
909 auto& TexData = InitData->Textures[i];
910
911 const auto& Levels = TexData.Levels;
912 const auto DstSlice = TexInfo.pAtlasSuballocation ? TexInfo.pAtlasSuballocation->GetSlice() : 0;
931 if (pInitData == nullptr)
932 {
933 // Texture data has already been initialized by another model
934 continue;
935 }
936
937 const auto& Levels = pInitData->Levels;
938 const auto DstSlice = DstTexInfo.pAtlasSuballocation ? DstTexInfo.pAtlasSuballocation->GetSlice() : 0;
913939 if (!Levels.empty())
914940 {
941 Uint32 DstX = 0;
942 Uint32 DstY = 0;
943 if (DstTexInfo.pAtlasSuballocation)
944 {
945 const auto& Origin = DstTexInfo.pAtlasSuballocation->GetOrigin();
946
947 DstX = Origin.x;
948 DstY = Origin.y;
949 }
915950 VERIFY_EXPR(Levels.size() == 1 || Levels.size() == pTexture->GetDesc().MipLevels);
916951 for (Uint32 mip = 0; mip < Levels.size(); ++mip)
917952 {
918953 const auto& Level = Levels[mip];
919954
955 Box UpdateBox;
956 UpdateBox.MinX = DstX >> mip;
957 UpdateBox.MaxX = UpdateBox.MinX + Level.Width;
958 UpdateBox.MinY = DstY >> mip;
959 UpdateBox.MaxY = UpdateBox.MinY + Level.Height;
920960 TextureSubResData SubresData{Level.Data.data(), Level.Stride};
921 pCtx->UpdateTexture(pTexture, mip, DstSlice, Level.UpdateBox, SubresData, RESOURCE_STATE_TRANSITION_MODE_NONE, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
961 pCtx->UpdateTexture(pTexture, mip, DstSlice, UpdateBox, SubresData, RESOURCE_STATE_TRANSITION_MODE_NONE, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
922962 }
923963
924964 if (Levels.size() == 1 && pTexture->GetDesc().MipLevels > 1)
925965 {
926966 pCtx->GenerateMips(pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
927967 }
928
929 if (Textures[i].pTexture != nullptr)
930 {
931 VERIFY_EXPR(pTexture == Textures[i].pTexture);
932 Barriers.emplace_back(StateTransitionDesc{pTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, true});
933 }
934 }
935 else if (TexData.pStagingTex)
968 }
969 else if (pInitData->pStagingTex)
936970 {
937971 CopyTextureAttribs CopyAttribs;
938 CopyAttribs.pSrcTexture = TexData.pStagingTex;
972 CopyAttribs.pSrcTexture = pInitData->pStagingTex;
939973 CopyAttribs.pDstTexture = pTexture;
940974 CopyAttribs.SrcTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION;
941975 CopyAttribs.DstTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION;
942976 CopyAttribs.SrcSlice = 0;
943977 CopyAttribs.DstSlice = DstSlice;
944978
945 if (Textures[i].pAtlasSuballocation)
946 {
947 const auto& Origin = Textures[i].pAtlasSuballocation->GetOrigin();
979 if (DstTexInfo.pAtlasSuballocation)
980 {
981 const auto& Origin = DstTexInfo.pAtlasSuballocation->GetOrigin();
948982 CopyAttribs.DstX = Origin.x;
949983 CopyAttribs.DstY = Origin.y;
950984 }
951985 const auto& DstTexDesc = pTexture->GetDesc();
952 auto NumMipLevels = std::min(DstTexDesc.MipLevels, TexData.pStagingTex->GetDesc().MipLevels);
986 auto NumMipLevels = std::min(DstTexDesc.MipLevels, pInitData->pStagingTex->GetDesc().MipLevels);
953987 for (Uint32 mip = 0; mip < NumMipLevels; ++mip)
954988 {
955989 CopyAttribs.SrcMipLevel = mip;
962996 else
963997 {
964998 // Texture is already initialized
965 continue;
999 }
1000
1001 if (DstTexInfo.pAtlasSuballocation)
1002 {
1003 // User data is only set when the allocation is created, so no other
1004 // threads can call SetUserData().
1005 DstTexInfo.pAtlasSuballocation->SetUserData(nullptr);
1006 }
1007 else if (DstTexInfo.pTexture)
1008 {
1009 VERIFY_EXPR(pTexture == DstTexInfo.pTexture);
1010 Barriers.emplace_back(StateTransitionDesc{pTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, true});
1011
1012 // User data is only set when the texture is created, so no other
1013 // threads can call SetUserData().
1014 pTexture->SetUserData(nullptr);
9661015 }
9671016 }
9681017
4848 m_DefaultAtlasDesc{CI.DefaultAtlasDesc},
4949 m_DefaultAtlasName{CI.DefaultAtlasDesc.Desc.Name != nullptr ? CI.DefaultAtlasDesc.Desc.Name : "GLTF texture atlas"}
5050 {
51 if (m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_TEX_2D &&
52 m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_TEX_2D_ARRAY &&
53 m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_UNDEFINED)
54 {
55 LOG_ERROR_AND_THROW(GetResourceDimString(m_DefaultAtlasDesc.Desc.Type), " is not a valid resource dimension for a texture atlas");
56 }
57
58 if (m_DefaultAtlasDesc.Desc.Width > 0 &&
59 m_DefaultAtlasDesc.Desc.Height > 0 &&
60 m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_UNDEFINED &&
61 m_DefaultAtlasDesc.Desc.MipLevels == 0)
62 {
63 m_DefaultAtlasDesc.Desc.MipLevels = ComputeMipLevelsCount(m_DefaultAtlasDesc.Desc.Width, m_DefaultAtlasDesc.Desc.Height);
64 }
65
5166 m_DefaultAtlasDesc.Desc.Name = m_DefaultAtlasName.c_str();
5267 m_BufferSuballocators.resize(CI.NumBuffSuballocators);
5368 for (Uint32 i = 0; i < CI.NumBuffSuballocators; ++i)
88103 TEXTURE_FORMAT Fmt,
89104 Uint32 Width,
90105 Uint32 Height,
91 const char* CacheId)
106 const char* CacheId,
107 IObject* pUserData)
92108 {
93109 RefCntAutoPtr<ITextureAtlasSuballocation> pAllocation;
94110 if (CacheId != nullptr && *CacheId != 0)
104120 cache_it = m_Atlases.find(Fmt);
105121 if (cache_it == m_Atlases.end())
106122 {
107 DEV_CHECK_ERR(m_DefaultAtlasDesc.Desc.Width > 0 &&
108 m_DefaultAtlasDesc.Desc.Height > 0 &&
109 m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_UNDEFINED,
123 // clang-format off
124 DEV_CHECK_ERR(m_DefaultAtlasDesc.Desc.Width > 0 &&
125 m_DefaultAtlasDesc.Desc.Height > 0 &&
126 m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_UNDEFINED,
110127 "Default texture description is not initialized");
128 // clang-format on
111129
112130 auto AtalsCreateInfo = m_DefaultAtlasDesc;
113131 AtalsCreateInfo.Desc.Format = Fmt;
121139 }
122140 // Allocate outside of mutex
123141 cache_it->second->Allocate(Width, Height, &pAllocation);
142 pAllocation->SetUserData(pUserData);
124143 }
125144
126145 if (CacheId != nullptr && *CacheId != 0)
103103
104104 /// Creates a texture from DDS data blob
105105
106 /// \param [in] pDDSData - Pointer to the DDS data blob
106 /// \param [in] pDDSData - Pointer to DDS data
107 /// \param [in] DataSize - DDS data size
107108 /// \param [in] TexLoadInfo - Texture loading information
108 /// \param [in] pDevice - Render device that will be used to create the texture
109 /// \param [out] ppTexture - Memory location where pointer to the created texture will be stored
110 void DILIGENT_GLOBAL_FUNCTION(CreateTextureFromDDS)(IDataBlob* pDDSData,
109 /// \param [in] pDevice - Render device that will be used to create the texture
110 /// \param [out] ppTexture - Memory location where pointer to the created texture will be stored
111 void DILIGENT_GLOBAL_FUNCTION(CreateTextureFromDDS)(const void* pDDSData,
112 size_t DataSize,
111113 const TextureLoadInfo REF TexLoadInfo,
112114 IRenderDevice* pDevice,
113115 ITexture** ppTexture);
115117
116118 /// Creates a texture from KTX data blob
117119
118 /// \param [in] pKTXData - Pointer to the KTX data blob
120 /// \param [in] pKTXData - Pointer to KTX data
121 /// \param [in] DataSize - KTX data size
119122 /// \param [in] TexLoadInfo - Texture loading information
120123 /// \param [in] pDevice - Render device that will be used to create the texture
121124 /// \param [out] ppTexture - Memory location where pointer to the created texture will be stored
122 void DILIGENT_GLOBAL_FUNCTION(CreateTextureFromKTX)(IDataBlob* pKTXData,
125 void DILIGENT_GLOBAL_FUNCTION(CreateTextureFromKTX)(const void* pKTXData,
126 size_t DataSize,
123127 const TextureLoadInfo REF TexLoadInfo,
124128 IRenderDevice* pDevice,
125129 ITexture** ppTexture);
211211 std::uint32_t BytesOfKeyValueData;
212212 };
213213
214 void CreateTextureFromKTX(IDataBlob* pKTXData,
214 void CreateTextureFromKTX(const void* pKTXData,
215 size_t DataSize,
215216 const TextureLoadInfo& TexLoadInfo,
216217 IRenderDevice* pDevice,
217218 ITexture** ppTexture)
218219 {
220 const Uint8* pData = reinterpret_cast<const Uint8*>(pKTXData);
221
219222 static constexpr Uint8 KTX10FileIdentifier[12] = {0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A};
220 const Uint8* pData = reinterpret_cast<const Uint8*>(pKTXData->GetDataPtr());
221 const auto DataSize = pKTXData->GetSize();
222223 if (DataSize >= 12 && memcmp(pData, KTX10FileIdentifier, sizeof(KTX10FileIdentifier)) == 0)
223224 {
224225 pData += sizeof(KTX10FileIdentifier);
272273 pData += Align(MipInfo.MipSize, 4u);
273274 }
274275 }
275 VERIFY(pData - reinterpret_cast<const Uint8*>(pKTXData->GetDataPtr()) == static_cast<ptrdiff_t>(DataSize), "Unexpected data size");
276 VERIFY(pData - reinterpret_cast<const Uint8*>(pKTXData) == static_cast<ptrdiff_t>(DataSize), "Unexpected data size");
276277
277278 TextureData InitData(SubresData.data(), static_cast<Uint32>(SubresData.size()));
278279 pDevice->CreateTexture(TexDesc, &InitData, ppTexture);
287288
288289 extern "C"
289290 {
290 void Diligent_CreateTextureFromKTX(Diligent::IDataBlob* pKTXData,
291 void Diligent_CreateTextureFromKTX(const void* pKTXData,
292 size_t DataSize,
291293 const Diligent::TextureLoadInfo& TexLoadInfo,
292294 Diligent::IRenderDevice* pDevice,
293295 Diligent::ITexture** ppTexture)
294296 {
295 Diligent::CreateTextureFromKTX(pKTXData, TexLoadInfo, pDevice, ppTexture);
297 Diligent::CreateTextureFromKTX(pKTXData, DataSize, TexLoadInfo, pDevice, ppTexture);
296298 }
297299 }
204204 pDevice->CreateTexture(TexDesc, &TexData, ppTexture);
205205 }
206206
207 void CreateTextureFromDDS(IDataBlob* pDDSData,
207 void CreateTextureFromDDS(const void* pDDSData,
208 size_t DataSize,
208209 const TextureLoadInfo& TexLoadInfo,
209210 IRenderDevice* pDevice,
210211 ITexture** ppTexture)
211212 {
212213 CreateDDSTextureFromMemoryEx(pDevice,
213 reinterpret_cast<const Uint8*>(pDDSData->GetDataPtr()),
214 static_cast<size_t>(pDDSData->GetSize()),
214 reinterpret_cast<const Uint8*>(pDDSData),
215 DataSize,
215216 0, // maxSize
216217 TexLoadInfo.Usage,
217218 TexLoadInfo.Name,
268269 Diligent::CreateTextureFromImage(pSrcImage, TexLoadInfo, pDevice, ppTexture);
269270 }
270271
271 void Diligent_CreateTextureFromDDS(Diligent::IDataBlob* pDDSData,
272 void Diligent_CreateTextureFromDDS(const void* pDDSData,
273 size_t DataSize,
272274 const Diligent::TextureLoadInfo& TexLoadInfo,
273275 Diligent::IRenderDevice* pDevice,
274276 Diligent::ITexture** ppTexture)
275277
276278 {
277 Diligent::CreateTextureFromDDS(pDDSData, TexLoadInfo, pDevice, ppTexture);
278 }
279 }
279 Diligent::CreateTextureFromDDS(pDDSData, DataSize, TexLoadInfo, pDevice, ppTexture);
280 }
281 }
5050 else if (pRawData)
5151 {
5252 if (ImgFmt == IMAGE_FILE_FORMAT_DDS)
53 CreateTextureFromDDS(pRawData, TexLoadInfo, pDevice, ppTexture);
53 CreateTextureFromDDS(pRawData->GetConstDataPtr(), pRawData->GetSize(), TexLoadInfo, pDevice, ppTexture);
5454 else if (ImgFmt == IMAGE_FILE_FORMAT_KTX)
55 CreateTextureFromKTX(pRawData, TexLoadInfo, pDevice, ppTexture);
55 CreateTextureFromKTX(pRawData->GetConstDataPtr(), pRawData->GetSize(), TexLoadInfo, pDevice, ppTexture);
5656 else
5757 UNEXPECTED("Unexpected format");
5858 }