diff --git a/62_CAD/DrawResourcesFiller.cpp b/62_CAD/DrawResourcesFiller.cpp index 97ae6621b..56bfdd704 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); @@ -1384,13 +1384,13 @@ const DrawResourcesFiller::ResourcesCollection& DrawResourcesFiller::getResource void DrawResourcesFiller::setActiveLineStyle(const LineStyleInfo& lineStyle) { activeLineStyle = lineStyle; - activeLineStyleIndex = InvalidStyleIdx; + activeLineStyleIndex = MainObject::getInvalidLineStyleIndex(); } void DrawResourcesFiller::setActiveDTMSettings(const DTMSettingsInfo& dtmSettingsInfo) { activeDTMSettings = dtmSettingsInfo; - activeDTMSettingsIndex = InvalidDTMSettingsIdx; + activeDTMSettingsIndex = MainObject::getInvalidDtmSettingsIndex(); } void DrawResourcesFiller::beginMainObject(MainObjectType type, TransformationType transformationType) @@ -1407,10 +1407,10 @@ 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(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() @@ -2076,8 +2076,9 @@ 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; + 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 LineStyle gpuLineStyle = lineStyleInfo.getAsGPUData(); @@ -2098,9 +2099,10 @@ 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) - return InvalidDTMSettingsIdx; + if (!enoughMem || indexLimitExceeded) + return MainObject::getInvalidDtmSettingsIndex(); // TODO: Maybe constraint by a max size? and return InvalidIdx if it would exceed DTMSettings dtmSettings; @@ -2152,15 +2154,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 +2185,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 @@ -2200,7 +2202,7 @@ float64_t3x3 DrawResourcesFiller::getFixedGeometryFinalTransformationMatrix(cons uint32_t DrawResourcesFiller::acquireActiveLineStyleIndex_SubmitIfNeeded(SIntendedSubmitInfo& intendedNextSubmit) { - if (activeLineStyleIndex == InvalidStyleIdx) + if (activeLineStyleIndex == MainObject::getInvalidLineStyleIndex()) activeLineStyleIndex = addLineStyle_SubmitIfNeeded(activeLineStyle, intendedNextSubmit); return activeLineStyleIndex; @@ -2208,7 +2210,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 +2219,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 +2230,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(); @@ -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) { @@ -2275,11 +2277,26 @@ 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.setLineStyleIndex(acquireActiveLineStyleIndex_SubmitIfNeeded(intendedNextSubmit)); + mainObject.setDtmSettingsFlag(false); + } + else if(needsDTMSettings) + { + mainObject.setDtmSettingsIndex(acquireActiveDTMSettingsIndex_SubmitIfNeeded(intendedNextSubmit)); + mainObject.setDtmSettingsFlag(true); + } + else + { + 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(); + mainObject.setCustomClipRectIndex((needsCustomClipRect) ? acquireActiveCustomClipRectIndex_SubmitIfNeeded(intendedNextSubmit) : MainObject::getInvalidCustomClipRectIndex()); + mainObject.setTransformationType((uint32_t)activeMainObjectTransformationType); activeMainObjectIndex = resourcesCollection.mainObjects.addAndGetOffset(mainObject); return activeMainObjectIndex; } @@ -2287,14 +2304,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::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 != InvalidStyleIdx); + assert(outLineStyleIdx != MainObject::getInvalidLineStyleIndex()); } return outLineStyleIdx; @@ -2304,25 +2321,26 @@ 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; } -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? + const bool indexLimitExceeded = resourcesCollection.customProjections.vector.size() > MainObject::getMaxIndexableCustomTransformations(); - if (!enoughMem) + if (!enoughMem || indexLimitExceeded) { submitDraws(intendedNextSubmit); reset(); // resets everything! be careful! @@ -2337,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! @@ -2395,8 +2414,9 @@ void DrawResourcesFiller::addPolylineConnectors_Internal(const CPolylineBase& po // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::POLYLINE_CONNECTOR) | 0 << 16); + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::POLYLINE_CONNECTOR); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2451,8 +2471,9 @@ void DrawResourcesFiller::addLines_Internal(const CPolylineBase& polyline, const // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(objectsToUpload); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::LINE) | 0 << 16); + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::LINE); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2508,13 +2529,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++) { - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::QUAD_BEZIER) | (subObject << 16)); + assert(subObject < 4); // there can be maximum 4 subsections + drawObj.setType(ObjectType::QUAD_BEZIER); + drawObj.setSubsectionIdx(subObject); drawObjectsToBeFilled[i * CagesPerQuadBezier + subObject] = drawObj; } drawObj.geometryAddress += sizeof(QuadraticBezierInfo); @@ -2561,8 +2584,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_subsectionIdx = uint32_t(static_cast(ObjectType::CURVE_BOX) | (0 << 16)); + drawObj.setMainObjIndex(mainObjIndex); + drawObj.setType(ObjectType::CURVE_BOX); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; for (uint32_t i = 0u; i < objectsToUpload; ++i) { @@ -2603,8 +2627,9 @@ bool DrawResourcesFiller::addFontGlyph_Internal(const GlyphInfo& glyphInfo, uint // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::FONT_GLYPH) | (0 << 16)); + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::FONT_GLYPH); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2640,8 +2665,9 @@ bool DrawResourcesFiller::addGridDTM_Internal(const GridDTMInfo& gridDTMInfo, ui // Add DrawObjs DrawObject* drawObjectsToBeFilled = resourcesCollection.drawObjects.increaseCountAndGetPtr(1u); DrawObject drawObj = {}; - drawObj.mainObjIndex = mainObjIdx; - drawObj.type_subsectionIdx = uint32_t(static_cast(ObjectType::GRID_DTM) | (0 << 16)); + drawObj.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::GRID_DTM); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2677,8 +2703,9 @@ bool DrawResourcesFiller::addImageObject_Internal(const ImageObjectInfo& imageOb // Add DrawObjs 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.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::STATIC_IMAGE); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; @@ -2714,8 +2741,9 @@ bool DrawResourcesFiller::addGeoreferencedImageInfo_Internal(const Georeferenced // Add DrawObjs 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.setMainObjIndex(mainObjIdx); + drawObj.setType(ObjectType::STREAMED_IMAGE); + drawObj.setSubsectionIdx(0); drawObj.geometryAddress = geometryBufferOffset; drawObjectsToBeFilled[0u] = drawObj; diff --git a/62_CAD/DrawResourcesFiller.h b/62_CAD/DrawResourcesFiller.h index 3b0e0c4bb..655161dbd 100644 --- a/62_CAD/DrawResourcesFiller.h +++ b/62_CAD/DrawResourcesFiller.h @@ -29,8 +29,8 @@ using namespace nbl::video; using namespace nbl::core; using namespace nbl::asset; -static_assert(sizeof(DrawObject) == 16u); -static_assert(sizeof(MainObject) == 20u); +static_assert(sizeof(DrawObject) == 8u); +static_assert(sizeof(MainObject) == 8u); static_assert(sizeof(LineStyle) == 88u); // ! DrawResourcesFiller @@ -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); @@ -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::getInvalidLineStyleIndex(); } 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::getInvalidLineStyleIndex(); DTMSettingsInfo activeDTMSettings; - uint32_t activeDTMSettingsIndex = InvalidDTMSettingsIdx; + uint32_t activeDTMSettingsIndex = MainObject::getInvalidDtmSettingsIndex(); MainObjectType activeMainObjectType; TransformationType activeMainObjectTransformationType; @@ -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 1a54531b8..e8dce8af9 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 { @@ -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 @@ -3752,7 +3751,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 +3808,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 +3820,34 @@ 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)) * static_cast(i) * 10.0; + 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, float64_t2x3(transformation[0], transformation[1]), TransformationType::TT_FIXED_SCREENSPACE_SIZE, intendedNextSubmit); + } } } else if (mode == ExampleMode::CASE_11) diff --git a/62_CAD/shaders/globals.hlsl b/62_CAD/shaders/globals.hlsl index 0d2c1190a..0b37fc88d 100644 --- a/62_CAD/shaders/globals.hlsl +++ b/62_CAD/shaders/globals.hlsl @@ -11,6 +11,8 @@ #include #include #include +#include +#include #ifdef __HLSL_VERSION #include @@ -28,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 @@ -144,24 +147,74 @@ 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 // [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 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 getLineStyleIndex() { return LineStyleIdxOrDtmSettingsIdxField::get(packedData); } + void setLineStyleIndex(uint32_t styleIdx) { packedData = LineStyleIdxOrDtmSettingsIdxField::set(packedData, styleIdx); } + + 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); } + + uint32_t getTransformationType() { return TransformationTypeField::get(packedData); } + void setTransformationType(uint32_t transformationTypeField) { packedData = TransformationTypeField::set(packedData, transformationTypeField); } + + bool isUsingDtmSettings() { return (bool)UseDtmSettingsField::get(packedData); } + void setDtmSettingsFlag(bool isUsingDtmSettings) { packedData = UseDtmSettingsField::set(packedData, (uint32_t)isUsingDtmSettings); } + + 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; } + + 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 { - uint32_t type_subsectionIdx; // packed two uint16 into uint32 - uint32_t mainObjIndex; - uint64_t geometryAddress; + 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 @@ -549,12 +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 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 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 @@ -606,7 +655,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) { @@ -618,7 +679,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 +687,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/fragment_shader.hlsl b/62_CAD/shaders/main_pipeline/fragment_shader.hlsl index d4222d229..68514d136 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).styleIdx; + MainObject mainObject = loadMainObject(currentMainObjectIdx); + + // `colorFromTexture` is required when drawing DTMs + if (mainObject.isUsingDtmSettings()) + color = float4(localTextureColor, localAlpha); + if (!colorFromTexture) { + uint32_t styleIdx = mainObject.getLineStyleIndex(); color = loadLineStyle(styleIdx).color; color.w *= localAlpha; } @@ -109,15 +115,23 @@ 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::getInvalidLineStyleIndex(); + 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).styleIdx; - if (toResolveStyleIdx == InvalidStyleIdx) // if style idx to resolve is invalid, then it means we should resolve from color + if(!mainObject.isUsingDtmSettings()) + { + 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 + { 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. @@ -136,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 != InvalidStyleIdx) // 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 @@ -170,7 +184,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 +235,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.getLineStyleIndex(); const float phaseShift = input.getCurrentPhaseShift(); const float stretch = input.getPatternStretch(); @@ -245,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.styleIdx; + const uint32_t styleIdx = mainObj.getLineStyleIndex(); const float phaseShift = input.getCurrentPhaseShift(); const float stretch = input.getPatternStretch(); @@ -387,7 +401,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.getLineStyleIndex()); uint32_t textureId = asuint(style.screenSpaceLineWidth); if (textureId != InvalidTextureIndex) { @@ -423,7 +437,7 @@ float4 fragMain(PSInput input) : SV_TARGET */ msdf *= exp2(max(mipLevel,0.0)); - LineStyle style = loadLineStyle(mainObj.styleIdx); + 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); @@ -443,7 +457,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..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 = InvalidStyleIdx; + 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); @@ -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).styleIdx; - if (toResolveStyleIdx == InvalidStyleIdx) // if style idx to resolve is invalid, then it means we should resolve from color + MainObject mainObject = loadMainObject(storedMainObjectIdx); + if(!mainObject.isUsingDtmSettings()) + { + 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 + { color = float32_t4(unpackR11G11B10_UNORM(colorStorage[fragCoord]), 1.0f); + } } } else if (globals.currentlyActiveMainObjectIndex != InvalidMainObjectIdx) @@ -62,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 != InvalidStyleIdx) // 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 45a308daa..6ab5598fa 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; @@ -203,14 +203,14 @@ 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.getType(); + uint32_t subsectionIdx = drawObj.getSubsectionIdx(); outV.setObjType(objType); - outV.setMainObjectIdx(drawObj.mainObjIndex); + outV.setMainObjectIdx(drawObj.getMainObjIndex()); - MainObject mainObj = loadMainObject(drawObj.mainObjIndex); + MainObject mainObj = loadMainObject(drawObj.getMainObjIndex()); clipProjectionData = getClipProjectionData(mainObj); - + float screenToWorldRatio = getScreenToWorldRatio(clipProjectionData.projectionToNDC, globals.resolution); float worldToScreenRatio = 1.0f / screenToWorldRatio; outV.setCurrentWorldToScreenRatio(worldToScreenRatio); @@ -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.styleIdx); + 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; @@ -230,11 +230,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 +270,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 +444,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 +510,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; @@ -597,14 +597,14 @@ PSInput vtxMain(uint vertexID : SV_VertexID) } else if (objType == ObjectType::FONT_GLYPH) { - LineStyle lineStyle = loadLineStyle(mainObj.styleIdx); + LineStyle lineStyle = loadLineStyle(mainObj.getLineStyleIndex()); 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 +652,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 +674,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 +740,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));