33// For conditions of distribution and use, see copyright notice in nabla.h
44#include " common.hpp"
55
6- class RayQueryGeometryApp final : public SimpleWindowedApplication, public MonoAssetManagerAndBuiltinResourceApplication
6+ class RayQueryGeometryApp final : public SimpleWindowedApplication, public BuiltinResourcesApplication
77{
88 using device_base_t = SimpleWindowedApplication;
9- using asset_base_t = MonoAssetManagerAndBuiltinResourceApplication ;
9+ using asset_base_t = BuiltinResourcesApplication ;
1010 using clock_t = std::chrono::steady_clock;
1111
1212 constexpr static inline uint32_t WIN_W = 1280 , WIN_H = 720 ;
@@ -486,25 +486,22 @@ class RayQueryGeometryApp final : public SimpleWindowedApplication, public MonoA
486486
487487 smart_refctd_ptr<IGPUDescriptorSet> createAccelerationStructureDS (video::CThreadSafeQueueAdapter* queue)
488488 {
489- // get geometries in ICPUBuffers
490- #if 1
491- return nullptr ;
492- #else
493- std::array<ReferenceObjectCpu, OT_COUNT> objectsCpu;
494- objectsCpu[OT_CUBE] = ReferenceObjectCpu{ .meta = {.type = OT_CUBE, .name = "Cube Mesh" }, .shadersType = GP_BASIC, .data = gc->createCubeMesh(nbl::core::vector3df(1.f, 1.f, 1.f)) };
495- objectsCpu[OT_SPHERE] = ReferenceObjectCpu{ .meta = {.type = OT_SPHERE, .name = "Sphere Mesh" }, .shadersType = GP_BASIC, .data = gc->createSphereMesh(2, 16, 16) };
496- objectsCpu[OT_CYLINDER] = ReferenceObjectCpu{ .meta = {.type = OT_CYLINDER, .name = "Cylinder Mesh" }, .shadersType = GP_BASIC, .data = gc->createCylinderMesh(2, 2, 20) };
497- objectsCpu[OT_RECTANGLE] = ReferenceObjectCpu{ .meta = {.type = OT_RECTANGLE, .name = "Rectangle Mesh" }, .shadersType = GP_BASIC, .data = gc->createRectangleMesh(nbl::core::vector2df_SIMD(1.5, 3)) };
498- objectsCpu[OT_DISK] = ReferenceObjectCpu{ .meta = {.type = OT_DISK, .name = "Disk Mesh" }, .shadersType = GP_BASIC, .data = gc->createDiskMesh(2, 30) };
499- objectsCpu[OT_ARROW] = ReferenceObjectCpu{ .meta = {.type = OT_ARROW, .name = "Arrow Mesh" }, .shadersType = GP_BASIC, .data = gc->createArrowMesh() };
500- objectsCpu[OT_CONE] = ReferenceObjectCpu{ .meta = {.type = OT_CONE, .name = "Cone Mesh" }, .shadersType = GP_CONE, .data = gc->createConeMesh(2, 3, 10) };
501- objectsCpu[OT_ICOSPHERE] = ReferenceObjectCpu{ .meta = {.type = OT_ICOSPHERE, .name = "Icosphere Mesh" }, .shadersType = GP_ICO, .data = gc->createIcoSphere(1, 3, true) };
489+ using namespace nbl ::scene;
490+
491+ // triangles geometries
492+ auto gc = make_smart_refctd_ptr<CGeometryCreator>();
493+
494+ std::array<ReferenceObjectCpu, OT_COUNT> cpuObjects;
495+ cpuObjects[OT_CUBE] = ReferenceObjectCpu{ .meta = {.type = OT_CUBE, .name = " Cube Mesh" }, .shadersType = GP_BASIC, .data = gc->createCube ({1 .f , 1 .f , 1 .f }) };
496+ cpuObjects[OT_SPHERE] = ReferenceObjectCpu{ .meta = {.type = OT_SPHERE, .name = " Sphere Mesh" }, .shadersType = GP_BASIC, .data = gc->createSphere (2 , 16 , 16 ) };
497+ cpuObjects[OT_CYLINDER] = ReferenceObjectCpu{ .meta = {.type = OT_CYLINDER, .name = " Cylinder Mesh" }, .shadersType = GP_BASIC, .data = gc->createCylinder (2 , 2 , 20 ) };
498+ cpuObjects[OT_RECTANGLE] = ReferenceObjectCpu{ .meta = {.type = OT_RECTANGLE, .name = " Rectangle Mesh" }, .shadersType = GP_BASIC, .data = gc->createRectangle ({1.5 , 3 }) };
499+ cpuObjects[OT_CONE] = ReferenceObjectCpu{ .meta = {.type = OT_CONE, .name = " Cone Mesh" }, .shadersType = GP_CONE, .data = gc->createCone (2 , 3 , 10 ) };
500+ cpuObjects[OT_ICOSPHERE] = ReferenceObjectCpu{ .meta = {.type = OT_ICOSPHERE, .name = " Icosphere Mesh" }, .shadersType = GP_ICO, .data = gc->createIcoSphere (1 , 3 , true ) };
502501
503502 auto geomInfoBuffer = ICPUBuffer::create ({ OT_COUNT * sizeof (SGeomInfo) });
504503
505504 SGeomInfo* geomInfos = reinterpret_cast <SGeomInfo*>(geomInfoBuffer->getPointer ());
506- const uint32_t byteOffsets[OT_COUNT] = { 18, 24, 24, 20, 20, 24, 16, 12 }; // based on normals data position
507- const uint32_t smoothNormals[OT_COUNT] = { 0, 1, 1, 0, 0, 1, 1, 1 };
508505
509506 // get ICPUBuffers into ICPUBottomLevelAccelerationStructures
510507 std::array<smart_refctd_ptr<ICPUBottomLevelAccelerationStructure>, OT_COUNT> cpuBlas;
@@ -514,37 +511,14 @@ class RayQueryGeometryApp final : public SimpleWindowedApplication, public MonoA
514511 auto primitiveCounts = make_refctd_dynamic_array<smart_refctd_dynamic_array<uint32_t >>(1u );
515512
516513 auto & tri = triangles->front ();
517- auto& primCount = primitiveCounts->front();
518- const auto& geom = objectsCpu[i];
519-
520- const bool useIndex = geom.data.indexType != EIT_UNKNOWN;
521- const uint32_t vertexStride = geom.data.inputParams.bindings[0].stride;
522- const uint32_t numVertices = (geom.data.bindings[0].buffer->getSize()-geom.data.bindings[0].offset) / vertexStride;
523514
524- if (useIndex)
525- primCount = geom.data.indexCount / 3;
526- else
527- primCount = numVertices / 3;
528-
529- geomInfos[i].indexType = geom.data.indexType;
530- geomInfos[i].vertexStride = vertexStride;
531- geomInfos[i].smoothNormals = smoothNormals[i];
515+ auto & primCount = primitiveCounts->front ();
516+ primCount = cpuObjects[i].data ->getPrimitiveCount ();
532517
533- geom.data.bindings[0].buffer->setContentHash(geom.data.bindings[0].buffer->computeContentHash());
534- tri.vertexData[0] = geom.data.bindings[0];
535- if (useIndex)
536- {
537- geom.data.indexBuffer.buffer->setContentHash(geom.data.indexBuffer.buffer->computeContentHash());
538- tri.indexData = geom.data.indexBuffer;
539- }
540- tri.maxVertex = numVertices - 1;
541- tri.vertexStride = vertexStride;
542- tri.vertexFormat = static_cast<E_FORMAT>(geom.data.inputParams.attributes[0].format);
543- tri.indexType = geom.data.indexType;
544- tri.geometryFlags = IGPUBottomLevelAccelerationStructure::GEOMETRY_FLAGS::OPAQUE_BIT;
518+ tri = cpuObjects[i].data ->exportForBLAS ();
545519
546520 auto & blas = cpuBlas[i];
547- blas = make_smart_refctd_ptr<ICPUBottomLevelAccelerationStructure>();
521+ blas = make_smart_refctd_ptr<ICPUBottomLevelAccelerationStructure>();
548522 blas->setGeometries (std::move (triangles), std::move (primitiveCounts));
549523
550524 auto blasFlags = bitflag (IGPUBottomLevelAccelerationStructure::BUILD_FLAGS::PREFER_FAST_TRACE_BIT) | IGPUBottomLevelAccelerationStructure::BUILD_FLAGS::ALLOW_COMPACTION_BIT;
@@ -639,28 +613,25 @@ class RayQueryGeometryApp final : public SimpleWindowedApplication, public MonoA
639613 CAssetConverter::patch_t <ICPUTopLevelAccelerationStructure> tlasPatch = {};
640614 tlasPatch.compactAfterBuild = true ;
641615 std::array<CAssetConverter::patch_t <ICPUBottomLevelAccelerationStructure>,OT_COUNT> tmpBLASPatches = {};
642- std::array<const ICPUBuffer *, OT_COUNT * 2u> tmpBuffers ;
643- std::array<CAssetConverter::patch_t<ICPUBuffer >, OT_COUNT * 2u> tmpBufferPatches ;
616+ std::array<ICPUPolygonGeometry *, std::size (cpuObjects)> tmpGeometries ;
617+ std::array<CAssetConverter::patch_t <asset::ICPUPolygonGeometry >, std::size (cpuObjects)> tmpGeometryPatches ;
644618 {
645619 tmpBLASPatches.front ().compactAfterBuild = true ;
646620 std::fill (tmpBLASPatches.begin (),tmpBLASPatches.end (),tmpBLASPatches.front ());
647621 //
648- for (uint32_t i = 0; i < objectsCpu.size(); i++)
649- {
650- tmpBuffers[2 * i + 0] = cpuBlas[i]->getTriangleGeometries().front().vertexData[0].buffer.get();
651- tmpBuffers[2 * i + 1] = cpuBlas[i]->getTriangleGeometries().front().indexData.buffer.get();
652- }
653- // make sure all buffers are BDA-readable
654- for (auto& patch : tmpBufferPatches)
655- patch.usage |= asset::IBuffer::E_USAGE_FLAGS::EUF_SHADER_DEVICE_ADDRESS_BIT;
622+ for (uint32_t i = 0 ; i < cpuObjects.size (); i++)
623+ {
624+ tmpGeometries[i] = cpuObjects[i].data .get ();
625+ tmpGeometryPatches[i].indexBufferUsages = IGPUBuffer::E_USAGE_FLAGS::EUF_SHADER_DEVICE_ADDRESS_BIT;
626+ }
656627
657628 std::get<CAssetConverter::SInputs::asset_span_t <ICPUDescriptorSet>>(inputs.assets ) = {&descriptorSet.get (),1 };
658629 std::get<CAssetConverter::SInputs::asset_span_t <ICPUTopLevelAccelerationStructure>>(inputs.assets ) = {&cpuTlas.get (),1 };
659630 std::get<CAssetConverter::SInputs::patch_span_t <ICPUTopLevelAccelerationStructure>>(inputs.patches ) = {&tlasPatch,1 };
660631 std::get<CAssetConverter::SInputs::asset_span_t <ICPUBottomLevelAccelerationStructure>>(inputs.assets ) = {&cpuBlas.data ()->get (),cpuBlas.size ()};
661632 std::get<CAssetConverter::SInputs::patch_span_t <ICPUBottomLevelAccelerationStructure>>(inputs.patches ) = tmpBLASPatches;
662- std::get<CAssetConverter::SInputs::asset_span_t<ICPUBuffer >>(inputs.assets) = tmpBuffers ;
663- std::get<CAssetConverter::SInputs::patch_span_t<ICPUBuffer >>(inputs.patches) = tmpBufferPatches ;
633+ std::get<CAssetConverter::SInputs::asset_span_t <ICPUPolygonGeometry >>(inputs.assets ) = tmpGeometries ;
634+ std::get<CAssetConverter::SInputs::patch_span_t <ICPUPolygonGeometry >>(inputs.patches ) = tmpGeometryPatches ;
664635 }
665636
666637 auto reservation = converter->reserve (inputs);
@@ -783,19 +754,38 @@ class RayQueryGeometryApp final : public SimpleWindowedApplication, public MonoA
783754 return {};
784755 }
785756
786- // assign gpu objects to output
787- for (const auto& buffer : reservation.getGPUObjects<ICPUBuffer>())
788- retainedBuffers.push_back(buffer.value);
789- for (uint32_t i = 0; i < objectsCpu.size(); i++)
790- {
791- auto vBuffer = retainedBuffers[2 * i + 0].get();
792- auto iBuffer = retainedBuffers[2 * i + 1].get();
793- const auto& geom = objectsCpu[i];
794- const bool useIndex = geom.data.indexType != EIT_UNKNOWN;
757+ auto && tlases = reservation.getGPUObjects <ICPUTopLevelAccelerationStructure>();
758+ m_gpuTlas = tlases[0 ].value ;
795759
796- geomInfos[i].vertexBufferAddress = vBuffer->getDeviceAddress() + byteOffsets[i];
797- geomInfos[i].indexBufferAddress = useIndex ? iBuffer->getDeviceAddress():0x0ull;
798- }
760+ auto && gpuPolygonGeometries = reservation.getGPUObjects <ICPUPolygonGeometry>();
761+ m_gpuPolygons.resize (gpuPolygonGeometries.size ());
762+
763+ // assign gpu objects to output
764+ for (uint32_t i = 0 ; i < gpuPolygonGeometries.size (); i++)
765+ {
766+ const auto & cpuObject = cpuObjects[i];
767+ const auto & gpuPolygon = gpuPolygonGeometries[i].value ;
768+ const auto gpuTriangles = gpuPolygon->exportForBLAS ();
769+
770+ const auto & vertexBufferBinding = gpuTriangles.vertexData [0 ];
771+ const uint64_t vertexBufferAddress = vertexBufferBinding.buffer ->getDeviceAddress () + vertexBufferBinding.offset ;
772+
773+ const auto & normalView = gpuPolygon->getNormalView ();
774+ const uint64_t normalBufferAddress = normalView ? normalView.src .buffer ->getDeviceAddress () + normalView.src .offset : 0 ;
775+
776+ const auto & indexBufferBinding = gpuTriangles.indexData ;
777+ auto & geomInfo = geomInfos[i];
778+ geomInfo = {
779+ .vertexBufferAddress = vertexBufferAddress,
780+ .indexBufferAddress = indexBufferBinding.buffer ? indexBufferBinding.buffer ->getDeviceAddress () + indexBufferBinding.offset : vertexBufferAddress,
781+ .normalBufferAddress = normalBufferAddress,
782+ .vertexStride = gpuTriangles.vertexStride ,
783+ .indexType = gpuTriangles.indexType ,
784+ .smoothNormals = s_smoothNormals[cpuObject.meta .type ],
785+ };
786+
787+ m_gpuPolygons[i] = gpuPolygon;
788+ }
799789 }
800790
801791 //
@@ -892,7 +882,6 @@ class RayQueryGeometryApp final : public SimpleWindowedApplication, public MonoA
892882 m_api->endCapture ();
893883
894884 return reservation.getGPUObjects <ICPUDescriptorSet>().front ().value ;
895- #endif
896885 }
897886
898887
@@ -911,11 +900,13 @@ class RayQueryGeometryApp final : public SimpleWindowedApplication, public MonoA
911900 video::CDumbPresentationOracle oracle;
912901
913902 smart_refctd_ptr<IGPUBuffer> geometryInfoBuffer;
914- core::vector<smart_refctd_ptr<IGPUBuffer>> retainedBuffers;
915903 smart_refctd_ptr<IGPUImage> outHDRImage;
904+ core::vector<smart_refctd_ptr<IGPUPolygonGeometry>> m_gpuPolygons;
905+ smart_refctd_ptr<IGPUTopLevelAccelerationStructure> m_gpuTlas;
916906
917907 smart_refctd_ptr<IGPUComputePipeline> renderPipeline;
918908 smart_refctd_ptr<IGPUDescriptorSet> renderDs;
909+
919910};
920911
921912NBL_MAIN_FUNC (RayQueryGeometryApp)
0 commit comments