git.s-ol.nu ~forks/DiligentTools / 398bdcc
GLTF Loader: fixed few issues with texture cache assiduous 1 year, 1 month ago
2 changed file(s) with 102 addition(s) and 99 deletion(s). Raw diff Collapse all Expand all
425425 float4 UVScaleBias{1, 1, 0, 0};
426426
427427 RefCntAutoPtr<GLTFResourceManager::TextureAllocation> pCacheAllocation;
428
429 bool IsValid() const
430 {
431 return pTexture || pCacheAllocation;
432 }
428433 };
429434 std::vector<TextureInfo> Textures;
430435 };
711711 TexInfo.UVScaleBias.y = static_cast<float>(gltf_image.height) / static_cast<float>(TexDesc.Height);
712712 TexInfo.UVScaleBias.z = static_cast<float>(Region.x) / static_cast<float>(TexDesc.Width);
713713 TexInfo.UVScaleBias.w = static_cast<float>(Region.y) / static_cast<float>(TexDesc.Height);
714
715 continue;
716714 }
717715 }
718716 else if (pTextureCache != nullptr)
723721 if (it != pTextureCache->Textures.end())
724722 {
725723 TexInfo.pTexture = it->second.Lock();
726 if (TexInfo.pTexture)
727 {
728 continue;
729 }
730 else
724 if (!TexInfo.pTexture)
731725 {
732726 // Image width and height (or pixel_type for dds/ktx) are initialized by LoadImageData()
733727 // if the texture is found in the cache.
747741
748742 TextureInitData TexInitData;
749743
750 RefCntAutoPtr<ISampler> pSampler;
751 if (gltf_tex.sampler == -1)
752 {
753 // No sampler specified, use a default one
754 pDevice->CreateSampler(Sam_LinearWrap, &pSampler);
755 }
756 else
757 {
758 pSampler = TextureSamplers[gltf_tex.sampler];
759 }
760
761 // Check if the texture is used in an alpha-cut material
762 float AlphaCutoff = GetTextureAlphaCutoffValue(gltf_model, static_cast<int>(Textures.size()));
763
764 if (gltf_image.width > 0 && gltf_image.height > 0)
765 {
766 if (CacheInfo.pResourceMgr != nullptr)
767 {
768 TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(0, gltf_image.width, gltf_image.height);
769 if (TexInfo.pCacheAllocation)
770 {
771 const auto& TexDesc = TexInfo.pCacheAllocation->GetTexDesc();
772
773 const auto& Region = TexInfo.pCacheAllocation->GetRegion();
774 TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, Region.x, Region.y, TexDesc.MipLevels);
775
776 TexInfo.UVScaleBias.x = static_cast<float>(gltf_image.width) / static_cast<float>(TexDesc.Width);
777 TexInfo.UVScaleBias.y = static_cast<float>(gltf_image.height) / static_cast<float>(TexDesc.Height);
778 TexInfo.UVScaleBias.z = static_cast<float>(Region.x) / static_cast<float>(TexDesc.Width);
779 TexInfo.UVScaleBias.w = static_cast<float>(Region.y) / static_cast<float>(TexDesc.Height);
780 }
744 if (!TexInfo.IsValid())
745 {
746 RefCntAutoPtr<ISampler> pSampler;
747 if (gltf_tex.sampler == -1)
748 {
749 // No sampler specified, use a default one
750 pDevice->CreateSampler(Sam_LinearWrap, &pSampler);
781751 }
782752 else
783753 {
754 pSampler = TextureSamplers[gltf_tex.sampler];
755 }
756
757 // Check if the texture is used in an alpha-cut material
758 float AlphaCutoff = GetTextureAlphaCutoffValue(gltf_model, static_cast<int>(Textures.size()));
759
760 if (gltf_image.width > 0 && gltf_image.height > 0)
761 {
762 if (CacheInfo.pResourceMgr != nullptr)
763 {
764 TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(0, gltf_image.width, gltf_image.height);
765 if (TexInfo.pCacheAllocation)
766 {
767 const auto& TexDesc = TexInfo.pCacheAllocation->GetTexDesc();
768
769 const auto& Region = TexInfo.pCacheAllocation->GetRegion();
770 TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, Region.x, Region.y, TexDesc.MipLevels);
771
772 TexInfo.UVScaleBias.x = static_cast<float>(gltf_image.width) / static_cast<float>(TexDesc.Width);
773 TexInfo.UVScaleBias.y = static_cast<float>(gltf_image.height) / static_cast<float>(TexDesc.Height);
774 TexInfo.UVScaleBias.z = static_cast<float>(Region.x) / static_cast<float>(TexDesc.Width);
775 TexInfo.UVScaleBias.w = static_cast<float>(Region.y) / static_cast<float>(TexDesc.Height);
776 }
777 }
778 else
779 {
780 TextureDesc TexDesc;
781 TexDesc.Name = "GLTF Texture";
782 TexDesc.Type = RESOURCE_DIM_TEX_2D;
783 TexDesc.Usage = USAGE_DEFAULT;
784 TexDesc.BindFlags = BIND_SHADER_RESOURCE;
785 TexDesc.Width = gltf_image.width;
786 TexDesc.Height = gltf_image.height;
787 TexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
788 TexDesc.MipLevels = 0;
789 TexDesc.MiscFlags = MISC_TEXTURE_FLAG_GENERATE_MIPS;
790
791 pDevice->CreateTexture(TexDesc, nullptr, &TexInfo.pTexture);
792 TexInfo.pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)->SetSampler(pSampler);
793 TexInfo.UVScaleBias = float4{1, 1, 0, 0};
794
795 TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, 0, 0, 1);
796 }
797 }
798 else if (gltf_image.pixel_type == IMAGE_FILE_FORMAT_DDS || gltf_image.pixel_type == IMAGE_FILE_FORMAT_KTX)
799 {
800 // Create the texture from raw bits
801 RefCntAutoPtr<DataBlobImpl> pRawData(MakeNewRCObj<DataBlobImpl>()(gltf_image.image.size()));
802 memcpy(pRawData->GetDataPtr(), gltf_image.image.data(), gltf_image.image.size());
803 switch (gltf_image.pixel_type)
804 {
805 case IMAGE_FILE_FORMAT_DDS:
806 CreateTextureFromDDS(pRawData, TextureLoadInfo{}, pDevice, &TexInfo.pTexture);
807 break;
808
809 case IMAGE_FILE_FORMAT_KTX:
810 CreateTextureFromKTX(pRawData, TextureLoadInfo{}, pDevice, &TexInfo.pTexture);
811 break;
812
813 default:
814 UNEXPECTED("Unknown raw image format");
815 }
816 }
817
818 if (!InitData)
819 {
820 // Create stub texture
784821 TextureDesc TexDesc;
785 TexDesc.Name = "GLTF Texture";
822 TexDesc.Name = "Checkerboard stub texture";
786823 TexDesc.Type = RESOURCE_DIM_TEX_2D;
787 TexDesc.Usage = USAGE_DEFAULT;
824 TexDesc.Width = 32;
825 TexDesc.Height = 32;
826 TexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
827 TexDesc.MipLevels = 1;
828 TexDesc.Usage = USAGE_IMMUTABLE;
788829 TexDesc.BindFlags = BIND_SHADER_RESOURCE;
789 TexDesc.Width = gltf_image.width;
790 TexDesc.Height = gltf_image.height;
791 TexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
792 TexDesc.MipLevels = 0;
793 TexDesc.MiscFlags = MISC_TEXTURE_FLAG_GENERATE_MIPS;
794
795 pDevice->CreateTexture(TexDesc, nullptr, &TexInfo.pTexture);
796 TexInfo.pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)->SetSampler(pSampler);
797 TexInfo.UVScaleBias = float4{1, 1, 0, 0};
798
799 TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, 0, 0, 1);
800 }
801 }
802 else if (gltf_image.pixel_type == IMAGE_FILE_FORMAT_DDS || gltf_image.pixel_type == IMAGE_FILE_FORMAT_KTX)
803 {
804 // Create the texture from raw bits
805 RefCntAutoPtr<DataBlobImpl> pRawData(MakeNewRCObj<DataBlobImpl>()(gltf_image.image.size()));
806 memcpy(pRawData->GetDataPtr(), gltf_image.image.data(), gltf_image.image.size());
807 switch (gltf_image.pixel_type)
808 {
809 case IMAGE_FILE_FORMAT_DDS:
810 CreateTextureFromDDS(pRawData, TextureLoadInfo{}, pDevice, &TexInfo.pTexture);
811 break;
812
813 case IMAGE_FILE_FORMAT_KTX:
814 CreateTextureFromKTX(pRawData, TextureLoadInfo{}, pDevice, &TexInfo.pTexture);
815 break;
816
817 default:
818 UNEXPECTED("Unknown raw image format");
819 }
820 }
821
822 if (!InitData)
823 {
824 // Create stub texture
825 TextureDesc TexDesc;
826 TexDesc.Name = "Checkerboard stub texture";
827 TexDesc.Type = RESOURCE_DIM_TEX_2D;
828 TexDesc.Width = 32;
829 TexDesc.Height = 32;
830 TexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
831 TexDesc.MipLevels = 1;
832 TexDesc.Usage = USAGE_IMMUTABLE;
833 TexDesc.BindFlags = BIND_SHADER_RESOURCE;
834
835 std::vector<Uint8> Data(TexDesc.Width * TexDesc.Height * 4);
836 TextureSubResData Mip0Data{Data.data(), TexDesc.Width * 4};
837 GenerateCheckerBoardPattern(TexDesc.Width, TexDesc.Height, TexDesc.Format, 4, 4, Data.data(), Mip0Data.Stride);
838 TextureData Level0SubresData{&Mip0Data, 1};
839 pDevice->CreateTexture(TexDesc, &Level0SubresData, &TexInfo.pTexture);
840 }
841
842 if (TexInfo.pTexture && pTextureCache != nullptr)
843 {
844 std::lock_guard<std::mutex> Lock{pTextureCache->TexturesMtx};
845 pTextureCache->Textures.emplace(CacheId, TexInfo.pTexture);
830
831 std::vector<Uint8> Data(TexDesc.Width * TexDesc.Height * 4);
832 TextureSubResData Mip0Data{Data.data(), TexDesc.Width * 4};
833 GenerateCheckerBoardPattern(TexDesc.Width, TexDesc.Height, TexDesc.Format, 4, 4, Data.data(), Mip0Data.Stride);
834 TextureData Level0SubresData{&Mip0Data, 1};
835 pDevice->CreateTexture(TexDesc, &Level0SubresData, &TexInfo.pTexture);
836 }
837
838 if (TexInfo.pTexture && pTextureCache != nullptr)
839 {
840 std::lock_guard<std::mutex> Lock{pTextureCache->TexturesMtx};
841 pTextureCache->Textures.emplace(CacheId, TexInfo.pTexture);
842 }
846843 }
847844
848845 Textures.emplace_back(std::move(TexInfo));
895892 }
896893 else
897894 {
898 UNEXPECTED("Either levels data or staging texture should not be null");
895 // Texture is already initialized
896 continue;
899897 }
900898 }
901899
15371535 {
15381536 pTextureCache,
15391537 &TextureHold,
1540 pCache->pResourceMgr,
1538 pCache ? pCache->pResourceMgr : nullptr,
15411539 &AllocationsHold
15421540 //
15431541 };