From 8b0bb45b9740422f7f6b6478a9fdd906fcf35789 Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Tue, 12 May 2026 23:36:15 +0200 Subject: [PATCH 1/9] Added more markers to case 10 --- 62_CAD/main.cpp | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/62_CAD/main.cpp b/62_CAD/main.cpp index 1a54531b8..700562e8a 100644 --- a/62_CAD/main.cpp +++ b/62_CAD/main.cpp @@ -80,7 +80,7 @@ constexpr std::array cameraExtents = 10.0 // CASE_12 }; -constexpr ExampleMode mode = ExampleMode::CASE_2; +constexpr ExampleMode mode = ExampleMode::CASE_10; class Camera2D { @@ -3752,7 +3752,7 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio LineStyleInfo style = {}; style.screenSpaceLineWidth = 4.0f; - style.color = float32_t4(0.619f, 0.325f, 0.709f, 0.5f); + style.color = float32_t4(0.2f, 0.2f, 0.2f, 0.5f); for (uint32_t i = 0; i < 128u; ++i) { @@ -3809,7 +3809,7 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio 0.0, 0.0, 1.0 }; - float64_t2 scale = float64_t2{ 100.0, 100.0 }; + float64_t2 scale = float64_t2{ 10.0, 10.0 }; float64_t3x3 scaleMat = { scale.x, 0.0, 0.0, @@ -3821,8 +3821,35 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio polyline.addLinePoints(line0); polyline.addLinePoints(line1); polyline.preprocessPolylineWithStyle(style); - // drawResourcesFiller.drawPolyline(polyline, intendedNextSubmit); - drawResourcesFiller.drawFixedGeometryPolyline(polyline, style, transformation, TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); + //drawResourcesFiller.drawPolyline(polyline, intendedNextSubmit); + //drawResourcesFiller.drawFixedGeometryPolyline(polyline, style, transformation, TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); + + constexpr int MarkerCount = 1000000; + for (int i = 0; i < MarkerCount; ++i) + { + translateMat = + { + 1.0, 0.0, static_cast(i) / static_cast(MarkerCount*0.2), + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0 + }; + + const float64_t rotationAngle = (core::radians(360.0) / static_cast(MarkerCount)) * i * 10; + dir = float64_t2{ std::cos(rotationAngle), std::sin(rotationAngle) }; + rotateMat = + { + dir.x, -dir.y, 0.0, + dir.y, dir.x, 0.0, + 0.0, 0.0, 1.0 + }; + + + transformation = nbl::hlsl::mul(rotateMat, translateMat); + + transformation = nbl::hlsl::mul(rotateMat, nbl::hlsl::mul(translateMat, scaleMat)); + + drawResourcesFiller.drawFixedGeometryPolyline(polyline, style, transformation, TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); + } } } else if (mode == ExampleMode::CASE_11) From ed9d686b932d5f0edeb278e2709a96ce69c8aad7 Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Mon, 18 May 2026 22:03:37 +0200 Subject: [PATCH 2/9] Packed members of the `DrawObject` struct into a bitfield --- 62_CAD/DrawResourcesFiller.cpp | 25 ++++-- 62_CAD/DrawResourcesFiller.h | 2 +- 62_CAD/main.cpp | 5 +- 62_CAD/shaders/globals.hlsl | 11 +-- .../shaders/main_pipeline/vertex_shader.hlsl | 76 ++++++++++--------- 5 files changed, 66 insertions(+), 53 deletions(-) diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index 97ae6621b..e9d69a06e 100644 --- a/62_CAD/DrawResourcesFiller.cpp +++ b/62_CAD/DrawResourcesFiller.cpp @@ -2396,7 +2396,8 @@ void DrawResourcesFiller::addPolylineConnectors_Internal(const CPolylineBase& po DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::POLYLINE_CONNECTOR) | 0 << 16); + drawObj.type = ObjectType::POLYLINE_CONNECTOR; + drawObj.subsectionIdx = 0; drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2452,7 +2453,8 @@ void DrawResourcesFiller::addLines_Internal(const CPolylineBase& polyline, const DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::LINE) | 0 << 16); + drawObj.type = ObjectType::LINE; + drawObj.subsectionIdx = 0; drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2514,7 +2516,9 @@ void DrawResourcesFiller::addQuadBeziers_Internal(const CPolylineBase& polyline, { for (uint16_t subObject = 0; subObject < CagesPerQuadBezier; subObject++) { - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::QUAD_BEZIER) | (subObject << 16)); + assert(subObject < 4); // there can be maximum 4 subsections + drawObj.type = ObjectType::QUAD_BEZIER; + drawObj.subsectionIdx = subObject; drawObjectsToBeFilled[i * CagesPerQuadBezier + subObject] = drawObj; } drawObj.geometryAddress += sizeof(QuadraticBezierInfo); @@ -2562,7 +2566,8 @@ void DrawResourcesFiller::addHatch_Internal(const Hatch& hatch, uint32_t& curren DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; drawObj.mainObjIndex = mainObjIndex; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::CURVE_BOX) | (0 << 16)); + drawObj.type = ObjectType::CURVE_BOX; + drawObj.subsectionIdx = 0; drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2604,7 +2609,8 @@ bool DrawResourcesFiller::addFontGlyph_Internal(const GlyphInfo& glyphInfo, uint DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::FONT_GLYPH) | (0 << 16)); + drawObj.type = ObjectType::FONT_GLYPH; + drawObj.subsectionIdx = 0; drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2641,7 +2647,8 @@ bool DrawResourcesFiller::addGridDTM_Internal(const GridDTMInfo& gridDTMInfo, ui DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::GRID_DTM) | (0 << 16)); + drawObj.type = ObjectType::GRID_DTM; + drawObj.subsectionIdx = 0; drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2678,7 +2685,8 @@ bool DrawResourcesFiller::addImageObject_Internal(const ImageObjectInfo& imageOb DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::STATIC_IMAGE) | (0 << 16)); // TODO: use custom pack/unpack function + drawObj.type = ObjectType::STATIC_IMAGE; + drawObj.subsectionIdx = 0; drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2715,7 +2723,8 @@ bool DrawResourcesFiller::addGeoreferencedImageInfo_Internal(const Georeferenced DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::STREAMED_IMAGE) | (0 << 16)); // TODO: use custom pack/unpack function + drawObj.type = ObjectType::STREAMED_IMAGE; + drawObj.subsectionIdx = 0; drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; diff --git a/62_CAD/DrawResourcesFiller.h b/62_CAD/DrawResourcesFiller.h index 3b0e0c4bb..2a83a1946 100644 --- a/62_CAD/DrawResourcesFiller.h +++ b/62_CAD/DrawResourcesFiller.h @@ -29,7 +29,7 @@ using namespace nbl::video; using namespace nbl::core; using namespace nbl::asset; -static_assert(sizeof(DrawObject) == 16u); +static_assert(sizeof(DrawObject) == 8u); static_assert(sizeof(MainObject) == 20u); static_assert(sizeof(LineStyle) == 88u); diff --git a/62_CAD/main.cpp b/62_CAD/main.cpp index 700562e8a..47bfbf27b 100644 --- a/62_CAD/main.cpp +++ b/62_CAD/main.cpp @@ -3824,7 +3824,8 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio //drawResourcesFiller.drawPolyline(polyline, intendedNextSubmit); //drawResourcesFiller.drawFixedGeometryPolyline(polyline, style, transformation, TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); - constexpr int MarkerCount = 1000000; + //constexpr int MarkerCount = 1000000; + constexpr int MarkerCount = 1; for (int i = 0; i < MarkerCount; ++i) { translateMat = @@ -3834,7 +3835,7 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio 0.0, 0.0, 1.0 }; - const float64_t rotationAngle = (core::radians(360.0) / static_cast(MarkerCount)) * i * 10; + const float64_t rotationAngle = (core::radians(360.0) / static_cast(MarkerCount)) * static_cast(i) * 10.0; dir = float64_t2{ std::cos(rotationAngle), std::sin(rotationAngle) }; rotateMat = { diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index 0d2c1190a..cf9565611 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -159,9 +159,10 @@ struct MainObject struct DrawObject { - uint32_t type_subsectionIdx; // packed two uint16 into uint32 - uint32_t mainObjIndex; - uint64_t geometryAddress; + ObjectType type : 4; // 16 different object types + uint32_t subsectionIdx : 2; // 4 max subsections + uint32_t mainObjIndex : 26; // 67M main objects max + uint32_t geometryAddress; // geometry has 8 byte alignment, max 34GB of data to reference }; // Goes into geometry buffer, needs to be aligned by 8 @@ -618,7 +619,7 @@ MainObject loadMainObject(const uint32_t index) } DrawObject loadDrawObject(const uint32_t index) { - return vk::RawBufferLoad(globals.pointers.drawObjects + index * sizeof(DrawObject), 8u); + return vk::RawBufferLoad(globals.pointers.drawObjects + index * sizeof(DrawObject), 4u); } #else static_assert(alignof(LineStyle)==4u); @@ -626,7 +627,7 @@ static_assert(alignof(DTMSettings)==4u); static_assert(alignof(pfloat64_t3x3)==8u); static_assert(alignof(WorldClipRect)==8u); static_assert(alignof(MainObject)==4u); -static_assert(alignof(DrawObject)==8u); +static_assert(alignof(DrawObject)==4u); #endif diff --git a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl index 45a308daa..a7e94171b 100644 --- a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl @@ -203,11 +203,13 @@ PSInput vtxMain(uint vertexID : SV_VertexID) DrawObject drawObj = loadDrawObject(objectID); - ObjectType objType = (ObjectType)(drawObj.type_subsectionIdx & 0x0000FFFF); - uint32_t subsectionIdx = drawObj.type_subsectionIdx >> 16; + ObjectType objType = drawObj.type; + uint32_t subsectionIdx = drawObj.subsectionIdx; outV.setObjType(objType); outV.setMainObjectIdx(drawObj.mainObjIndex); + printf("offset: %u", drawObj.geometryAddress); + MainObject mainObj = loadMainObject(drawObj.mainObjIndex); clipProjectionData = getClipProjectionData(mainObj); @@ -230,11 +232,11 @@ PSInput vtxMain(uint vertexID : SV_VertexID) if (objType == ObjectType::LINE) { pfloat64_t2 points[2u]; - points[0u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - points[1u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(LinePointInfo), 8u); + points[0u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + points[1u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(LinePointInfo), 8u); - const float phaseShift = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 8u); - const float patternStretch = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float), 8u); + const float phaseShift = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 8u); + const float patternStretch = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float), 8u); outV.setCurrentPhaseShift(phaseShift); outV.setPatternStretch(patternStretch); @@ -270,12 +272,12 @@ PSInput vtxMain(uint vertexID : SV_VertexID) else if (objType == ObjectType::QUAD_BEZIER) { pfloat64_t2 points[3u]; - points[0u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - points[1u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 8u); - points[2u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) * 2u, 8u); + points[0u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + points[1u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 8u); + points[2u] = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) * 2u, 8u); - const float phaseShift = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) * 3u, 8u); - const float patternStretch = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) * 3u + sizeof(float), 8u); + const float phaseShift = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) * 3u, 8u); + const float patternStretch = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) * 3u + sizeof(float), 8u); outV.setCurrentPhaseShift(phaseShift); outV.setPatternStretch(patternStretch); @@ -444,9 +446,9 @@ PSInput vtxMain(uint vertexID : SV_VertexID) if (lineStyle.isRoadStyleFlag) { - const pfloat64_t2 circleCenter = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - const float2 v = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 8u); - const float cosHalfAngleBetweenNormals = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float2), 8u); + const pfloat64_t2 circleCenter = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + const float2 v = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 8u); + const float cosHalfAngleBetweenNormals = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float2), 8u); const float2 circleCenterScreenSpace = transformPointScreenSpace(clipProjectionData.projectionToNDC, globals.resolution, circleCenter); outV.setPolylineConnectorCircleCenter(circleCenterScreenSpace); @@ -510,13 +512,13 @@ PSInput vtxMain(uint vertexID : SV_VertexID) else if (objType == ObjectType::CURVE_BOX) { CurveBox curveBox; - curveBox.aabbMin = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - curveBox.aabbMax = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 8u); + curveBox.aabbMin = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + curveBox.aabbMax = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 8u); for (uint32_t i = 0; i < 3; i ++) { - curveBox.curveMin[i] = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) * 2 + sizeof(float32_t2) * i, 4u); - curveBox.curveMax[i] = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) * 2 + sizeof(float32_t2) * (3 + i), 4u); + curveBox.curveMin[i] = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) * 2 + sizeof(float32_t2) * i, 4u); + curveBox.curveMax[i] = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) * 2 + sizeof(float32_t2) * (3 + i), 4u); } pfloat64_t2 aabbMaxXMinY; @@ -601,10 +603,10 @@ PSInput vtxMain(uint vertexID : SV_VertexID) const float italicTiltSlope = lineStyle.screenSpaceLineWidth; // aliased text style member with line style GlyphInfo glyphInfo; - glyphInfo.topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - glyphInfo.dirU = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 4u); - glyphInfo.aspectRatio = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float2), 4u); - glyphInfo.minUV_textureID_packed = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float2) + sizeof(float), 4u); + glyphInfo.topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + glyphInfo.dirU = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 4u); + glyphInfo.aspectRatio = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float2), 4u); + glyphInfo.minUV_textureID_packed = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float2) + sizeof(float), 4u); float32_t2 minUV = glyphInfo.getMinUV(); uint16_t textureID = glyphInfo.getTextureID(); @@ -652,10 +654,10 @@ PSInput vtxMain(uint vertexID : SV_VertexID) } else if (objType == ObjectType::STATIC_IMAGE) { - pfloat64_t2 topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - float32_t2 dirU = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 4u); - float32_t aspectRatio = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float2), 4u); - uint32_t textureID = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float2) + sizeof(float), 4u); + pfloat64_t2 topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + float32_t2 dirU = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 4u); + float32_t aspectRatio = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float2), 4u); + uint32_t textureID = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float2) + sizeof(float), 4u); // TODO[DEVSH]: make sure it's documented properly that for topLeft+dirV+aspectRatio to work it's computing dirU like below (they need to be careful with transformations when y increases when you go down in screen const float32_t2 dirV = float32_t2(dirU.y, -dirU.x) * aspectRatio; @@ -674,11 +676,11 @@ PSInput vtxMain(uint vertexID : SV_VertexID) } else if (objType == ObjectType::GRID_DTM) { - pfloat64_t2 topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - const pfloat64_t2 worldSpaceExtents = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 8u); - uint32_t textureID = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + 2 * sizeof(pfloat64_t2), 8u); - float gridCellWidth = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + 2 * sizeof(pfloat64_t2) + sizeof(uint32_t), 8u); - float thicknessOfTheThickestLine = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + 2 * sizeof(pfloat64_t2) + sizeof(uint32_t) + sizeof(float), 8u); + pfloat64_t2 topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + const pfloat64_t2 worldSpaceExtents = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 8u); + uint32_t textureID = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + 2 * sizeof(pfloat64_t2), 8u); + float gridCellWidth = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + 2 * sizeof(pfloat64_t2) + sizeof(uint32_t), 8u); + float thicknessOfTheThickestLine = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + 2 * sizeof(pfloat64_t2) + sizeof(uint32_t) + sizeof(float), 8u); // TODO: remove // test large dilation @@ -740,12 +742,12 @@ PSInput vtxMain(uint vertexID : SV_VertexID) } else if (objType == ObjectType::STREAMED_IMAGE) { - const pfloat64_t2 topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress, 8u); - const float32_t2 dirU = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2), 4u); - const float32_t aspectRatio = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float32_t2), 4u); - const uint32_t textureID = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float32_t2) + sizeof(float32_t), 4u); - const float32_t2 minUV = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + sizeof(float32_t2) + sizeof(float32_t) + sizeof(uint32_t), 4u); - const float32_t2 maxUV = vk::RawBufferLoad(globals.pointers.geometryBuffer + drawObj.geometryAddress + sizeof(pfloat64_t2) + 2 * sizeof(float32_t2) + sizeof(float32_t) + sizeof(uint32_t), 4u); + const pfloat64_t2 topLeft = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress), 8u); + const float32_t2 dirU = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2), 4u); + const float32_t aspectRatio = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float32_t2), 4u); + const uint32_t textureID = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float32_t2) + sizeof(float32_t), 4u); + const float32_t2 minUV = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + sizeof(float32_t2) + sizeof(float32_t) + sizeof(uint32_t), 4u); + const float32_t2 maxUV = vk::RawBufferLoad(globals.pointers.geometryBuffer + uint64_t(drawObj.geometryAddress) + sizeof(pfloat64_t2) + 2 * sizeof(float32_t2) + sizeof(float32_t) + sizeof(uint32_t), 4u); const float32_t2 dirV = float32_t2(dirU.y, -dirU.x) * aspectRatio; const float32_t2 ndcTopLeft = _static_cast(transformPointNdc(clipProjectionData.projectionToNDC, topLeft)); From b30f0909a4a4ffabb807c7629f80062b6de640f1 Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Sat, 23 May 2026 17:27:03 +0200 Subject: [PATCH 3/9] Implemented bitfield --- 62_CAD/DrawResourcesFiller.cpp | 48 +++++++++---------- 62_CAD/main.cpp | 3 +- 62_CAD/shaders/globals.hlsl | 18 +++++-- .../shaders/main_pipeline/vertex_shader.hlsl | 8 ++-- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index e9d69a06e..7dc9acf32 100644 --- a/62_CAD/DrawResourcesFiller.cpp +++ b/62_CAD/DrawResourcesFiller.cpp @@ -2395,9 +2395,9 @@ void DrawResourcesFiller::addPolylineConnectors_Internal(const CPolylineBase& po // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type = ObjectType::POLYLINE_CONNECTOR; - drawObj.subsectionIdx = 0; + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::POLYLINE_CONNECTOR); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2452,9 +2452,9 @@ void DrawResourcesFiller::addLines_Internal(const CPolylineBase& polyline, const // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type = ObjectType::LINE; - drawObj.subsectionIdx = 0; + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::LINE); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2510,15 +2510,15 @@ void DrawResourcesFiller::addQuadBeziers_Internal(const CPolylineBase& polyline, // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(cagesCount); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; + drawObj.setMainObjIndex(mainObjIdx); drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { for (uint16_t subObject = 0; subObject < CagesPerQuadBezier; subObject++) { assert(subObject < 4); // there can be maximum 4 subsections - drawObj.type = ObjectType::QUAD_BEZIER; - drawObj.subsectionIdx = subObject; + drawObj.setType(ObjectType::QUAD_BEZIER); + drawObj.setSubsectionIdx(subObject); drawObjectsToBeFilled[i * CagesPerQuadBezier + subObject] = drawObj; } drawObj.geometryAddress += sizeof(QuadraticBezierInfo); @@ -2565,9 +2565,9 @@ void DrawResourcesFiller::addHatch_Internal(const Hatch& hatch, uint32_t& curren // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIndex; - drawObj.type = ObjectType::CURVE_BOX; - drawObj.subsectionIdx = 0; + drawObj.setMainObjIndex(mainObjIndex); + drawObj.setType(ObjectType::CURVE_BOX); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2608,9 +2608,9 @@ bool DrawResourcesFiller::addFontGlyph_Internal(const GlyphInfo& glyphInfo, uint // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type = ObjectType::FONT_GLYPH; - drawObj.subsectionIdx = 0; + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::FONT_GLYPH); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2646,9 +2646,9 @@ bool DrawResourcesFiller::addGridDTM_Internal(const GridDTMInfo& gridDTMInfo, ui // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type = ObjectType::GRID_DTM; - drawObj.subsectionIdx = 0; + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::GRID_DTM); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2684,9 +2684,9 @@ bool DrawResourcesFiller::addImageObject_Internal(const ImageObjectInfo& imageOb // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type = ObjectType::STATIC_IMAGE; - drawObj.subsectionIdx = 0; + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::STATIC_IMAGE); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2722,9 +2722,9 @@ bool DrawResourcesFiller::addGeoreferencedImageInfo_Internal(const Georeferenced // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type = ObjectType::STREAMED_IMAGE; - drawObj.subsectionIdx = 0; + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::STREAMED_IMAGE); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; diff --git a/62_CAD/main.cpp b/62_CAD/main.cpp index 47bfbf27b..78cc0bbb2 100644 --- a/62_CAD/main.cpp +++ b/62_CAD/main.cpp @@ -3824,8 +3824,7 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio //drawResourcesFiller.drawPolyline(polyline, intendedNextSubmit); //drawResourcesFiller.drawFixedGeometryPolyline(polyline, style, transformation, TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); - //constexpr int MarkerCount = 1000000; - constexpr int MarkerCount = 1; + constexpr int MarkerCount = 1000000; for (int i = 0; i < MarkerCount; ++i) { translateMat = diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index cf9565611..915b6eed5 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef __HLSL_VERSION #include @@ -159,10 +160,21 @@ struct MainObject struct DrawObject { - ObjectType type : 4; // 16 different object types - uint32_t subsectionIdx : 2; // 4 max subsections - uint32_t mainObjIndex : 26; // 67M main objects max + uint32_t packedData; uint32_t geometryAddress; // geometry has 8 byte alignment, max 34GB of data to reference + + using TypeField = utils::BitField; // 16 different object types + using SubsectionField = utils::BitField; // 4 max subsections + using MainObjField = utils::BitField; // 67M main objects max + + ObjectType getType() { return (ObjectType)TypeField::get(packedData); } + void setType(ObjectType objType) { packedData = TypeField::set(packedData, (uint32_t)objType); } + + uint32_t getSubsectionIdx() { return SubsectionField::get(packedData); } + void setSubsectionIdx(uint32_t subsectionIdx) { packedData = SubsectionField::set(packedData, subsectionIdx); } + + uint32_t getMainObjIndex() { return MainObjField::get(packedData); } + void setMainObjIndex(uint32_t mainObjIdx) { packedData = MainObjField::set(packedData, mainObjIdx); } }; // Goes into geometry buffer, needs to be aligned by 8 diff --git a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl index a7e94171b..a9f3932cb 100644 --- a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl @@ -203,14 +203,14 @@ PSInput vtxMain(uint vertexID : SV_VertexID) DrawObject drawObj = loadDrawObject(objectID); - ObjectType objType = drawObj.type; - uint32_t subsectionIdx = drawObj.subsectionIdx; + ObjectType objType = drawObj.getType(); + uint32_t subsectionIdx = drawObj.getSubsectionIdx(); outV.setObjType(objType); - outV.setMainObjectIdx(drawObj.mainObjIndex); + outV.setMainObjectIdx(drawObj.getMainObjIndex()); printf("offset: %u", drawObj.geometryAddress); - MainObject mainObj = loadMainObject(drawObj.mainObjIndex); + MainObject mainObj = loadMainObject(drawObj.getMainObjIndex()); clipProjectionData = getClipProjectionData(mainObj); float screenToWorldRatio = getScreenToWorldRatio(clipProjectionData.projectionToNDC, globals.resolution); From 9aac52e295e26d98e0108b477fd4e74731272b8a Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Mon, 25 May 2026 16:13:20 +0200 Subject: [PATCH 4/9] Optimized the `MainObject` struct --- 62_CAD/DrawResourcesFiller.cpp | 54 +++++++++++-------- 62_CAD/DrawResourcesFiller.h | 14 ++--- 62_CAD/main.cpp | 1 - 62_CAD/shaders/globals.hlsl | 32 +++++++---- .../main_pipeline/fragment_shader.hlsl | 22 ++++---- .../fragment_shader_resolve_alphas.hlsl | 8 +-- .../shaders/main_pipeline/vertex_shader.hlsl | 18 +++---- 7 files changed, 86 insertions(+), 63 deletions(-) diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index 7dc9acf32..cda1668fd 100644 --- a/62_CAD/DrawResourcesFiller.cpp +++ b/62_CAD/DrawResourcesFiller.cpp @@ -1384,13 +1384,13 @@ const DrawResourcesFiller::ResourcesCollection& DrawResourcesFiller::getResource void DrawResourcesFiller::setActiveLineStyle(const LineStyleInfo& lineStyle) { activeLineStyle = lineStyle; - activeLineStyleIndex = InvalidStyleIdx; + activeLineStyleIndex = MainObject::getInvalidStyleIndex(); } void DrawResourcesFiller::setActiveDTMSettings(const DTMSettingsInfo& dtmSettingsInfo) { activeDTMSettings = dtmSettingsInfo; - activeDTMSettingsIndex = InvalidDTMSettingsIdx; + activeDTMSettingsIndex = MainObject::getInvalidDtmSettingsIndex(); } void DrawResourcesFiller::beginMainObject(MainObjectType type, TransformationType transformationType) @@ -1410,7 +1410,7 @@ void DrawResourcesFiller::endMainObject() void DrawResourcesFiller::pushCustomProjection(const float64_t3x3& projection) { activeProjections.push_back(projection); - activeProjectionIndices.push_back(InvalidCustomProjectionIndex); + activeProjectionIndices.push_back(MainObject::getInvalidCustomTransformationIndex()); } void DrawResourcesFiller::popCustomProjection() @@ -1425,7 +1425,7 @@ void DrawResourcesFiller::popCustomProjection() void DrawResourcesFiller::pushCustomClipRect(const WorldClipRect& clipRect) { activeClipRects.push_back(clipRect); - activeClipRectIndices.push_back(InvalidCustomClipRectIndex); + activeClipRectIndices.push_back(MainObject::getInvalidCustomClipRectIndex()); } void DrawResourcesFiller::popCustomClipRect() @@ -2077,7 +2077,7 @@ uint32_t DrawResourcesFiller::addLineStyle_Internal(const LineStyleInfo& lineSty const size_t remainingResourcesSize = calculateRemainingResourcesSize(); const bool enoughMem = remainingResourcesSize >= sizeof(LineStyle); // enough remaining memory for 1 more linestyle? if (!enoughMem) - return InvalidStyleIdx; + return MainObject::getInvalidStyleIndex(); // TODO: Maybe constraint by a max size? and return InvalidIdx if it would exceed LineStyle gpuLineStyle = lineStyleInfo.getAsGPUData(); @@ -2100,7 +2100,7 @@ uint32_t DrawResourcesFiller::addDTMSettings_Internal(const DTMSettingsInfo& dtm const bool enoughMem = remainingResourcesSize >= maxMemRequired; // enough remaining memory for 1 more dtm settings with 2 referenced line styles? if (!enoughMem) - return InvalidDTMSettingsIdx; + return MainObject::getInvalidDtmSettingsIndex(); // TODO: Maybe constraint by a max size? and return InvalidIdx if it would exceed DTMSettings dtmSettings; @@ -2200,7 +2200,7 @@ float64_t3x3 DrawResourcesFiller::getFixedGeometryFinalTransformationMatrix(cons uint32_t DrawResourcesFiller::acquireActiveLineStyleIndex_SubmitIfNeeded(SIntendedSubmitInfo& intendedNextSubmit) { - if (activeLineStyleIndex == InvalidStyleIdx) + if (activeLineStyleIndex == MainObject::getInvalidStyleIndex()) activeLineStyleIndex = addLineStyle_SubmitIfNeeded(activeLineStyle, intendedNextSubmit); return activeLineStyleIndex; @@ -2208,7 +2208,7 @@ uint32_t DrawResourcesFiller::acquireActiveLineStyleIndex_SubmitIfNeeded(SIntend uint32_t DrawResourcesFiller::acquireActiveDTMSettingsIndex_SubmitIfNeeded(SIntendedSubmitInfo& intendedNextSubmit) { - if (activeDTMSettingsIndex == InvalidDTMSettingsIdx) + if (activeDTMSettingsIndex == MainObject::getInvalidDtmSettingsIndex()) activeDTMSettingsIndex = addDTMSettings_SubmitIfNeeded(activeDTMSettings, intendedNextSubmit); return activeDTMSettingsIndex; @@ -2217,9 +2217,9 @@ uint32_t DrawResourcesFiller::acquireActiveDTMSettingsIndex_SubmitIfNeeded(SInte uint32_t DrawResourcesFiller::acquireActiveCustomProjectionIndex_SubmitIfNeeded(SIntendedSubmitInfo& intendedNextSubmit) { if (activeProjectionIndices.empty()) - return InvalidCustomProjectionIndex; + return MainObject::getInvalidCustomTransformationIndex(); - if (activeProjectionIndices.back() == InvalidCustomProjectionIndex) + if (activeProjectionIndices.back() == MainObject::getInvalidCustomTransformationIndex()) activeProjectionIndices.back() = addCustomProjection_SubmitIfNeeded(activeProjections.back(), intendedNextSubmit); return activeProjectionIndices.back(); @@ -2228,9 +2228,9 @@ uint32_t DrawResourcesFiller::acquireActiveCustomProjectionIndex_SubmitIfNeeded( uint32_t DrawResourcesFiller::acquireActiveCustomClipRectIndex_SubmitIfNeeded(SIntendedSubmitInfo& intendedNextSubmit) { if (activeClipRectIndices.empty()) - return InvalidCustomClipRectIndex; + return MainObject::getInvalidCustomClipRectIndex(); - if (activeClipRectIndices.back() == InvalidCustomClipRectIndex) + if (activeClipRectIndices.back() == MainObject::getInvalidCustomClipRectIndex()) activeClipRectIndices.back() = addCustomClipRect_SubmitIfNeeded(activeClipRects.back(), intendedNextSubmit); return activeClipRectIndices.back(); @@ -2275,11 +2275,23 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten MainObject mainObject = {}; // These 3 calls below shouldn't need to Submit because we made sure there is enough memory for all of them. // if something here triggers a auto-submit it's a possible bug with calculating `memRequired` above, TODO: assert that somehow? - mainObject.styleIdx = (needsLineStyle) ? acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit) : InvalidStyleIdx; - mainObject.dtmSettingsIdx = (needsDTMSettings) ? acquireActiveDTMSettingsIndex_SubmitIfNeeded(intendedNextSubmit) : InvalidDTMSettingsIdx; - mainObject.customProjectionIndex = (needsCustomProjection) ? acquireActiveCustomProjectionIndex_SubmitIfNeeded(intendedNextSubmit) : InvalidCustomProjectionIndex; - mainObject.customClipRectIndex = (needsCustomClipRect) ? acquireActiveCustomClipRectIndex_SubmitIfNeeded(intendedNextSubmit) : InvalidCustomClipRectIndex; - mainObject.transformationType = (uint32_t)activeMainObjectTransformationType; + + assert((needsLineStyle == !needsDTMSettings) || (needsLineStyle == false && needsDTMSettings == false)); + if (needsLineStyle) + { + mainObject.setStyleIdx(acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit)); + } + else if(needsDTMSettings) + { + mainObject.setDtmSettingsIdx(acquireActiveDTMSettingsIndex_SubmitIfNeeded(intendedNextSubmit)); + } + else + { + mainObject.setStyleIdx(MainObject::getInvalidStyleIndex()); + } + mainObject.customTransformationIndex = (needsCustomProjection) ? acquireActiveCustomProjectionIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomTransformationIndex(); + mainObject.setCustomClipRectIndex((needsCustomClipRect) ? acquireActiveCustomClipRectIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomClipRectIndex()); + mainObject.setTransformationType((uint32_t)activeMainObjectTransformationType); activeMainObjectIndex = resourcesCollection.mainObjects.addAndGetOffset(mainObject); return activeMainObjectIndex; } @@ -2287,14 +2299,14 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten uint32_t DrawResourcesFiller::addLineStyle_SubmitIfNeeded(const LineStyleInfo& lineStyle, SIntendedSubmitInfo& intendedNextSubmit) { uint32_t outLineStyleIdx = addLineStyle_Internal(lineStyle); - if (outLineStyleIdx == InvalidStyleIdx) + if (outLineStyleIdx == MainObject::getInvalidStyleIndex()) { // There wasn't enough resource memory remaining to fit a single LineStyle submitDraws(intendedNextSubmit); reset(); // resets everything! be careful! outLineStyleIdx = addLineStyle_Internal(lineStyle); - assert(outLineStyleIdx != InvalidStyleIdx); + assert(outLineStyleIdx != MainObject::getInvalidStyleIndex()); } return outLineStyleIdx; @@ -2304,14 +2316,14 @@ uint32_t DrawResourcesFiller::addDTMSettings_SubmitIfNeeded(const DTMSettingsInf { // before calling `addDTMSettings_Internal` we have made sute we have enough mem for uint32_t outDTMSettingIdx = addDTMSettings_Internal(dtmSettings, intendedNextSubmit); - if (outDTMSettingIdx == InvalidDTMSettingsIdx) + if (outDTMSettingIdx == MainObject::getInvalidDtmSettingsIndex()) { // There wasn't enough resource memory remaining to fit dtmsettings struct + 2 linestyles structs. submitDraws(intendedNextSubmit); reset(); // resets everything! be careful! outDTMSettingIdx = addDTMSettings_Internal(dtmSettings, intendedNextSubmit); - assert(outDTMSettingIdx != InvalidDTMSettingsIdx); + assert(outDTMSettingIdx != MainObject::getInvalidDtmSettingsIndex()); } return outDTMSettingIdx; } diff --git a/62_CAD/DrawResourcesFiller.h b/62_CAD/DrawResourcesFiller.h index 2a83a1946..af4f3d4ea 100644 --- a/62_CAD/DrawResourcesFiller.h +++ b/62_CAD/DrawResourcesFiller.h @@ -30,7 +30,7 @@ using namespace nbl::core; using namespace nbl::asset; static_assert(sizeof(DrawObject) == 8u); -static_assert(sizeof(MainObject) == 20u); +static_assert(sizeof(MainObject) == 8u); static_assert(sizeof(LineStyle) == 88u); // ! DrawResourcesFiller @@ -859,7 +859,7 @@ struct DrawResourcesFiller // Invalidate all the clip projection addresses because activeProjections buffer got reset for (auto& addr : activeProjectionIndices) - addr = InvalidCustomProjectionIndex; + addr = MainObject::getInvalidCustomTransformationIndex(); } void resetCustomClipRects() @@ -868,19 +868,19 @@ struct DrawResourcesFiller // Invalidate all the clip projection addresses because activeProjections buffer got reset for (auto& addr : activeClipRectIndices) - addr = InvalidCustomClipRectIndex; + addr = MainObject::getInvalidCustomClipRectIndex(); } void resetLineStyles() { resourcesCollection.lineStyles.vector.clear(); - activeLineStyleIndex = InvalidStyleIdx; + activeLineStyleIndex = MainObject::getInvalidStyleIndex(); } void resetDTMSettings() { resourcesCollection.dtmSettings.vector.clear(); - activeDTMSettingsIndex = InvalidDTMSettingsIdx; + activeDTMSettingsIndex = MainObject::getInvalidDtmSettingsIndex(); } // MSDF Hashing and Caching Internal Functions @@ -991,10 +991,10 @@ struct DrawResourcesFiller // Active Resources we need to keep track of and push to resources buffer if needed. LineStyleInfo activeLineStyle; - uint32_t activeLineStyleIndex = InvalidStyleIdx; + uint32_t activeLineStyleIndex = MainObject::getInvalidStyleIndex(); DTMSettingsInfo activeDTMSettings; - uint32_t activeDTMSettingsIndex = InvalidDTMSettingsIdx; + uint32_t activeDTMSettingsIndex = MainObject::getInvalidDtmSettingsIndex(); MainObjectType activeMainObjectType; TransformationType activeMainObjectTransformationType; diff --git a/62_CAD/main.cpp b/62_CAD/main.cpp index 78cc0bbb2..adf31874c 100644 --- a/62_CAD/main.cpp +++ b/62_CAD/main.cpp @@ -3843,7 +3843,6 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio 0.0, 0.0, 1.0 }; - transformation = nbl::hlsl::mul(rotateMat, translateMat); transformation = nbl::hlsl::mul(rotateMat, nbl::hlsl::mul(translateMat, scaleMat)); diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index 915b6eed5..66d3f0593 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -151,11 +151,29 @@ enum TransformationType // [TODO]: pack indices and members of mainObject and DrawObject + enforce max size for autosubmit --> but do it only after the mainobject definition is finalized in gpu-driven rendering work struct MainObject { - uint32_t styleIdx; - uint32_t dtmSettingsIdx; - uint32_t customProjectionIndex; - uint32_t customClipRectIndex; - uint32_t transformationType; // todo pack later, it's just 2 possible values atm + uint32_t packedData; + uint32_t customTransformationIndex; // needs at least 24 bits + + using StyleIdxOrDtmSettingsIdxField = utils::BitField; // 65,536 distinct lineStyles or dtmSettings is more than enough for an n4ce frame, but make sure auto submit in drawresources filler plays nice and doesn't exceed this value + using CustomClipRectIndexField = utils::BitField; // these are associated with the number of clipping rects or dwgs one could have in a frame. from experience they'll always be less than 10, 32,768 is more than enough + using TransformationTypeField = utils::BitField; // todo pack later, it's just 2 possible values atm + + uint32_t getStyleIndex() { return StyleIdxOrDtmSettingsIdxField::get(packedData); } + void setStyleIdx(uint32_t styleIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, styleIdx); } + + uint32_t getDtmSettingsIndex() { return StyleIdxOrDtmSettingsIdxField::get(packedData); } + void setDtmSettingsIdx(uint32_t dtmSettingsIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, dtmSettingsIdx); } + + uint32_t getCustomClipRectIndex() { return CustomClipRectIndexField::get(packedData); } + void setCustomClipRectIndex(uint32_t customClipRectIndexField) { packedData = CustomClipRectIndexField::set(packedData, customClipRectIndexField); } + + uint32_t getTransformationType() { return TransformationTypeField::get(packedData); } + void setTransformationType(uint32_t transformationTypeField) { packedData = TransformationTypeField::set(packedData, transformationTypeField); } + + static uint32_t getInvalidStyleIndex() { return nbl::hlsl::numeric_limits::max & 0xFFFF; } + static uint32_t getInvalidDtmSettingsIndex() { return getInvalidStyleIndex(); } + static uint32_t getInvalidCustomClipRectIndex() { return nbl::hlsl::numeric_limits::max & 0x7FFF; } + static uint32_t getInvalidCustomTransformationIndex() { return nbl::hlsl::numeric_limits::max; } }; struct DrawObject @@ -563,11 +581,7 @@ NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t ImagesBindingArraySize = 128; NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t MainObjectIdxBits = 24u; // It will be packed next to alpha in a texture NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t AlphaBits = 32u - MainObjectIdxBits; NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t MaxIndexableMainObjects = (1u << MainObjectIdxBits) - 1u; -NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidStyleIdx = nbl::hlsl::numeric_limits::max; -NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidDTMSettingsIdx = nbl::hlsl::numeric_limits::max; NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidMainObjectIdx = MaxIndexableMainObjects; -NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidCustomProjectionIndex = nbl::hlsl::numeric_limits::max; -NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidCustomClipRectIndex = nbl::hlsl::numeric_limits::max; NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidTextureIndex = nbl::hlsl::numeric_limits::max; // Hatches diff --git a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl index d4222d229..a3a38790a 100644 --- a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl @@ -83,7 +83,7 @@ template<> float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlpha, const uint32_t currentMainObjectIdx, float3 localTextureColor, bool colorFromTexture) { float32_t4 color; - uint32_t styleIdx = loadMainObject(currentMainObjectIdx).styleIdx; + uint32_t styleIdx = loadMainObject(currentMainObjectIdx).getStyleIndex(); if (!colorFromTexture) { color = loadLineStyle(styleIdx).color; @@ -109,14 +109,14 @@ float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlp // if geomID has changed, we resolve the SDF alpha (draw using blend), else accumulate const bool differentMainObject = currentMainObjectIdx != storedMainObjectIdx; // meaning current pixel's main object is different than what is already stored const bool resolve = differentMainObject && storedMainObjectIdx != InvalidMainObjectIdx; - uint32_t toResolveStyleIdx = InvalidStyleIdx; + uint32_t toResolveStyleIdx = MainObject::getInvalidStyleIndex(); // load from colorStorage only if we want to resolve color from texture instead of style // sampling from colorStorage needs to happen in critical section because another fragment may also want to store into it at the same time + need to happen before store if (resolve) { - toResolveStyleIdx = loadMainObject(storedMainObjectIdx).styleIdx; - if (toResolveStyleIdx == InvalidStyleIdx) // if style idx to resolve is invalid, then it means we should resolve from color + toResolveStyleIdx = loadMainObject(storedMainObjectIdx).getStyleIndex(); + if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); } @@ -136,7 +136,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlp // draw with previous geometry's style's color or stored in texture buffer :kek: // we don't need to load the style's color in critical section because we've already retrieved the style index from the stored main obj - if (toResolveStyleIdx != InvalidStyleIdx) // if toResolveStyleIdx is valid then that means our resolved color should come from line style + if (toResolveStyleIdx != MainObject::getInvalidStyleIndex()) // if toResolveStyleIdx is valid then that means our resolved color should come from line style { color = loadLineStyle(toResolveStyleIdx).color; gammaUncorrect(color.rgb); // want to output to SRGB without gamma correction @@ -170,7 +170,7 @@ float4 fragMain(PSInput input) : SV_TARGET if (pc.isDTMRendering) { - DTMSettings dtmSettings = loadDTMSettings(mainObj.dtmSettingsIdx); + DTMSettings dtmSettings = loadDTMSettings(mainObj.getDtmSettingsIndex()); float3 triangleVertices[3]; triangleVertices[0] = input.getScreenSpaceVertexAttribs(0); @@ -221,7 +221,7 @@ float4 fragMain(PSInput input) : SV_TARGET { const float2 start = input.getLineStart(); const float2 end = input.getLineEnd(); - const uint32_t styleIdx = mainObj.styleIdx; + const uint32_t styleIdx = mainObj.getStyleIndex(); const float phaseShift = input.getCurrentPhaseShift(); const float stretch = input.getPatternStretch(); @@ -245,7 +245,7 @@ float4 fragMain(PSInput input) : SV_TARGET nbl::hlsl::shapes::Quadratic quadratic = input.getQuadratic(); nbl::hlsl::shapes::Quadratic::ArcLengthCalculator arcLenCalc = input.getQuadraticArcLengthCalculator(); - const uint32_t styleIdx = mainObj.styleIdx; + const uint32_t styleIdx = mainObj.getStyleIndex(); const float phaseShift = input.getCurrentPhaseShift(); const float stretch = input.getPatternStretch(); @@ -387,7 +387,7 @@ float4 fragMain(PSInput input) : SV_TARGET localAlpha = 1.0f - smoothstep(0.0, globals.antiAliasingFactor, dist); } - LineStyle style = loadLineStyle(mainObj.styleIdx); + LineStyle style = loadLineStyle(mainObj.getStyleIndex()); uint32_t textureId = asuint(style.screenSpaceLineWidth); if (textureId != InvalidTextureIndex) { @@ -423,7 +423,7 @@ float4 fragMain(PSInput input) : SV_TARGET */ msdf *= exp2(max(mipLevel,0.0)); - LineStyle style = loadLineStyle(mainObj.styleIdx); + LineStyle style = loadLineStyle(mainObj.getStyleIndex()); const float screenPxRange = input.getFontGlyphPxRange() / MSDFPixelRangeHalf; const float bolden = style.worldSpaceLineWidth * screenPxRange; // worldSpaceLineWidth is actually boldenInPixels, aliased TextStyle with LineStyle localAlpha = 1.0f - smoothstep(-globals.antiAliasingFactor / 2.0f + bolden, globals.antiAliasingFactor / 2.0f + bolden, msdf); @@ -443,7 +443,7 @@ float4 fragMain(PSInput input) : SV_TARGET } else if (objType == ObjectType::GRID_DTM) { - DTMSettings dtmSettings = loadDTMSettings(mainObj.dtmSettingsIdx); + DTMSettings dtmSettings = loadDTMSettings(mainObj.getDtmSettingsIndex()); if (!dtmSettings.drawContourEnabled() && !dtmSettings.drawOutlineEnabled() && !dtmSettings.drawHeightShadingEnabled()) discard; diff --git a/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl index b30fe8431..5c1dbba74 100644 --- a/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl +++ b/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl @@ -19,7 +19,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord) nbl::hlsl::spirv::beginInvocationInterlockEXT(); bool resolve = false; - uint32_t toResolveStyleIdx = InvalidStyleIdx; + uint32_t toResolveStyleIdx = MainObject::getInvalidStyleIndex(); const uint32_t packedData = pseudoStencil[fragCoord]; const uint32_t storedQuantizedAlpha = nbl::hlsl::glsl::bitfieldExtract(packedData,0,AlphaBits); const uint32_t storedMainObjectIdx = nbl::hlsl::glsl::bitfieldExtract(packedData,AlphaBits,MainObjectIdxBits); @@ -38,8 +38,8 @@ float32_t4 calculateFinalColor(const uint2 fragCoord) // sampling from colorStorage needs to happen in critical section because another fragment may also want to store into it at the same time + need to happen before store if (resolve) { - toResolveStyleIdx = loadMainObject(storedMainObjectIdx).styleIdx; - if (toResolveStyleIdx == InvalidStyleIdx) // if style idx to resolve is invalid, then it means we should resolve from color + toResolveStyleIdx = loadMainObject(storedMainObjectIdx).getStyleIndex(); + if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); } } @@ -62,7 +62,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord) // draw with previous geometry's style's color or stored in texture buffer :kek: // we don't need to load the style's color in critical section because we've already retrieved the style index from the stored main obj - if (toResolveStyleIdx != InvalidStyleIdx) // if toResolveStyleIdx is valid then that means our resolved color should come from line style + if (toResolveStyleIdx != MainObject::getInvalidStyleIndex()) // if toResolveStyleIdx is valid then that means our resolved color should come from line style { color = loadLineStyle(toResolveStyleIdx).color; gammaUncorrect(color.rgb); // want to output to SRGB without gamma correction diff --git a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl index a9f3932cb..5019b3464 100644 --- a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl @@ -32,18 +32,18 @@ struct NDCClipProjectionData NDCClipProjectionData getClipProjectionData(in MainObject mainObj) { NDCClipProjectionData ret; - if (mainObj.customProjectionIndex != InvalidCustomProjectionIndex) + if (mainObj.customTransformationIndex != MainObject::getInvalidCustomTransformationIndex()) { // If projection type is worldspace projection and clip: - pfloat64_t3x3 customProjection = loadCustomProjection(mainObj.customProjectionIndex); + pfloat64_t3x3 customProjection = loadCustomProjection(mainObj.customTransformationIndex); ret.projectionToNDC = nbl::hlsl::mul(globals.defaultProjectionToNDC, customProjection); } else ret.projectionToNDC = globals.defaultProjectionToNDC; - if (mainObj.customClipRectIndex != InvalidCustomClipRectIndex) + if (mainObj.getCustomClipRectIndex() != MainObject::getInvalidCustomClipRectIndex()) { - WorldClipRect worldClipRect = loadCustomClipRect(mainObj.customClipRectIndex); + WorldClipRect worldClipRect = loadCustomClipRect(mainObj.getCustomClipRectIndex()); /// [NOTE]: Optimization: we avoid looking for min/max in the shader because minClip and maxClip in default worldspace are defined in such a way that minClip.y > maxClip.y so minClipNDC.y < maxClipNDC.y ret.minClipNDC = nbl::hlsl::_static_cast(transformPointNdc(globals.defaultProjectionToNDC, worldClipRect.minClip)); @@ -55,7 +55,7 @@ NDCClipProjectionData getClipProjectionData(in MainObject mainObj) ret.maxClipNDC = float2(+1.0f, +1.0f); } - if (mainObj.transformationType == TransformationType::TT_FIXED_SCREENSPACE_SIZE) + if (mainObj.getTransformationType() == TransformationType::TT_FIXED_SCREENSPACE_SIZE) ret.projectionToNDC = nbl::hlsl::mul(ret.projectionToNDC, globals.screenToWorldScaleTransform); return ret; @@ -208,11 +208,9 @@ PSInput vtxMain(uint vertexID : SV_VertexID) outV.setObjType(objType); outV.setMainObjectIdx(drawObj.getMainObjIndex()); - printf("offset: %u", drawObj.geometryAddress); - MainObject mainObj = loadMainObject(drawObj.getMainObjIndex()); clipProjectionData = getClipProjectionData(mainObj); - + float screenToWorldRatio = getScreenToWorldRatio(clipProjectionData.projectionToNDC, globals.resolution); float worldToScreenRatio = 1.0f / screenToWorldRatio; outV.setCurrentWorldToScreenRatio(worldToScreenRatio); @@ -220,7 +218,7 @@ PSInput vtxMain(uint vertexID : SV_VertexID) // We only need these for Outline type objects like lines and bezier curves if (objType == ObjectType::LINE || objType == ObjectType::QUAD_BEZIER || objType == ObjectType::POLYLINE_CONNECTOR) { - LineStyle lineStyle = loadLineStyle(mainObj.styleIdx); + LineStyle lineStyle = loadLineStyle(mainObj.getStyleIndex()); // Width is on both sides, thickness is one one side of the curve (div by 2.0f) const float screenSpaceLineWidth = lineStyle.screenSpaceLineWidth + lineStyle.worldSpaceLineWidth * screenToWorldRatio; @@ -599,7 +597,7 @@ PSInput vtxMain(uint vertexID : SV_VertexID) } else if (objType == ObjectType::FONT_GLYPH) { - LineStyle lineStyle = loadLineStyle(mainObj.styleIdx); + LineStyle lineStyle = loadLineStyle(mainObj.getStyleIndex()); const float italicTiltSlope = lineStyle.screenSpaceLineWidth; // aliased text style member with line style GlyphInfo glyphInfo; From 0d0d8687fc6ef6e19bfb5a06ae81d7033af5ff4b Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Tue, 26 May 2026 13:20:27 +0200 Subject: [PATCH 5/9] Optimized matrices --- 62_CAD/DrawResourcesFiller.cpp | 32 ++++++++++++++++---------------- 62_CAD/DrawResourcesFiller.h | 20 ++++++++++---------- 62_CAD/main.cpp | 7 +++---- 62_CAD/shaders/globals.hlsl | 24 +++++++++++++++++++----- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index cda1668fd..c81823014 100644 --- a/62_CAD/DrawResourcesFiller.cpp +++ b/62_CAD/DrawResourcesFiller.cpp @@ -228,7 +228,7 @@ void DrawResourcesFiller::drawPolyline(const CPolylineBase& polyline, const Line endMainObject(); } -void DrawResourcesFiller::drawFixedGeometryPolyline(const CPolylineBase& polyline, const LineStyleInfo& lineStyleInfo, const float64_t3x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit) +void DrawResourcesFiller::drawFixedGeometryPolyline(const CPolylineBase& polyline, const LineStyleInfo& lineStyleInfo, const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit) { if (!lineStyleInfo.isVisible()) return; @@ -397,7 +397,7 @@ void DrawResourcesFiller::drawFixedGeometryHatch( const float32_t4& foregroundColor, const float32_t4& backgroundColor, const HatchFillPattern fillPattern, - const float64_t3x3& transformation, + const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit) { @@ -413,7 +413,7 @@ void DrawResourcesFiller::drawFixedGeometryHatch( const Hatch& hatch, const float32_t4& color, const HatchFillPattern fillPattern, - const float64_t3x3& transformation, + const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit) { @@ -425,7 +425,7 @@ void DrawResourcesFiller::drawFixedGeometryHatch( void DrawResourcesFiller::drawFixedGeometryHatch( const Hatch& hatch, const float32_t4& color, - const float64_t3x3& transformation, + const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit) { @@ -1007,7 +1007,7 @@ void DrawResourcesFiller::drawGeoreferencedImage(image_id imageID, nbl::core::sm // Georefernced Image Data in the cache was already pre-transformed from local to main worldspace coordinates for tile calculation purposes // Because of this reason, the pre-transformed obb in the cache doesn't need to be transformed by custom projection again anymore. // we push the identity transform to prevent any more tranformation on the obb which is already in worldspace units. - float64_t3x3 identity = float64_t3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); + float64_t2x3 identity = float64_t2x3(1, 0, 0, 0, 1, 0); pushCustomProjection(identity); beginMainObject(MainObjectType::STREAMED_IMAGE); @@ -1407,7 +1407,7 @@ void DrawResourcesFiller::endMainObject() activeMainObjectIndex = InvalidMainObjectIdx; } -void DrawResourcesFiller::pushCustomProjection(const float64_t3x3& projection) +void DrawResourcesFiller::pushCustomProjection(const float64_t2x3& projection) { activeProjections.push_back(projection); activeProjectionIndices.push_back(MainObject::getInvalidCustomTransformationIndex()); @@ -2152,15 +2152,15 @@ uint32_t DrawResourcesFiller::addDTMSettings_Internal(const DTMSettingsInfo& dtm return resourcesCollection.dtmSettings.addAndGetOffset(dtmSettings); // this will implicitly increase total resource consumption and reduce remaining size --> no need for mem size trackers } -float64_t3x3 DrawResourcesFiller::getFixedGeometryFinalTransformationMatrix(const float64_t3x3& transformation, TransformationType transformationType) const +float64_t2x3 DrawResourcesFiller::getFixedGeometryFinalTransformationMatrix(const float64_t2x3& transformation, TransformationType transformationType) const { if (!activeProjections.empty()) { - float64_t3x3 newTransformation = nbl::hlsl::mul(activeProjections.back(), transformation); + float64_t3x3 newTransformation = nbl::hlsl::mul(hlsl::math::linalg::promote_affine<3,3,2,3>(activeProjections.back()), hlsl::math::linalg::promote_affine<3, 3, 2, 3>(transformation)); if (transformationType == TransformationType::TT_NORMAL) { - return newTransformation; + return float64_t2x3(newTransformation[0], newTransformation[1]); } else if (transformationType == TransformationType::TT_FIXED_SCREENSPACE_SIZE) { @@ -2183,12 +2183,12 @@ float64_t3x3 DrawResourcesFiller::getFixedGeometryFinalTransformationMatrix(cons newTransformation[0][1] = column1[0]; newTransformation[1][1] = column1[1]; - return newTransformation; + return float64_t2x3(newTransformation[0], newTransformation[1]); } else { // Fallback if transformationType is unrecognized, shouldn't happen - return newTransformation; + return float64_t2x3(newTransformation[0], newTransformation[1]); } } else @@ -2279,15 +2279,15 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten assert((needsLineStyle == !needsDTMSettings) || (needsLineStyle == false && needsDTMSettings == false)); if (needsLineStyle) { - mainObject.setStyleIdx(acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit)); + mainObject.setStyleIndex(acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit)); } else if(needsDTMSettings) { - mainObject.setDtmSettingsIdx(acquireActiveDTMSettingsIndex_SubmitIfNeeded(intendedNextSubmit)); + mainObject.setDtmSettingsIndex(acquireActiveDTMSettingsIndex_SubmitIfNeeded(intendedNextSubmit)); } else { - mainObject.setStyleIdx(MainObject::getInvalidStyleIndex()); + mainObject.setStyleIndex(MainObject::getInvalidStyleIndex()); // line style and dtm settings indices share the same memory, so no need to invalidate dtm settings here } mainObject.customTransformationIndex = (needsCustomProjection) ? acquireActiveCustomProjectionIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomTransformationIndex(); mainObject.setCustomClipRectIndex((needsCustomClipRect) ? acquireActiveCustomClipRectIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomClipRectIndex()); @@ -2328,10 +2328,10 @@ uint32_t DrawResourcesFiller::addDTMSettings_SubmitIfNeeded(const DTMSettingsInf return outDTMSettingIdx; } -uint32_t DrawResourcesFiller::addCustomProjection_SubmitIfNeeded(const float64_t3x3& projection, SIntendedSubmitInfo& intendedNextSubmit) +uint32_t DrawResourcesFiller::addCustomProjection_SubmitIfNeeded(const float64_t2x3& projection, SIntendedSubmitInfo& intendedNextSubmit) { const size_t remainingResourcesSize = calculateRemainingResourcesSize(); - const size_t memRequired = sizeof(float64_t3x3); + const size_t memRequired = sizeof(float64_t2x3); const bool enoughMem = remainingResourcesSize >= memRequired; // enough remaining memory for 1 more dtm settings with 2 referenced line styles? if (!enoughMem) diff --git a/62_CAD/DrawResourcesFiller.h b/62_CAD/DrawResourcesFiller.h index af4f3d4ea..07cebe3d9 100644 --- a/62_CAD/DrawResourcesFiller.h +++ b/62_CAD/DrawResourcesFiller.h @@ -109,7 +109,7 @@ struct DrawResourcesFiller // auto-submission level 0 resources (settings that mainObj references) CPUGeneratedResource lineStyles; CPUGeneratedResource dtmSettings; - CPUGeneratedResource customProjections; + CPUGeneratedResource customProjections; CPUGeneratedResource customClipRects; // auto-submission level 1 buffers (mainObj that drawObjs references, if all drawObjs+idxBuffer+geometryInfo doesn't fit into mem this will be broken down into many) @@ -229,7 +229,7 @@ struct DrawResourcesFiller //! Draws a fixed-geometry polyline using a custom transformation. //! TODO: Change `polyline` input to an ID referencing a possibly cached instance in our buffers, allowing reuse and avoiding redundant uploads. - void drawFixedGeometryPolyline(const CPolylineBase& polyline, const LineStyleInfo& lineStyleInfo, const float64_t3x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit); + void drawFixedGeometryPolyline(const CPolylineBase& polyline, const LineStyleInfo& lineStyleInfo, const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit); /// Use this in a begin/endMainObject scope when you want to draw different polylines that should essentially be a single main object (no self-blending between components of a single main object) /// WARNING: make sure this function is called within begin/endMainObject scope @@ -267,7 +267,7 @@ struct DrawResourcesFiller const float32_t4& foregroundColor, const float32_t4& backgroundColor, const HatchFillPattern fillPattern, - const float64_t3x3& transformation, + const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit); @@ -276,7 +276,7 @@ struct DrawResourcesFiller const Hatch& hatch, const float32_t4& color, const HatchFillPattern fillPattern, - const float64_t3x3& transformation, + const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit); @@ -284,7 +284,7 @@ struct DrawResourcesFiller void drawFixedGeometryHatch( const Hatch& hatch, const float32_t4& color, - const float64_t3x3& transformation, + const float64_t2x3& transformation, TransformationType transformationType, SIntendedSubmitInfo& intendedNextSubmit); @@ -490,13 +490,13 @@ struct DrawResourcesFiller void beginMainObject(MainObjectType type, TransformationType transformationType = TransformationType::TT_NORMAL); void endMainObject(); - void pushCustomProjection(const float64_t3x3& projection); + void pushCustomProjection(const float64_t2x3& projection); void popCustomProjection(); void pushCustomClipRect(const WorldClipRect& clipRect); void popCustomClipRect(); - const std::deque& getCustomProjectionStack() const { return activeProjections; } + const std::deque& getCustomProjectionStack() const { return activeProjections; } const std::deque& getCustomClipRectsStack() const { return activeClipRects; } smart_refctd_ptr getMSDFsTextureArray() { return msdfTextureArray; } @@ -719,7 +719,7 @@ struct DrawResourcesFiller uint32_t addDTMSettings_SubmitIfNeeded(const DTMSettingsInfo& dtmSettings, SIntendedSubmitInfo& intendedNextSubmit); /// Attempts to add custom projection to gpu resources. If it fails to do, due to resource limitations, auto-submits and tries again. - uint32_t addCustomProjection_SubmitIfNeeded(const float64_t3x3& projection, SIntendedSubmitInfo& intendedNextSubmit); + uint32_t addCustomProjection_SubmitIfNeeded(const float64_t2x3& projection, SIntendedSubmitInfo& intendedNextSubmit); /// Attempts to add custom clip to gpu resources. If it fails to do, due to resource limitations, auto-submits and tries again. uint32_t addCustomClipRect_SubmitIfNeeded(const WorldClipRect& clipRect, SIntendedSubmitInfo& intendedNextSubmit); @@ -748,7 +748,7 @@ struct DrawResourcesFiller * @param transformationType The type of transformation to apply (e.g., TT_NORMAL or TT_FIXED_SCREENSPACE_SIZE). * */ - float64_t3x3 getFixedGeometryFinalTransformationMatrix(const float64_t3x3& transformation, TransformationType transformationType) const; + float64_t2x3 getFixedGeometryFinalTransformationMatrix(const float64_t2x3& transformation, TransformationType transformationType) const; /// Attempts to upload as many draw objects as possible within the given polyline section considering resource limitations void addPolylineObjects_Internal(const CPolylineBase& polyline, const CPolylineBase::SectionInfo& section, uint32_t& currentObjectInSection, uint32_t mainObjIdx); @@ -1002,7 +1002,7 @@ struct DrawResourcesFiller uint32_t activeMainObjectIndex = InvalidMainObjectIdx; // The ClipRects & Projections are stack, because user can push/pop ClipRects & Projections in any order - std::deque activeProjections; // stack of projections stored so we can resubmit them if geometry buffer got reset. + std::deque activeProjections; // stack of projections stored so we can resubmit them if geometry buffer got reset. std::deque activeProjectionIndices; // stack of projection gpu addresses in geometry buffer. to keep track of them in push/pops std::deque activeClipRects; // stack of clips stored so we can resubmit them if geometry buffer got reset. diff --git a/62_CAD/main.cpp b/62_CAD/main.cpp index adf31874c..e8dce8af9 100644 --- a/62_CAD/main.cpp +++ b/62_CAD/main.cpp @@ -3290,10 +3290,9 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio } else if (mode == ExampleMode::CASE_6) { - float64_t3x3 customProjection = float64_t3x3{ + float64_t2x3 customProjection = float64_t2x3{ 1.0, 0.0, cos(m_timeElapsed * 0.0005) * 100.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0 + 0.0, 1.0, 0.0 }; /// [NOTE]: We set minClip and maxClip (in default worldspace) in such a way that minClip.y > maxClip.y so that minClipNDC.y < maxClipNDC.y @@ -3847,7 +3846,7 @@ class ComputerAidedDesign final : public nbl::examples::SimpleWindowedApplicatio transformation = nbl::hlsl::mul(rotateMat, nbl::hlsl::mul(translateMat, scaleMat)); - drawResourcesFiller.drawFixedGeometryPolyline(polyline, style, transformation, TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); + drawResourcesFiller.drawFixedGeometryPolyline(polyline, style, float64_t2x3(transformation[0], transformation[1]), TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); } } } diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index 66d3f0593..0640a273b 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef __HLSL_VERSION #include @@ -29,6 +30,7 @@ using pfloat64_t2 = nbl::hlsl::vector; using pfloat64_t3 = nbl::hlsl::vector; #endif +using pfloat64_t2x3 = portable_matrix_t2x3; using pfloat64_t3x3 = portable_matrix_t3x3; struct PushConstants @@ -159,10 +161,10 @@ struct MainObject using TransformationTypeField = utils::BitField; // todo pack later, it's just 2 possible values atm uint32_t getStyleIndex() { return StyleIdxOrDtmSettingsIdxField::get(packedData); } - void setStyleIdx(uint32_t styleIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, styleIdx); } + void setStyleIndex(uint32_t styleIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, styleIdx); } uint32_t getDtmSettingsIndex() { return StyleIdxOrDtmSettingsIdxField::get(packedData); } - void setDtmSettingsIdx(uint32_t dtmSettingsIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, dtmSettingsIdx); } + void setDtmSettingsIndex(uint32_t dtmSettingsIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, dtmSettingsIdx); } uint32_t getCustomClipRectIndex() { return CustomClipRectIndexField::get(packedData); } void setCustomClipRectIndex(uint32_t customClipRectIndexField) { packedData = CustomClipRectIndexField::set(packedData, customClipRectIndexField); } @@ -170,9 +172,9 @@ struct MainObject uint32_t getTransformationType() { return TransformationTypeField::get(packedData); } void setTransformationType(uint32_t transformationTypeField) { packedData = TransformationTypeField::set(packedData, transformationTypeField); } - static uint32_t getInvalidStyleIndex() { return nbl::hlsl::numeric_limits::max & 0xFFFF; } + static uint32_t getInvalidStyleIndex() { return 0xFFFF; } static uint32_t getInvalidDtmSettingsIndex() { return getInvalidStyleIndex(); } - static uint32_t getInvalidCustomClipRectIndex() { return nbl::hlsl::numeric_limits::max & 0x7FFF; } + static uint32_t getInvalidCustomClipRectIndex() { return 0x7FFF; } static uint32_t getInvalidCustomTransformationIndex() { return nbl::hlsl::numeric_limits::max; } }; @@ -633,7 +635,19 @@ DTMSettings loadDTMSettings(const uint32_t index) } pfloat64_t3x3 loadCustomProjection(const uint32_t index) { - return vk::RawBufferLoad(globals.pointers.customProjections + index * sizeof(pfloat64_t3x3), 8u); + pfloat64_t2x3 matrix2x3 = vk::RawBufferLoad(globals.pointers.customProjections + index * sizeof(pfloat64_t2x3), 8u); + + pfloat64_t3x3 output; + output.rows[0].setComponent(0, matrix2x3.rows[0].getComponent(0)); + output.rows[0].setComponent(1, matrix2x3.rows[0].getComponent(1)); + output.rows[0].setComponent(2, matrix2x3.rows[0].getComponent(2)); + output.rows[1].setComponent(0, matrix2x3.rows[1].getComponent(0)); + output.rows[1].setComponent(1, matrix2x3.rows[1].getComponent(1)); + output.rows[1].setComponent(2, matrix2x3.rows[1].getComponent(2)); + output.rows[2].setComponent(0, nbl::hlsl::_static_cast(0.0)); + output.rows[2].setComponent(1, nbl::hlsl::_static_cast(0.0)); + output.rows[2].setComponent(2, nbl::hlsl::_static_cast(1.0)); + return output; } WorldClipRect loadCustomClipRect(const uint32_t index) { From 1e54aa855a7c053e644628ab4aef7140fa45ce95 Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Wed, 27 May 2026 21:37:10 +0200 Subject: [PATCH 6/9] Added DTM settings flag to the `MainObject` struct --- 62_CAD/DrawResourcesFiller.cpp | 3 +++ 62_CAD/shaders/globals.hlsl | 23 +++++++++++++++---- .../main_pipeline/fragment_shader.hlsl | 14 ++++++++--- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index c81823014..990899c04 100644 --- a/62_CAD/DrawResourcesFiller.cpp +++ b/62_CAD/DrawResourcesFiller.cpp @@ -2280,14 +2280,17 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten if (needsLineStyle) { mainObject.setStyleIndex(acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit)); + mainObject.setDtmSettingsFlag(false); } else if(needsDTMSettings) { mainObject.setDtmSettingsIndex(acquireActiveDTMSettingsIndex_SubmitIfNeeded(intendedNextSubmit)); + mainObject.setDtmSettingsFlag(true); } else { mainObject.setStyleIndex(MainObject::getInvalidStyleIndex()); // line style and dtm settings indices share the same memory, so no need to invalidate dtm settings here + mainObject.setDtmSettingsFlag(false); } mainObject.customTransformationIndex = (needsCustomProjection) ? acquireActiveCustomProjectionIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomTransformationIndex(); mainObject.setCustomClipRectIndex((needsCustomClipRect) ? acquireActiveCustomClipRectIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomClipRectIndex()); diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index 0640a273b..9a7b18b2c 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -147,6 +147,17 @@ enum TransformationType TT_FIXED_SCREENSPACE_SIZE }; +template +struct IndexLimits +{ + // The universal invalid marker (all 1s for the given bit width) + NBL_CONSTEXPR_STATIC T Invalid = (Bits >= sizeof(T) * 8) + ? ~T(0) + : (T(1) << Bits) - T(1); + + // The highest valid index is one less than the invalid marker + NBL_CONSTEXPR_STATIC T MaxIndexable = Invalid - T(1); +}; // Consists of multiple DrawObjects // [IDEA]: In GPU-driven rendering, to save mem for MainObject data fetching: many of these can be shared amongst different main objects, we could find these styles, settings, etc indices with upper_bound @@ -157,8 +168,9 @@ struct MainObject uint32_t customTransformationIndex; // needs at least 24 bits using StyleIdxOrDtmSettingsIdxField = utils::BitField; // 65,536 distinct lineStyles or dtmSettings is more than enough for an n4ce frame, but make sure auto submit in drawresources filler plays nice and doesn't exceed this value - using CustomClipRectIndexField = utils::BitField; // these are associated with the number of clipping rects or dwgs one could have in a frame. from experience they'll always be less than 10, 32,768 is more than enough - using TransformationTypeField = utils::BitField; // todo pack later, it's just 2 possible values atm + using CustomClipRectIndexField = utils::BitField; // these are associated with the number of clipping rects or dwgs one could have in a frame. from experience they'll always be less than 10, 32,768 is more than enough + using TransformationTypeField = utils::BitField; // todo pack later, it's just 2 possible values atm + using UseDtmSettingsField = utils::BitField; // this bit indicates if MainObject uses DTM settings uint32_t getStyleIndex() { return StyleIdxOrDtmSettingsIdxField::get(packedData); } void setStyleIndex(uint32_t styleIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, styleIdx); } @@ -172,9 +184,12 @@ struct MainObject uint32_t getTransformationType() { return TransformationTypeField::get(packedData); } void setTransformationType(uint32_t transformationTypeField) { packedData = TransformationTypeField::set(packedData, transformationTypeField); } - static uint32_t getInvalidStyleIndex() { return 0xFFFF; } + bool isUsingDtmSettings() { return (bool)UseDtmSettingsField::get(packedData); } + void setDtmSettingsFlag(bool isUsingDtmSettings) { packedData = UseDtmSettingsField::set(packedData, (uint32_t)isUsingDtmSettings); } + + static uint32_t getInvalidStyleIndex() { return IndexLimits::Invalid; } static uint32_t getInvalidDtmSettingsIndex() { return getInvalidStyleIndex(); } - static uint32_t getInvalidCustomClipRectIndex() { return 0x7FFF; } + static uint32_t getInvalidCustomClipRectIndex() { return IndexLimits::Invalid; } static uint32_t getInvalidCustomTransformationIndex() { return nbl::hlsl::numeric_limits::max; } }; diff --git a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl index a3a38790a..560bd361f 100644 --- a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl @@ -110,14 +110,22 @@ float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlp const bool differentMainObject = currentMainObjectIdx != storedMainObjectIdx; // meaning current pixel's main object is different than what is already stored const bool resolve = differentMainObject && storedMainObjectIdx != InvalidMainObjectIdx; uint32_t toResolveStyleIdx = MainObject::getInvalidStyleIndex(); - + MainObject mainObject = loadMainObject(storedMainObjectIdx); + // load from colorStorage only if we want to resolve color from texture instead of style // sampling from colorStorage needs to happen in critical section because another fragment may also want to store into it at the same time + need to happen before store if (resolve) { - toResolveStyleIdx = loadMainObject(storedMainObjectIdx).getStyleIndex(); - if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color + if(!mainObject.isUsingDtmSettings()) + { + toResolveStyleIdx = mainObject.getStyleIndex(); + if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color + color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); + } + else + { color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); + } } // If current localAlpha is higher than what is already stored in pseudoStencil we will update the value in pseudoStencil or the color in colorStorage, this is equivalent to programmable blending MAX operation. From 2b25aa34eee369dd8e9c9bc3688b8c6832c794a1 Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Fri, 29 May 2026 10:40:51 +0200 Subject: [PATCH 7/9] Fixed DTMs --- 62_CAD/shaders/main_pipeline/fragment_shader.hlsl | 8 +++++++- .../fragment_shader_resolve_alphas.hlsl | 12 ++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl index 560bd361f..cfdfd5a8e 100644 --- a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl @@ -83,9 +83,15 @@ template<> float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlpha, const uint32_t currentMainObjectIdx, float3 localTextureColor, bool colorFromTexture) { float32_t4 color; - uint32_t styleIdx = loadMainObject(currentMainObjectIdx).getStyleIndex(); + MainObject mainObject = loadMainObject(storedMainObjectIdx); + + // `colorFromTexture` is required when drawing DTMs + if (mainObject.isUsingDtmSettings()) + color = float4(localTextureColor, localAlpha); + if (!colorFromTexture) { + uint32_t styleIdx = loadMainObject(currentMainObjectIdx).getStyleIndex(); color = loadLineStyle(styleIdx).color; color.w *= localAlpha; } diff --git a/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl index 5c1dbba74..5a04c6c54 100644 --- a/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl +++ b/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl @@ -38,9 +38,17 @@ float32_t4 calculateFinalColor(const uint2 fragCoord) // sampling from colorStorage needs to happen in critical section because another fragment may also want to store into it at the same time + need to happen before store if (resolve) { - toResolveStyleIdx = loadMainObject(storedMainObjectIdx).getStyleIndex(); - if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color + MainObject mainObject = loadMainObject(storedMainObjectIdx); + if(!mainObject.isUsingDtmSettings()) + { + toResolveStyleIdx = mainObject.getStyleIndex(); + if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color + color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); + } + else + { color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); + } } } else if (globals.currentlyActiveMainObjectIndex != InvalidMainObjectIdx) From 7c8ac8a0736ddf38d7f9669811bbfcf269979fb5 Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Fri, 29 May 2026 10:56:16 +0200 Subject: [PATCH 8/9] Refactor --- 62_CAD/DrawResourcesFiller.cpp | 14 ++++++------- 62_CAD/DrawResourcesFiller.h | 4 ++-- 62_CAD/shaders/globals.hlsl | 14 ++++++------- .../main_pipeline/fragment_shader.hlsl | 20 +++++++++---------- .../fragment_shader_resolve_alphas.hlsl | 8 ++++---- .../shaders/main_pipeline/vertex_shader.hlsl | 4 ++-- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index 990899c04..789911198 100644 --- a/62_CAD/DrawResourcesFiller.cpp +++ b/62_CAD/DrawResourcesFiller.cpp @@ -1384,7 +1384,7 @@ const DrawResourcesFiller::ResourcesCollection& DrawResourcesFiller::getResource void DrawResourcesFiller::setActiveLineStyle(const LineStyleInfo& lineStyle) { activeLineStyle = lineStyle; - activeLineStyleIndex = MainObject::getInvalidStyleIndex(); + activeLineStyleIndex = MainObject::getInvalidLineStyleIndex(); } void DrawResourcesFiller::setActiveDTMSettings(const DTMSettingsInfo& dtmSettingsInfo) @@ -2077,7 +2077,7 @@ uint32_t DrawResourcesFiller::addLineStyle_Internal(const LineStyleInfo& lineSty const size_t remainingResourcesSize = calculateRemainingResourcesSize(); const bool enoughMem = remainingResourcesSize >= sizeof(LineStyle); // enough remaining memory for 1 more linestyle? if (!enoughMem) - return MainObject::getInvalidStyleIndex(); + return MainObject::getInvalidLineStyleIndex(); // TODO: Maybe constraint by a max size? and return InvalidIdx if it would exceed LineStyle gpuLineStyle = lineStyleInfo.getAsGPUData(); @@ -2200,7 +2200,7 @@ float64_t2x3 DrawResourcesFiller::getFixedGeometryFinalTransformationMatrix(cons uint32_t DrawResourcesFiller::acquireActiveLineStyleIndex_SubmitIfNeeded(SIntendedSubmitInfo& intendedNextSubmit) { - if (activeLineStyleIndex == MainObject::getInvalidStyleIndex()) + if (activeLineStyleIndex == MainObject::getInvalidLineStyleIndex()) activeLineStyleIndex = addLineStyle_SubmitIfNeeded(activeLineStyle, intendedNextSubmit); return activeLineStyleIndex; @@ -2279,7 +2279,7 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten assert((needsLineStyle == !needsDTMSettings) || (needsLineStyle == false && needsDTMSettings == false)); if (needsLineStyle) { - mainObject.setStyleIndex(acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit)); + mainObject.setLineStyleIndex(acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit)); mainObject.setDtmSettingsFlag(false); } else if(needsDTMSettings) @@ -2289,7 +2289,7 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten } else { - mainObject.setStyleIndex(MainObject::getInvalidStyleIndex()); // line style and dtm settings indices share the same memory, so no need to invalidate dtm settings here + mainObject.setLineStyleIndex(MainObject::getInvalidLineStyleIndex()); // line style and dtm settings indices share the same memory, so no need to invalidate dtm settings here mainObject.setDtmSettingsFlag(false); } mainObject.customTransformationIndex = (needsCustomProjection) ? acquireActiveCustomProjectionIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomTransformationIndex(); @@ -2302,14 +2302,14 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten uint32_t DrawResourcesFiller::addLineStyle_SubmitIfNeeded(const LineStyleInfo& lineStyle, SIntendedSubmitInfo& intendedNextSubmit) { uint32_t outLineStyleIdx = addLineStyle_Internal(lineStyle); - if (outLineStyleIdx == MainObject::getInvalidStyleIndex()) + if (outLineStyleIdx == MainObject::getInvalidLineStyleIndex()) { // There wasn't enough resource memory remaining to fit a single LineStyle submitDraws(intendedNextSubmit); reset(); // resets everything! be careful! outLineStyleIdx = addLineStyle_Internal(lineStyle); - assert(outLineStyleIdx != MainObject::getInvalidStyleIndex()); + assert(outLineStyleIdx != MainObject::getInvalidLineStyleIndex()); } return outLineStyleIdx; diff --git a/62_CAD/DrawResourcesFiller.h b/62_CAD/DrawResourcesFiller.h index 07cebe3d9..655161dbd 100644 --- a/62_CAD/DrawResourcesFiller.h +++ b/62_CAD/DrawResourcesFiller.h @@ -874,7 +874,7 @@ struct DrawResourcesFiller void resetLineStyles() { resourcesCollection.lineStyles.vector.clear(); - activeLineStyleIndex = MainObject::getInvalidStyleIndex(); + activeLineStyleIndex = MainObject::getInvalidLineStyleIndex(); } void resetDTMSettings() @@ -991,7 +991,7 @@ struct DrawResourcesFiller // Active Resources we need to keep track of and push to resources buffer if needed. LineStyleInfo activeLineStyle; - uint32_t activeLineStyleIndex = MainObject::getInvalidStyleIndex(); + uint32_t activeLineStyleIndex = MainObject::getInvalidLineStyleIndex(); DTMSettingsInfo activeDTMSettings; uint32_t activeDTMSettingsIndex = MainObject::getInvalidDtmSettingsIndex(); diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index 9a7b18b2c..4005b3767 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -167,16 +167,16 @@ struct MainObject uint32_t packedData; uint32_t customTransformationIndex; // needs at least 24 bits - using StyleIdxOrDtmSettingsIdxField = utils::BitField; // 65,536 distinct lineStyles or dtmSettings is more than enough for an n4ce frame, but make sure auto submit in drawresources filler plays nice and doesn't exceed this value + using LineStyleIdxOrDtmSettingsIdxField = utils::BitField; // 65,536 distinct lineStyles or dtmSettings is more than enough for an n4ce frame, but make sure auto submit in drawresources filler plays nice and doesn't exceed this value using CustomClipRectIndexField = utils::BitField; // these are associated with the number of clipping rects or dwgs one could have in a frame. from experience they'll always be less than 10, 32,768 is more than enough using TransformationTypeField = utils::BitField; // todo pack later, it's just 2 possible values atm using UseDtmSettingsField = utils::BitField; // this bit indicates if MainObject uses DTM settings - uint32_t getStyleIndex() { return StyleIdxOrDtmSettingsIdxField::get(packedData); } - void setStyleIndex(uint32_t styleIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, styleIdx); } + uint32_t getLineStyleIndex() { return LineStyleIdxOrDtmSettingsIdxField::get(packedData); } + void setLineStyleIndex(uint32_t styleIdx) { packedData = LineStyleIdxOrDtmSettingsIdxField::set(packedData, styleIdx); } - uint32_t getDtmSettingsIndex() { return StyleIdxOrDtmSettingsIdxField::get(packedData); } - void setDtmSettingsIndex(uint32_t dtmSettingsIdx) { packedData = StyleIdxOrDtmSettingsIdxField::set(packedData, dtmSettingsIdx); } + uint32_t getDtmSettingsIndex() { return LineStyleIdxOrDtmSettingsIdxField::get(packedData); } + void setDtmSettingsIndex(uint32_t dtmSettingsIdx) { packedData = LineStyleIdxOrDtmSettingsIdxField::set(packedData, dtmSettingsIdx); } uint32_t getCustomClipRectIndex() { return CustomClipRectIndexField::get(packedData); } void setCustomClipRectIndex(uint32_t customClipRectIndexField) { packedData = CustomClipRectIndexField::set(packedData, customClipRectIndexField); } @@ -187,8 +187,8 @@ struct MainObject bool isUsingDtmSettings() { return (bool)UseDtmSettingsField::get(packedData); } void setDtmSettingsFlag(bool isUsingDtmSettings) { packedData = UseDtmSettingsField::set(packedData, (uint32_t)isUsingDtmSettings); } - static uint32_t getInvalidStyleIndex() { return IndexLimits::Invalid; } - static uint32_t getInvalidDtmSettingsIndex() { return getInvalidStyleIndex(); } + static uint32_t getInvalidLineStyleIndex() { return IndexLimits::Invalid; } + static uint32_t getInvalidDtmSettingsIndex() { return getInvalidLineStyleIndex(); } static uint32_t getInvalidCustomClipRectIndex() { return IndexLimits::Invalid; } static uint32_t getInvalidCustomTransformationIndex() { return nbl::hlsl::numeric_limits::max; } }; diff --git a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl index cfdfd5a8e..68514d136 100644 --- a/62_CAD/shaders/main_pipeline/fragment_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl @@ -83,7 +83,7 @@ template<> float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlpha, const uint32_t currentMainObjectIdx, float3 localTextureColor, bool colorFromTexture) { float32_t4 color; - MainObject mainObject = loadMainObject(storedMainObjectIdx); + MainObject mainObject = loadMainObject(currentMainObjectIdx); // `colorFromTexture` is required when drawing DTMs if (mainObject.isUsingDtmSettings()) @@ -91,7 +91,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAl if (!colorFromTexture) { - uint32_t styleIdx = loadMainObject(currentMainObjectIdx).getStyleIndex(); + uint32_t styleIdx = mainObject.getLineStyleIndex(); color = loadLineStyle(styleIdx).color; color.w *= localAlpha; } @@ -115,7 +115,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlp // if geomID has changed, we resolve the SDF alpha (draw using blend), else accumulate const bool differentMainObject = currentMainObjectIdx != storedMainObjectIdx; // meaning current pixel's main object is different than what is already stored const bool resolve = differentMainObject && storedMainObjectIdx != InvalidMainObjectIdx; - uint32_t toResolveStyleIdx = MainObject::getInvalidStyleIndex(); + uint32_t toResolveStyleIdx = MainObject::getInvalidLineStyleIndex(); MainObject mainObject = loadMainObject(storedMainObjectIdx); // load from colorStorage only if we want to resolve color from texture instead of style @@ -124,8 +124,8 @@ float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlp { if(!mainObject.isUsingDtmSettings()) { - toResolveStyleIdx = mainObject.getStyleIndex(); - if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color + toResolveStyleIdx = mainObject.getLineStyleIndex(); + if (toResolveStyleIdx == MainObject::getInvalidLineStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); } else @@ -150,7 +150,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord, const float localAlp // draw with previous geometry's style's color or stored in texture buffer :kek: // we don't need to load the style's color in critical section because we've already retrieved the style index from the stored main obj - if (toResolveStyleIdx != MainObject::getInvalidStyleIndex()) // if toResolveStyleIdx is valid then that means our resolved color should come from line style + if (toResolveStyleIdx != MainObject::getInvalidLineStyleIndex()) // if toResolveStyleIdx is valid then that means our resolved color should come from line style { color = loadLineStyle(toResolveStyleIdx).color; gammaUncorrect(color.rgb); // want to output to SRGB without gamma correction @@ -235,7 +235,7 @@ float4 fragMain(PSInput input) : SV_TARGET { const float2 start = input.getLineStart(); const float2 end = input.getLineEnd(); - const uint32_t styleIdx = mainObj.getStyleIndex(); + const uint32_t styleIdx = mainObj.getLineStyleIndex(); const float phaseShift = input.getCurrentPhaseShift(); const float stretch = input.getPatternStretch(); @@ -259,7 +259,7 @@ float4 fragMain(PSInput input) : SV_TARGET nbl::hlsl::shapes::Quadratic quadratic = input.getQuadratic(); nbl::hlsl::shapes::Quadratic::ArcLengthCalculator arcLenCalc = input.getQuadraticArcLengthCalculator(); - const uint32_t styleIdx = mainObj.getStyleIndex(); + const uint32_t styleIdx = mainObj.getLineStyleIndex(); const float phaseShift = input.getCurrentPhaseShift(); const float stretch = input.getPatternStretch(); @@ -401,7 +401,7 @@ float4 fragMain(PSInput input) : SV_TARGET localAlpha = 1.0f - smoothstep(0.0, globals.antiAliasingFactor, dist); } - LineStyle style = loadLineStyle(mainObj.getStyleIndex()); + LineStyle style = loadLineStyle(mainObj.getLineStyleIndex()); uint32_t textureId = asuint(style.screenSpaceLineWidth); if (textureId != InvalidTextureIndex) { @@ -437,7 +437,7 @@ float4 fragMain(PSInput input) : SV_TARGET */ msdf *= exp2(max(mipLevel,0.0)); - LineStyle style = loadLineStyle(mainObj.getStyleIndex()); + LineStyle style = loadLineStyle(mainObj.getLineStyleIndex()); const float screenPxRange = input.getFontGlyphPxRange() / MSDFPixelRangeHalf; const float bolden = style.worldSpaceLineWidth * screenPxRange; // worldSpaceLineWidth is actually boldenInPixels, aliased TextStyle with LineStyle localAlpha = 1.0f - smoothstep(-globals.antiAliasingFactor / 2.0f + bolden, globals.antiAliasingFactor / 2.0f + bolden, msdf); diff --git a/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl index 5a04c6c54..d2d3eadb6 100644 --- a/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl +++ b/62_CAD/shaders/main_pipeline/fragment_shader_resolve_alphas.hlsl @@ -19,7 +19,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord) nbl::hlsl::spirv::beginInvocationInterlockEXT(); bool resolve = false; - uint32_t toResolveStyleIdx = MainObject::getInvalidStyleIndex(); + uint32_t toResolveStyleIdx = MainObject::getInvalidLineStyleIndex(); const uint32_t packedData = pseudoStencil[fragCoord]; const uint32_t storedQuantizedAlpha = nbl::hlsl::glsl::bitfieldExtract(packedData,0,AlphaBits); const uint32_t storedMainObjectIdx = nbl::hlsl::glsl::bitfieldExtract(packedData,AlphaBits,MainObjectIdxBits); @@ -41,8 +41,8 @@ float32_t4 calculateFinalColor(const uint2 fragCoord) MainObject mainObject = loadMainObject(storedMainObjectIdx); if(!mainObject.isUsingDtmSettings()) { - toResolveStyleIdx = mainObject.getStyleIndex(); - if (toResolveStyleIdx == MainObject::getInvalidStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color + toResolveStyleIdx = mainObject.getLineStyleIndex(); + if (toResolveStyleIdx == MainObject::getInvalidLineStyleIndex()) // if style idx to resolve is invalid, then it means we should resolve from color color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); } else @@ -70,7 +70,7 @@ float32_t4 calculateFinalColor(const uint2 fragCoord) // draw with previous geometry's style's color or stored in texture buffer :kek: // we don't need to load the style's color in critical section because we've already retrieved the style index from the stored main obj - if (toResolveStyleIdx != MainObject::getInvalidStyleIndex()) // if toResolveStyleIdx is valid then that means our resolved color should come from line style + if (toResolveStyleIdx != MainObject::getInvalidLineStyleIndex()) // if toResolveStyleIdx is valid then that means our resolved color should come from line style { color = loadLineStyle(toResolveStyleIdx).color; gammaUncorrect(color.rgb); // want to output to SRGB without gamma correction diff --git a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl index 5019b3464..6ab5598fa 100644 --- a/62_CAD/shaders/main_pipeline/vertex_shader.hlsl +++ b/62_CAD/shaders/main_pipeline/vertex_shader.hlsl @@ -218,7 +218,7 @@ PSInput vtxMain(uint vertexID : SV_VertexID) // We only need these for Outline type objects like lines and bezier curves if (objType == ObjectType::LINE || objType == ObjectType::QUAD_BEZIER || objType == ObjectType::POLYLINE_CONNECTOR) { - LineStyle lineStyle = loadLineStyle(mainObj.getStyleIndex()); + LineStyle lineStyle = loadLineStyle(mainObj.getLineStyleIndex()); // Width is on both sides, thickness is one one side of the curve (div by 2.0f) const float screenSpaceLineWidth = lineStyle.screenSpaceLineWidth + lineStyle.worldSpaceLineWidth * screenToWorldRatio; @@ -597,7 +597,7 @@ PSInput vtxMain(uint vertexID : SV_VertexID) } else if (objType == ObjectType::FONT_GLYPH) { - LineStyle lineStyle = loadLineStyle(mainObj.getStyleIndex()); + LineStyle lineStyle = loadLineStyle(mainObj.getLineStyleIndex()); const float italicTiltSlope = lineStyle.screenSpaceLineWidth; // aliased text style member with line style GlyphInfo glyphInfo; From 1897a45b63e660285b2dfe203e16023334229a76 Mon Sep 17 00:00:00 2001 From: Przemog1 Date: Fri, 29 May 2026 11:40:12 +0200 Subject: [PATCH 9/9] Added safety mechanism for indexing --- 62_CAD/DrawResourcesFiller.cpp | 14 +++++++++----- 62_CAD/shaders/globals.hlsl | 9 +++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index 789911198..56bfdd704 100644 --- a/62_CAD/DrawResourcesFiller.cpp +++ b/62_CAD/DrawResourcesFiller.cpp @@ -2076,7 +2076,8 @@ uint32_t DrawResourcesFiller::addLineStyle_Internal(const LineStyleInfo& lineSty { const size_t remainingResourcesSize = calculateRemainingResourcesSize(); const bool enoughMem = remainingResourcesSize >= sizeof(LineStyle); // enough remaining memory for 1 more linestyle? - if (!enoughMem) + const bool indexLimitExceeded = resourcesCollection.lineStyles.vector.size() > MainObject::getMaxIndexableLineStyles(); + if (!enoughMem || indexLimitExceeded) return MainObject::getInvalidLineStyleIndex(); // TODO: Maybe constraint by a max size? and return InvalidIdx if it would exceed @@ -2098,8 +2099,9 @@ uint32_t DrawResourcesFiller::addDTMSettings_Internal(const DTMSettingsInfo& dtm const size_t noOfLineStylesRequired = ((dtmSettingsInfo.mode & E_DTM_MODE::OUTLINE) ? 1u : 0u) + dtmSettingsInfo.contourSettingsCount; const size_t maxMemRequired = sizeof(DTMSettings) + noOfLineStylesRequired * sizeof(LineStyle); const bool enoughMem = remainingResourcesSize >= maxMemRequired; // enough remaining memory for 1 more dtm settings with 2 referenced line styles? + const bool indexLimitExceeded = resourcesCollection.dtmSettings.vector.size() > MainObject::getMaxIndexableDtmSettings(); - if (!enoughMem) + if (!enoughMem || indexLimitExceeded) return MainObject::getInvalidDtmSettingsIndex(); // TODO: Maybe constraint by a max size? and return InvalidIdx if it would exceed @@ -2263,7 +2265,7 @@ uint32_t DrawResourcesFiller::acquireActiveMainObjectIndex_SubmitIfNeeded(SInten if (needsCustomClipRect) memRequired += sizeof(WorldClipRect); const bool enoughMem = remainingResourcesSize >= memRequired; // enough remaining memory for 1 more dtm settings with 2 referenced line styles? - const bool needToOverflowSubmit = (!enoughMem) || (resourcesCollection.mainObjects.vector.size() >= MaxIndexableMainObjects); + const bool needToOverflowSubmit = (!enoughMem) || (resourcesCollection.mainObjects.vector.size() > MaxIndexableMainObjects); if (needToOverflowSubmit) { @@ -2336,8 +2338,9 @@ uint32_t DrawResourcesFiller::addCustomProjection_SubmitIfNeeded(const float64_t const size_t remainingResourcesSize = calculateRemainingResourcesSize(); const size_t memRequired = sizeof(float64_t2x3); const bool enoughMem = remainingResourcesSize >= memRequired; // enough remaining memory for 1 more dtm settings with 2 referenced line styles? + const bool indexLimitExceeded = resourcesCollection.customProjections.vector.size() > MainObject::getMaxIndexableCustomTransformations(); - if (!enoughMem) + if (!enoughMem || indexLimitExceeded) { submitDraws(intendedNextSubmit); reset(); // resets everything! be careful! @@ -2352,8 +2355,9 @@ uint32_t DrawResourcesFiller::addCustomClipRect_SubmitIfNeeded(const WorldClipRe const size_t remainingResourcesSize = calculateRemainingResourcesSize(); const size_t memRequired = sizeof(WorldClipRect); const bool enoughMem = remainingResourcesSize >= memRequired; // enough remaining memory for 1 more dtm settings with 2 referenced line styles? + const bool indexLimitExceeded = resourcesCollection.customClipRects.vector.size() > MainObject::getMaxIndexableCustomClipRects(); - if (!enoughMem) + if (!enoughMem || indexLimitExceeded) { submitDraws(intendedNextSubmit); reset(); // resets everything! be careful! diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index 4005b3767..0b37fc88d 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -191,6 +191,11 @@ struct MainObject static uint32_t getInvalidDtmSettingsIndex() { return getInvalidLineStyleIndex(); } static uint32_t getInvalidCustomClipRectIndex() { return IndexLimits::Invalid; } static uint32_t getInvalidCustomTransformationIndex() { return nbl::hlsl::numeric_limits::max; } + + static uint32_t getMaxIndexableLineStyles() { return IndexLimits::MaxIndexable; } + static uint32_t getMaxIndexableDtmSettings() { return getMaxIndexableLineStyles(); } + static uint32_t getMaxIndexableCustomClipRects() { return IndexLimits::MaxIndexable; } + static uint32_t getMaxIndexableCustomTransformations() { return nbl::hlsl::numeric_limits::max - 1u; } }; struct DrawObject @@ -597,8 +602,8 @@ inline bool operator==(const DTMSettings& lhs, const DTMSettings& rhs) NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t ImagesBindingArraySize = 128; NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t MainObjectIdxBits = 24u; // It will be packed next to alpha in a texture NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t AlphaBits = 32u - MainObjectIdxBits; -NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t MaxIndexableMainObjects = (1u << MainObjectIdxBits) - 1u; -NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidMainObjectIdx = MaxIndexableMainObjects; +NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t MaxIndexableMainObjects = IndexLimits::MaxIndexable; +NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidMainObjectIdx = IndexLimits::Invalid; NBL_CONSTEXPR_INLINE_NSPC_SCOPE_VAR uint32_t InvalidTextureIndex = nbl::hlsl::numeric_limits::max; // Hatches