git.s-ol.nu ~forks/DiligentTools / e355607
GLTF loader: reworked buffer initialization with user data assiduous 10 months ago
2 changed file(s) with 112 addition(s) and 127 deletion(s). Raw diff Collapse all Expand all
448448 IDeviceContext* pContext,
449449 const CreateInfo& CI);
450450
451 void LoadNode(IRenderDevice* pDevice,
452 Node* parent,
453 const tinygltf::Node& gltf_node,
454 uint32_t nodeIndex,
455 const tinygltf::Model& gltf_model,
456 bool LoadSkin);
451 void LoadNode(IRenderDevice* pDevice,
452 Node* parent,
453 const tinygltf::Node& gltf_node,
454 uint32_t nodeIndex,
455 const tinygltf::Model& gltf_model,
456 std::vector<Uint32>& IndexData,
457 std::vector<VertexBasicAttribs>& VertexBasicData,
458 std::vector<VertexSkinAttribs>* pVertexSkinData);
457459
458460 void LoadSkins(const tinygltf::Model& gltf_model);
459461
471473 Node* FindNode(Node* parent, Uint32 index);
472474 Node* NodeFromIndex(uint32_t index);
473475
474 struct ResourceInitData;
475 std::unique_ptr<ResourceInitData> InitData;
476 bool GPUDataInitialized = false;
476477
477478 struct BufferInfo
478479 {
7777
7878 } // namespace
7979
80 struct Model::ResourceInitData
81 {
82 std::vector<Uint32> IndexData;
83 std::vector<VertexBasicAttribs> VertexBasicData;
84 std::vector<VertexSkinAttribs> VertexSkinData;
85 };
86
8780
8881 static RefCntAutoPtr<TextureInitData> PrepareGLTFTextureInitData(
8982 const tinygltf::Image& gltfimage,
263256 {
264257 }
265258
266 void Model::LoadNode(IRenderDevice* pDevice,
267 Node* parent,
268 const tinygltf::Node& gltf_node,
269 uint32_t nodeIndex,
270 const tinygltf::Model& gltf_model,
271 bool LoadSkin)
259 void Model::LoadNode(IRenderDevice* pDevice,
260 Node* parent,
261 const tinygltf::Node& gltf_node,
262 uint32_t nodeIndex,
263 const tinygltf::Model& gltf_model,
264 std::vector<Uint32>& IndexData,
265 std::vector<VertexBasicAttribs>& VertexBasicData,
266 std::vector<VertexSkinAttribs>* pVertexSkinData)
272267 {
273268 std::unique_ptr<Node> NewNode(new Node{});
274269 NewNode->Index = nodeIndex;
308303 {
309304 for (size_t i = 0; i < gltf_node.children.size(); i++)
310305 {
311 LoadNode(pDevice, NewNode.get(), gltf_model.nodes[gltf_node.children[i]], gltf_node.children[i], gltf_model, LoadSkin);
306 LoadNode(pDevice, NewNode.get(), gltf_model.nodes[gltf_node.children[i]], gltf_node.children[i], gltf_model,
307 IndexData, VertexBasicData, pVertexSkinData);
312308 }
313309 }
314310
321317 {
322318 const tinygltf::Primitive& primitive = gltf_mesh.primitives[j];
323319
324 uint32_t indexStart = static_cast<uint32_t>(InitData->IndexData.size());
325 uint32_t vertexStart = static_cast<uint32_t>(InitData->VertexBasicData.size());
326 VERIFY_EXPR(InitData->VertexSkinData.empty() || InitData->VertexBasicData.size() == InitData->VertexSkinData.size());
320 uint32_t indexStart = static_cast<uint32_t>(IndexData.size());
321 uint32_t vertexStart = static_cast<uint32_t>(VertexBasicData.size());
322 VERIFY_EXPR(pVertexSkinData == nullptr || pVertexSkinData->empty() || VertexBasicData.size() == pVertexSkinData->size());
327323
328324 uint32_t indexCount = 0;
329325 uint32_t vertexCount = 0;
464460 BasicAttribs.uv0 = bufferTexCoordSet0 != nullptr ? float2::MakeVector(bufferTexCoordSet0 + v * texCoordSet0Stride) : float2{};
465461 BasicAttribs.uv1 = bufferTexCoordSet1 != nullptr ? float2::MakeVector(bufferTexCoordSet1 + v * texCoordSet1Stride) : float2{};
466462 // clang-format on
467 InitData->VertexBasicData.push_back(BasicAttribs);
468
469 if (LoadSkin)
463 VertexBasicData.push_back(BasicAttribs);
464
465 if (pVertexSkinData != nullptr)
470466 {
471467 VertexSkinAttribs SkinAttribs{};
472468 if (hasSkin)
476472 float4::MakeVector(bufferJoints16 + v * jointsStride);
477473 SkinAttribs.weight0 = float4::MakeVector(bufferWeights + v * weightsStride);
478474 }
479 InitData->VertexSkinData.push_back(SkinAttribs);
475 pVertexSkinData->push_back(SkinAttribs);
480476 }
481477 }
482478 }
492488
493489 const void* dataPtr = &(buffer.data[accessor.byteOffset + bufferView.byteOffset]);
494490
495 auto& IndexData = InitData->IndexData;
496491 IndexData.reserve(IndexData.size() + accessor.count);
497492 switch (accessor.componentType)
498493 {
903898
904899 void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx)
905900 {
906 if (!InitData)
901 if (GPUDataInitialized)
907902 return;
908903
909904 std::vector<StateTransitionDesc> Barriers;
10151010 }
10161011 }
10171012
1018 auto UpdateBuffer = [&](BUFFER_ID BuffId, const void* pData, size_t Size) //
1013 auto UpdateBuffer = [&](BUFFER_ID BuffId) //
10191014 {
10201015 auto& BuffInfo = Buffers[BuffId];
10211016 IBuffer* pBuffer = nullptr;
10221017 Uint32 Offset = 0;
1018
1019 RefCntAutoPtr<IDataBlob> pInitData;
10231020 if (BuffInfo.pSuballocation)
10241021 {
1025 pBuffer = BuffInfo.pSuballocation->GetAllocator()->GetBuffer(pDevice, pCtx);
1026 Offset = BuffInfo.pSuballocation->GetOffset();
1022 pBuffer = BuffInfo.pSuballocation->GetAllocator()->GetBuffer(pDevice, pCtx);
1023 Offset = BuffInfo.pSuballocation->GetOffset();
1024 pInitData = RefCntAutoPtr<IDataBlob>{BuffInfo.pSuballocation->GetUserData(), IID_DataBlob};
1025 BuffInfo.pSuballocation->SetUserData(nullptr);
1026 }
1027 else if (BuffInfo.pBuffer)
1028 {
1029 pBuffer = BuffInfo.pBuffer;
1030 pInitData = RefCntAutoPtr<IDataBlob>{pBuffer->GetUserData(), IID_DataBlob};
1031 pBuffer->SetUserData(nullptr);
10271032 }
10281033 else
10291034 {
1030 pBuffer = BuffInfo.pBuffer;
1031 }
1032
1033 pCtx->UpdateBuffer(pBuffer, Offset, static_cast<Uint32>(Size), pData, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
1034 if (Buffers[BuffId].pBuffer != nullptr)
1035 {
1036 VERIFY_EXPR(Buffers[BuffId].pBuffer == pBuffer);
1037 Barriers.emplace_back(StateTransitionDesc{pBuffer, RESOURCE_STATE_UNKNOWN, BuffId == BUFFER_ID_INDEX ? RESOURCE_STATE_INDEX_BUFFER : RESOURCE_STATE_VERTEX_BUFFER, true});
1035 return;
1036 }
1037
1038 if (pInitData)
1039 {
1040 pCtx->UpdateBuffer(pBuffer, Offset, static_cast<Uint32>(pInitData->GetSize()), pInitData->GetConstDataPtr(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
1041 if (Buffers[BuffId].pBuffer != nullptr)
1042 {
1043 VERIFY_EXPR(Buffers[BuffId].pBuffer == pBuffer);
1044 Barriers.emplace_back(StateTransitionDesc{pBuffer, RESOURCE_STATE_UNKNOWN, BuffId == BUFFER_ID_INDEX ? RESOURCE_STATE_INDEX_BUFFER : RESOURCE_STATE_VERTEX_BUFFER, true});
1045 }
10381046 }
10391047 };
10401048
1041 if (!InitData->VertexBasicData.empty())
1042 {
1043 const auto& VertexData = InitData->VertexBasicData;
1044 UpdateBuffer(BUFFER_ID_VERTEX_BASIC_ATTRIBS, VertexData.data(), VertexData.size() * sizeof(VertexData[0]));
1045 }
1046 if (!InitData->VertexSkinData.empty())
1047 {
1048 const auto& VertexData = InitData->VertexSkinData;
1049 UpdateBuffer(BUFFER_ID_VERTEX_SKIN_ATTRIBS, VertexData.data(), VertexData.size() * sizeof(VertexData[0]));
1050 }
1051 if (!InitData->IndexData.empty())
1052 {
1053 const auto& IndexData = InitData->IndexData;
1054 UpdateBuffer(BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]));
1055 }
1056
1057 InitData.reset();
1049 UpdateBuffer(BUFFER_ID_VERTEX_BASIC_ATTRIBS);
1050 UpdateBuffer(BUFFER_ID_VERTEX_SKIN_ATTRIBS);
1051 UpdateBuffer(BUFFER_ID_INDEX);
10581052
10591053 if (!Barriers.empty())
10601054 pCtx->TransitionResourceStates(static_cast<Uint32>(Barriers.size()), Barriers.data());
1055
1056 GPUDataInitialized = true;
10611057 }
10621058
10631059 namespace
17491745 LOG_WARNING_MESSAGE("Loaded gltf file ", filename, " with the following warning:", warning);
17501746 }
17511747
1752 InitData.reset(new ResourceInitData);
1753
17541748 LoadTextureSamplers(pDevice, gltf_model);
17551749 LoadTextures(pDevice, gltf_model, LoaderData.BaseDir, pTextureCache, pResourceMgr);
17561750 LoadMaterials(gltf_model);
17571751
1752 std::vector<Uint32> IndexData;
1753 std::vector<VertexBasicAttribs> VertexBasicData;
1754 std::vector<VertexSkinAttribs> VertexSkinData;
1755
17581756 // TODO: scene handling with no default scene
17591757 const tinygltf::Scene& scene = gltf_model.scenes[gltf_model.defaultScene > -1 ? gltf_model.defaultScene : 0];
17601758 for (size_t i = 0; i < scene.nodes.size(); i++)
17611759 {
17621760 const tinygltf::Node node = gltf_model.nodes[scene.nodes[i]];
1763 LoadNode(pDevice, nullptr, node, scene.nodes[i], gltf_model, CI.LoadAnimationAndSkin);
1761 LoadNode(pDevice, nullptr, node, scene.nodes[i], gltf_model,
1762 IndexData, VertexBasicData,
1763 CI.LoadAnimationAndSkin ? &VertexSkinData : nullptr);
17641764 }
17651765
17661766 if (CI.LoadAnimationAndSkin)
17911791
17921792 Extensions = gltf_model.extensionsUsed;
17931793
1794 {
1795 auto& VertexData0 = InitData->VertexBasicData;
1796 auto BufferSize = static_cast<Uint32>(VertexData0.size() * sizeof(VertexData0[0]));
1794 auto CreateBuffer = [&](BUFFER_ID BuffId, const void* pData, size_t Size, BIND_FLAGS BindFlags, const char* Name) //
1795 {
1796 VERIFY_EXPR(Size > 0);
1797
1798 auto BufferSize = static_cast<Uint32>(Size);
17971799 if (pResourceMgr != nullptr)
17981800 {
1799 Buffers[BUFFER_ID_VERTEX_BASIC_ATTRIBS].pSuballocation = pResourceMgr->AllocateBufferSpace(CI.pCacheInfo->VertexBuffer0Idx, BufferSize, 1);
1801 Uint32 CacheBufferIndex = 0;
1802 switch (BuffId)
1803 {
1804 case BUFFER_ID_INDEX:
1805 CacheBufferIndex = CI.pCacheInfo->IndexBufferIdx;
1806 break;
1807 case BUFFER_ID_VERTEX_BASIC_ATTRIBS:
1808 CacheBufferIndex = CI.pCacheInfo->VertexBuffer0Idx;
1809 break;
1810 case BUFFER_ID_VERTEX_SKIN_ATTRIBS:
1811 CacheBufferIndex = CI.pCacheInfo->VertexBuffer1Idx;
1812 break;
1813 default:
1814 UNEXPECTED("Unknown buffer id ", BuffId);
1815 }
1816 Buffers[BuffId].pSuballocation = pResourceMgr->AllocateBufferSpace(CacheBufferIndex, BufferSize, 1);
1817
1818 RefCntAutoPtr<DataBlobImpl> pBuffInitData{MakeNewRCObj<DataBlobImpl>()(Size)};
1819 memcpy(pBuffInitData->GetDataPtr(), pData, Size);
1820 Buffers[BuffId].pSuballocation->SetUserData(pBuffInitData);
18001821 }
18011822 else
18021823 {
1803
1804 VERIFY_EXPR(!VertexData0.empty());
1805 BufferDesc VBDesc;
1806 VBDesc.Name = "GLTF vertex attribs 0 buffer";
1807 VBDesc.uiSizeInBytes = BufferSize;
1808 VBDesc.BindFlags = BIND_VERTEX_BUFFER;
1809 VBDesc.Usage = USAGE_IMMUTABLE;
1810
1811 BufferData BuffData(VertexData0.data(), VBDesc.uiSizeInBytes);
1812 pDevice->CreateBuffer(VBDesc, &BuffData, &Buffers[BUFFER_ID_VERTEX_BASIC_ATTRIBS].pBuffer);
1813
1814 VertexData0.clear();
1815 }
1816 }
1817
1818 if (CI.LoadAnimationAndSkin)
1819 {
1820 auto& VertexData1 = InitData->VertexSkinData;
1821 auto BufferSize = static_cast<Uint32>(VertexData1.size() * sizeof(VertexData1[0]));
1822 if (pResourceMgr != nullptr)
1823 {
1824 Buffers[BUFFER_ID_VERTEX_SKIN_ATTRIBS].pSuballocation = pResourceMgr->AllocateBufferSpace(CI.pCacheInfo->VertexBuffer1Idx, BufferSize, 1);
1825 }
1826 else
1827 {
1828 VERIFY_EXPR(!VertexData1.empty());
1829 BufferDesc VBDesc;
1830 VBDesc.Name = "GLTF vertex attribs 1 buffer";
1831 VBDesc.uiSizeInBytes = BufferSize;
1832 VBDesc.BindFlags = BIND_VERTEX_BUFFER;
1833 VBDesc.Usage = USAGE_IMMUTABLE;
1834
1835 BufferData BuffData(VertexData1.data(), VBDesc.uiSizeInBytes);
1836 pDevice->CreateBuffer(VBDesc, &BuffData, &Buffers[BUFFER_ID_VERTEX_SKIN_ATTRIBS].pBuffer);
1837
1838 VertexData1.clear();
1839 }
1840 }
1841
1842
1843 if (!InitData->IndexData.empty())
1844 {
1845 auto& IndexBuffer = InitData->IndexData;
1846 auto BufferSize = static_cast<Uint32>(IndexBuffer.size() * sizeof(IndexBuffer[0]));
1847 if (pResourceMgr != nullptr)
1848 {
1849 Buffers[BUFFER_ID_INDEX].pSuballocation = pResourceMgr->AllocateBufferSpace(CI.pCacheInfo->IndexBufferIdx, BufferSize, 1);
1850 }
1851 else
1852 {
1853 BufferDesc IBDesc;
1854 IBDesc.Name = "GLTF inde buffer";
1855 IBDesc.uiSizeInBytes = BufferSize;
1856 IBDesc.BindFlags = BIND_INDEX_BUFFER;
1857 IBDesc.Usage = USAGE_IMMUTABLE;
1858
1859 BufferData BuffData(IndexBuffer.data(), IBDesc.uiSizeInBytes);
1860 pDevice->CreateBuffer(IBDesc, &BuffData, &Buffers[BUFFER_ID_INDEX].pBuffer);
1861
1862 IndexBuffer.clear();
1863 }
1824 BufferDesc BuffDesc;
1825 BuffDesc.Name = Name;
1826 BuffDesc.uiSizeInBytes = BufferSize;
1827 BuffDesc.BindFlags = BindFlags;
1828 BuffDesc.Usage = USAGE_IMMUTABLE;
1829
1830 BufferData BuffData{pData, BuffDesc.uiSizeInBytes};
1831 pDevice->CreateBuffer(BuffDesc, &BuffData, &Buffers[BuffId].pBuffer);
1832 }
1833 };
1834
1835 CreateBuffer(BUFFER_ID_VERTEX_BASIC_ATTRIBS, VertexBasicData.data(), VertexBasicData.size() * sizeof(VertexBasicData[0]),
1836 BIND_VERTEX_BUFFER, "GLTF vertex attribs 0 buffer");
1837
1838 if (!VertexSkinData.empty())
1839 {
1840 CreateBuffer(BUFFER_ID_VERTEX_SKIN_ATTRIBS, VertexSkinData.data(), VertexSkinData.size() * sizeof(VertexSkinData[0]),
1841 BIND_VERTEX_BUFFER, "GLTF vertex attribs 1 buffer");
1842 }
1843
1844 if (!IndexData.empty())
1845 {
1846 CreateBuffer(BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]),
1847 BIND_INDEX_BUFFER, "GLTF index buffer");
18641848 }
18651849
18661850 if (pContext != nullptr)