From 3218cc088fc7ce1fb6dae54e73fd70f266723d25 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 30 Nov 2020 18:13:22 -0800 Subject: GLTF Loader: updated GPU resource initialization --- AssetLoader/src/GLTFLoader.cpp | 178 +++++++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 80 deletions(-) (limited to 'AssetLoader/src/GLTFLoader.cpp') diff --git a/AssetLoader/src/GLTFLoader.cpp b/AssetLoader/src/GLTFLoader.cpp index 943b180..13446f5 100644 --- a/AssetLoader/src/GLTFLoader.cpp +++ b/AssetLoader/src/GLTFLoader.cpp @@ -54,7 +54,10 @@ namespace Diligent namespace GLTF { -struct GLTFTextureUpdateData +namespace +{ + +struct TextureInitData { struct LevelData { @@ -68,7 +71,19 @@ struct GLTFTextureUpdateData RefCntAutoPtr pStagingTex; }; -static std::unique_ptr PrepareGLTFTextureUpdateData( +} // namespace + +struct Model::ResourceInitData +{ + std::vector Textures; + + std::vector IndexBuffer; + std::vector VertexData0; + std::vector VertexData1; +}; + + +static TextureInitData PrepareGLTFTextureInitData( const tinygltf::Image& gltfimage, float AlphaCutoff, Uint32 DstX, @@ -78,9 +93,9 @@ static std::unique_ptr PrepareGLTFTextureUpdateData( VERIFY_EXPR(!gltfimage.image.empty()); VERIFY_EXPR(gltfimage.width > 0 && gltfimage.height > 0 && gltfimage.component > 0); - std::unique_ptr UpdateInfo{new GLTFTextureUpdateData}; + TextureInitData UpdateInfo; - auto& Levels = UpdateInfo->Levels; + auto& Levels = UpdateInfo.Levels; Levels.resize(NumMipLevels); auto& Level0 = Levels[0]; @@ -270,14 +285,11 @@ Model::~Model() } } -void Model::LoadNode(IRenderDevice* pDevice, - Node* parent, - const tinygltf::Node& gltf_node, - uint32_t nodeIndex, - const tinygltf::Model& gltf_model, - std::vector& indexBuffer, - std::vector& vertexData0, - std::vector& vertexData1) +void Model::LoadNode(IRenderDevice* pDevice, + Node* parent, + const tinygltf::Node& gltf_node, + uint32_t nodeIndex, + const tinygltf::Model& gltf_model) { std::unique_ptr NewNode(new Node{}); NewNode->Index = nodeIndex; @@ -314,7 +326,7 @@ void Model::LoadNode(IRenderDevice* pDevice, { for (size_t i = 0; i < gltf_node.children.size(); i++) { - LoadNode(pDevice, NewNode.get(), gltf_model.nodes[gltf_node.children[i]], gltf_node.children[i], gltf_model, indexBuffer, vertexData0, vertexData1); + LoadNode(pDevice, NewNode.get(), gltf_model.nodes[gltf_node.children[i]], gltf_node.children[i], gltf_model); } } @@ -327,9 +339,9 @@ void Model::LoadNode(IRenderDevice* pDevice, { const tinygltf::Primitive& primitive = gltf_mesh.primitives[j]; - uint32_t indexStart = static_cast(indexBuffer.size()); - uint32_t vertexStart = static_cast(vertexData0.size()); - VERIFY_EXPR(vertexData1.empty() || vertexData0.size() == vertexData1.size()); + uint32_t indexStart = static_cast(InitData->IndexBuffer.size()); + uint32_t vertexStart = static_cast(InitData->VertexData0.size()); + VERIFY_EXPR(InitData->VertexData1.empty() || InitData->VertexData0.size() == InitData->VertexData1.size()); uint32_t indexCount = 0; uint32_t vertexCount = 0; @@ -470,7 +482,7 @@ void Model::LoadNode(IRenderDevice* pDevice, vert0.uv0 = bufferTexCoordSet0 != nullptr ? float2::MakeVector(bufferTexCoordSet0 + v * texCoordSet0Stride) : float2{}; vert0.uv1 = bufferTexCoordSet1 != nullptr ? float2::MakeVector(bufferTexCoordSet1 + v * texCoordSet1Stride) : float2{}; // clang-format on - vertexData0.push_back(vert0); + InitData->VertexData0.push_back(vert0); VertexAttribs1 vert1{}; if (hasSkin) @@ -480,7 +492,7 @@ void Model::LoadNode(IRenderDevice* pDevice, float4::MakeVector(bufferJoints16 + v * jointsStride); vert1.weight0 = float4::MakeVector(bufferWeights + v * weightsStride); } - vertexData1.push_back(vert1); + InitData->VertexData1.push_back(vert1); } } @@ -495,6 +507,8 @@ void Model::LoadNode(IRenderDevice* pDevice, const void* dataPtr = &(buffer.data[accessor.byteOffset + bufferView.byteOffset]); + auto& IndexBuffer = InitData->IndexBuffer; + IndexBuffer.reserve(IndexBuffer.size() + accessor.count); switch (accessor.componentType) { case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: @@ -502,7 +516,7 @@ void Model::LoadNode(IRenderDevice* pDevice, const uint32_t* buf = static_cast(dataPtr); for (size_t index = 0; index < accessor.count; index++) { - indexBuffer.push_back(buf[index] + vertexStart); + IndexBuffer.push_back(buf[index] + vertexStart); } break; } @@ -511,7 +525,7 @@ void Model::LoadNode(IRenderDevice* pDevice, const uint16_t* buf = static_cast(dataPtr); for (size_t index = 0; index < accessor.count; index++) { - indexBuffer.push_back(buf[index] + vertexStart); + IndexBuffer.push_back(buf[index] + vertexStart); } break; } @@ -520,7 +534,7 @@ void Model::LoadNode(IRenderDevice* pDevice, const uint8_t* buf = static_cast(dataPtr); for (size_t index = 0; index < accessor.count; index++) { - indexBuffer.push_back(buf[index] + vertexStart); + IndexBuffer.push_back(buf[index] + vertexStart); } break; } @@ -722,7 +736,7 @@ void Model::LoadTextures(IRenderDevice* pDevice, } } - std::unique_ptr TexUpdateData; + TextureInitData TexInitData; if (!TexInfo.pTexture) { RefCntAutoPtr pSampler; @@ -750,7 +764,7 @@ void Model::LoadTextures(IRenderDevice* pDevice, const auto& TexDesc = TexInfo.pTexture->GetDesc(); const auto& Region = TexInfo.CacheAllocation.Region; - TexInfo.UpdateData = PrepareGLTFTextureUpdateData(gltf_image, AlphaCutoff, Region.x, Region.y, TexDesc.MipLevels); + TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, Region.x, Region.y, TexDesc.MipLevels); TexInfo.UVScaleBias.x = static_cast(gltf_image.width) / static_cast(TexDesc.Width); TexInfo.UVScaleBias.y = static_cast(gltf_image.height) / static_cast(TexDesc.Height); @@ -775,7 +789,7 @@ void Model::LoadTextures(IRenderDevice* pDevice, TexInfo.pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)->SetSampler(pSampler); TexInfo.UVScaleBias = float4{1, 1, 0, 0}; - TexInfo.UpdateData = PrepareGLTFTextureUpdateData(gltf_image, AlphaCutoff, 0, 0, 1); + TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, 0, 0, 1); } } else if (gltf_image.pixel_type == IMAGE_FILE_FORMAT_DDS || gltf_image.pixel_type == IMAGE_FILE_FORMAT_KTX) @@ -798,7 +812,7 @@ void Model::LoadTextures(IRenderDevice* pDevice, } } - if (!TexInfo.UpdateData) + if (!InitData) { // Create stub texture TextureDesc TexDesc; @@ -814,8 +828,8 @@ void Model::LoadTextures(IRenderDevice* pDevice, std::vector Data(TexDesc.Width * TexDesc.Height * 4); TextureSubResData Mip0Data{Data.data(), TexDesc.Width * 4}; GenerateCheckerBoardPattern(TexDesc.Width, TexDesc.Height, TexDesc.Format, 4, 4, Data.data(), Mip0Data.Stride); - TextureData InitData{&Mip0Data, 1}; - pDevice->CreateTexture(TexDesc, &InitData, &TexInfo.pTexture); + TextureData Level0SubresData{&Mip0Data, 1}; + pDevice->CreateTexture(TexDesc, &Level0SubresData, &TexInfo.pTexture); } if (TexInfo.pTexture && pTextureCache != nullptr) @@ -825,72 +839,67 @@ void Model::LoadTextures(IRenderDevice* pDevice, } } - if (TexInfo.pTexture) - { - Textures.emplace_back(std::move(TexInfo)); - } + Textures.emplace_back(std::move(TexInfo)); + InitData->Textures.emplace_back(std::move(TexInitData)); } } void Model::PrepareGPUResources(IDeviceContext* pCtx) { - if (!TexturesUpdated) + if (!InitData) + return; + + VERIFY_EXPR(InitData->Textures.size() == Textures.size()); + for (Uint32 i = 0; i < Textures.size(); ++i) { - for (auto& TexInfo : Textures) + auto* pTexture = GetTexture(i); + if (!pTexture) + continue; + + auto& TexData = InitData->Textures[i]; + + const auto& Levels = TexData.Levels; + if (!Levels.empty()) { - if (TexInfo.pTexture && TexInfo.UpdateData) + VERIFY_EXPR(Levels.size() == 1 || Levels.size() == pTexture->GetDesc().MipLevels); + for (Uint32 mip = 0; mip < Levels.size(); ++mip) { - const auto& Levels = TexInfo.UpdateData->Levels; - if (!Levels.empty()) - { - VERIFY_EXPR(Levels.size() == 1 || Levels.size() == TexInfo.pTexture->GetDesc().MipLevels); - for (Uint32 mip = 0; mip < Levels.size(); ++mip) - { - const auto& Level = Levels[mip]; - - TextureSubResData SubresData{Level.Data.data(), Level.Stride}; - pCtx->UpdateTexture(TexInfo.pTexture, mip, 0, Level.UpdateBox, SubresData, RESOURCE_STATE_TRANSITION_MODE_NONE, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - } + const auto& Level = Levels[mip]; - if (Levels.size() == 1 && TexInfo.pTexture->GetDesc().MipLevels > 1) - { - pCtx->GenerateMips(TexInfo.pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)); - } - } - else if (TexInfo.UpdateData->pStagingTex) - { - UNSUPPORTED("Not yet implemented"); - } - else - { - UNEXPECTED("Either levels data or staging texture should not be null"); - } + TextureSubResData SubresData{Level.Data.data(), Level.Stride}; + pCtx->UpdateTexture(pTexture, mip, 0, Level.UpdateBox, SubresData, RESOURCE_STATE_TRANSITION_MODE_NONE, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); } - TexInfo.UpdateData.reset(); + if (Levels.size() == 1 && pTexture->GetDesc().MipLevels > 1) + { + pCtx->GenerateMips(pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)); + } + } + else if (TexData.pStagingTex) + { + UNSUPPORTED("Not yet implemented"); + } + else + { + UNEXPECTED("Either levels data or staging texture should not be null"); } - TexturesUpdated = true; } + InitData.reset(); - if (!TexturesTransitioned) + std::vector Barriers; + Barriers.reserve(Textures.size()); + for (auto& TexInfo : Textures) { - std::vector Barriers; - Barriers.reserve(Textures.size()); - for (auto& TexInfo : Textures) + if (TexInfo.pTexture) { - if (TexInfo.pTexture) - { - StateTransitionDesc Barrier{TexInfo.pTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE}; - Barrier.UpdateResourceState = true; - Barriers.emplace_back(Barrier); - } + StateTransitionDesc Barrier{TexInfo.pTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE}; + Barrier.UpdateResourceState = true; + Barriers.emplace_back(Barrier); } - - if (!Barriers.empty()) - pCtx->TransitionResourceStates(static_cast(Barriers.size()), Barriers.data()); - - TexturesTransitioned = true; } + + if (!Barriers.empty()) + pCtx->TransitionResourceStates(static_cast(Barriers.size()), Barriers.data()); } namespace @@ -1503,9 +1512,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice, LOG_WARNING_MESSAGE("Loaded gltf file ", filename, " with the following warning:", warning); } - std::vector IndexBuffer; - std::vector VertexData0; - std::vector VertexData1; + InitData.reset(new ResourceInitData); LoadTextureSamplers(pDevice, gltf_model); LoadTextures(pDevice, gltf_model, LoaderData.BaseDir, pTextureCache); @@ -1516,7 +1523,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice, for (size_t i = 0; i < scene.nodes.size(); i++) { const tinygltf::Node node = gltf_model.nodes[scene.nodes[i]]; - LoadNode(pDevice, nullptr, node, scene.nodes[i], gltf_model, IndexBuffer, VertexData0, VertexData1); + LoadNode(pDevice, nullptr, node, scene.nodes[i], gltf_model); } if (gltf_model.animations.size() > 0) @@ -1544,6 +1551,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice, Extensions = gltf_model.extensionsUsed; { + auto& VertexData0 = InitData->VertexData0; VERIFY_EXPR(!VertexData0.empty()); BufferDesc VBDesc; VBDesc.Name = "GLTF vertex attribs 0 buffer"; @@ -1553,9 +1561,13 @@ void Model::LoadFromFile(IRenderDevice* pDevice, BufferData BuffData(VertexData0.data(), VBDesc.uiSizeInBytes); pDevice->CreateBuffer(VBDesc, &BuffData, &pVertexBuffer[0]); + + VertexData0.clear(); } { + auto& VertexData1 = InitData->VertexData1; + VERIFY_EXPR(!VertexData1.empty()); BufferDesc VBDesc; VBDesc.Name = "GLTF vertex attribs 1 buffer"; @@ -1565,11 +1577,15 @@ void Model::LoadFromFile(IRenderDevice* pDevice, BufferData BuffData(VertexData1.data(), VBDesc.uiSizeInBytes); pDevice->CreateBuffer(VBDesc, &BuffData, &pVertexBuffer[1]); + + VertexData1.clear(); } - if (!IndexBuffer.empty()) + if (!InitData->IndexBuffer.empty()) { + auto& IndexBuffer = InitData->IndexBuffer; + BufferDesc IBDesc; IBDesc.Name = "GLTF inde buffer"; IBDesc.uiSizeInBytes = static_cast(IndexBuffer.size() * sizeof(IndexBuffer[0])); @@ -1578,6 +1594,8 @@ void Model::LoadFromFile(IRenderDevice* pDevice, BufferData BuffData(IndexBuffer.data(), IBDesc.uiSizeInBytes); pDevice->CreateBuffer(IBDesc, &BuffData, &pIndexBuffer); + + IndexBuffer.clear(); } if (pContext != nullptr) -- cgit v1.2.3