Skip to content

Commit dca423d

Browse files
committed
[62.CAD][UNTESTED] clipProjectionData in geometry buffer, cleanups and overflow fixes, renamed CPULineStyle to LineStyleInfo
1 parent 685a501 commit dca423d

File tree

8 files changed

+549
-547
lines changed

8 files changed

+549
-547
lines changed

62_CAD/DrawBuffers.cpp

Lines changed: 136 additions & 129 deletions
Large diffs are not rendered by default.

62_CAD/DrawBuffers.h

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ using namespace nbl::video;
77
using namespace nbl::core;
88
using namespace nbl::asset;
99

10+
static_assert(sizeof(DrawObject) == 16u);
11+
static_assert(sizeof(MainObject) == 16u);
12+
static_assert(sizeof(Globals) == 128u);
13+
static_assert(sizeof(LineStyle) == 96u);
14+
static_assert(sizeof(ClipProjectionData) == 88u);
15+
1016
template <typename BufferType>
1117
struct DrawBuffers
1218
{
@@ -15,7 +21,6 @@ struct DrawBuffers
1521
smart_refctd_ptr<BufferType> drawObjectsBuffer;
1622
smart_refctd_ptr<BufferType> geometryBuffer;
1723
smart_refctd_ptr<BufferType> lineStylesBuffer;
18-
smart_refctd_ptr<BufferType> customClipProjectionBuffer;
1924
};
2025

2126
// ! this is just a buffers filler with autosubmission features used for convenience to how you feed our CAD renderer
@@ -42,34 +47,34 @@ struct DrawBuffersFiller
4247

4348
void allocateGeometryBuffer(ILogicalDevice* logicalDevice, size_t size);
4449

45-
void allocateStylesBuffer(ILogicalDevice* logicalDevice, uint32_t stylesCount);
50+
void allocateStylesBuffer(ILogicalDevice* logicalDevice, uint32_t lineStylesCount);
4651

4752
void allocateCustomClipProjectionBuffer(ILogicalDevice* logicalDevice, uint32_t ClipProjectionDataCount);
4853

4954
//! this function fills buffers required for drawing a polyline and submits a draw through provided callback when there is not enough memory.
50-
void drawPolyline(
51-
const CPolylineBase& polyline,
52-
const CPULineStyle& cpuLineStyle,
53-
const uint32_t clipProjectionIdx,
54-
SIntendedSubmitInfo& intendedNextSubmit);
55+
void drawPolyline(const CPolylineBase& polyline, const LineStyleInfo& lineStyleInfo, SIntendedSubmitInfo& intendedNextSubmit);
5556

56-
void drawPolyline(
57-
const CPolylineBase& polyline,
58-
const uint32_t polylineMainObjIdx,
57+
void drawPolyline(const CPolylineBase& polyline, uint32_t polylineMainObjIdx, SIntendedSubmitInfo& intendedNextSubmit);
58+
59+
// !drawSolid
60+
void drawHatch(
61+
const Hatch& hatch,
62+
const float32_t4& foregroundColor,
63+
const float32_t4& backgroundColor,
64+
/* something that gets you the texture id */
5965
SIntendedSubmitInfo& intendedNextSubmit);
6066

6167
void drawHatch(
6268
const Hatch& hatch,
63-
// If more parameters from cpu line style are used here later, make a new HatchStyle & use that
64-
const float32_t4 color,
65-
const uint32_t clipProjectionIdx,
69+
const float32_t4& color,
70+
/* something that gets you the texture id */
6671
SIntendedSubmitInfo& intendedNextSubmit);
6772

6873
void finalizeAllCopiesToGPU(SIntendedSubmitInfo& intendedNextSubmit);
6974

7075
inline uint32_t getLineStyleCount() const { return currentLineStylesCount; }
7176

72-
inline uint32_t getDrawObjectCount() const { return currentDrawObjectCount; }
77+
inline uint32_t getDrawObjectCount() const { return currentDrawObjectCount; }
7378

7479
inline uint32_t getMainObjectCount() const { return currentMainObjectCount; }
7580

@@ -93,52 +98,52 @@ struct DrawBuffersFiller
9398
return sizeof(LineStyle) * currentLineStylesCount;
9499
}
95100

96-
inline size_t getCurrentCustomClipProjectionBufferSize() const
97-
{
98-
return sizeof(ClipProjectionData) * currentClipProjectionDataCount;
99-
}
100-
101101
void reset()
102102
{
103-
resetAllCounters();
103+
resetGeometryCounters();
104+
resetMainObjectCounters();
105+
resetLineStyleCounters();
104106
}
105107

106108
DrawBuffers<ICPUBuffer> cpuDrawBuffers;
107109
DrawBuffers<IGPUBuffer> gpuDrawBuffers;
108110

109-
void addLineStyle_SubmitIfNeeded(
110-
const CPULineStyle& lineStyle,
111-
uint32_t& outLineStyleIdx,
112-
SIntendedSubmitInfo& intendedNextSubmit);
111+
uint32_t addLineStyle_SubmitIfNeeded(const LineStyleInfo& lineStyle, SIntendedSubmitInfo& intendedNextSubmit);
112+
113+
uint32_t addMainObject_SubmitIfNeeded(uint32_t styleIdx, SIntendedSubmitInfo& intendedNextSubmit);
113114

114-
void addMainObject_SubmitIfNeeded(
115-
const MainObject& mainObject,
116-
uint32_t& outMainObjectIdx,
117-
SIntendedSubmitInfo& intendedNextSubmit);
118-
119-
void addClipProjectionData_SubmitIfNeeded(
120-
const ClipProjectionData& clipProjectionData,
121-
uint32_t& outClipProjectionIdx,
122-
SIntendedSubmitInfo& intendedNextSubmit);
115+
// we need to store the clip projection stack to make sure the front is always available in memory
116+
void pushClipProjectionData(const ClipProjectionData& clipProjectionData);
117+
void popClipProjectionData();
123118

124119
protected:
125120

126121
SubmitFunc submitDraws;
127-
static constexpr uint32_t InvalidLineStyleIdx = ~0u;
122+
static constexpr uint32_t InvalidStyleIdx = ~0u;
128123

129124
void finalizeMainObjectCopiesToGPU(SIntendedSubmitInfo& intendedNextSubmit);
130125

131126
void finalizeGeometryCopiesToGPU(SIntendedSubmitInfo& intendedNextSubmit);
132127

133128
void finalizeLineStyleCopiesToGPU(SIntendedSubmitInfo& intendedNextSubmit);
134-
129+
135130
void finalizeCustomClipProjectionCopiesToGPU(SIntendedSubmitInfo& intendedNextSubmit);
131+
132+
// A hatch and a polyline are considered a "Main Object" which consists of smaller geometries such as beziers, lines, connectors, hatchBoxes
133+
// If the whole polyline can't fit into memory for draw, then we submit the render of smaller geometries midway and continue
134+
void submitCurrentObjectsAndReset(SIntendedSubmitInfo& intendedNextSubmit, uint32_t mainObjectIndex);
136135

137136
uint32_t addMainObject_Internal(const MainObject& mainObject);
138137

139-
uint32_t addLineStyle_Internal(const CPULineStyle& cpuLineStyle);
138+
uint32_t addLineStyle_Internal(const LineStyleInfo& lineStyleInfo);
139+
140+
// Gets the current clip projection data (the top of stack) gpu addreess inside the geometryBuffer
141+
// If it's been invalidated then it will request to upload again with a possible auto-submit on low geometry buffer memory.
142+
uint64_t getCurrentClipProjectionAddress(SIntendedSubmitInfo& intendedNextSubmit);
143+
144+
uint64_t addClipProjectionData_SubmitIfNeeded(const ClipProjectionData& clipProjectionData, SIntendedSubmitInfo& intendedNextSubmit);
140145

141-
uint32_t addClipProjectionData_Internal(const ClipProjectionData& clipProjectionData);
146+
uint64_t addClipProjectionData_Internal(const ClipProjectionData& clipProjectionData);
142147

143148
static constexpr uint32_t getCageCountPerPolylineObject(ObjectType type)
144149
{
@@ -151,26 +156,14 @@ struct DrawBuffersFiller
151156

152157
void addPolylineObjects_Internal(const CPolylineBase& polyline, const CPolylineBase::SectionInfo& section, uint32_t& currentObjectInSection, uint32_t mainObjIdx);
153158

154-
// TODO[Prezmek]: another function named addPolylineConnectors_Internal and you pass a Range<PolylineConnectorInfo>, uint32_t currentPolylineConnectorObj, uint32_t mainObjIdx
155-
// And implement it similar to addLines/QuadBeziers_Internal which is check how much memory is left and how many PolylineConnectors you can fit into the current geometry and drawobj memory left and return to the drawPolylinefunction
156159
void addPolylineConnectors_Internal(const CPolylineBase& polyline, uint32_t& currentPolylineConnectorObj, uint32_t mainObjIdx);
157160

158-
// TODO[Przemek]: this function will change a little as you'll be copying LinePointInfos instead of double2's
159-
// Make sure to test with small memory to trigger submitInBetween function when you run out of memory to see if your changes here didn't mess things up, ask Lucas for help if you're not sure on how to do this
160161
void addLines_Internal(const CPolylineBase& polyline, const CPolylineBase::SectionInfo& section, uint32_t& currentObjectInSection, uint32_t mainObjIdx);
161162

162163
void addQuadBeziers_Internal(const CPolylineBase& polyline, const CPolylineBase::SectionInfo& section, uint32_t& currentObjectInSection, uint32_t mainObjIdx);
163164

164165
void addHatch_Internal(const Hatch& hatch, uint32_t& currentObjectInSection, uint32_t mainObjIndex);
165166

166-
void resetAllCounters()
167-
{
168-
resetMainObjectCounters();
169-
resetGeometryCounters();
170-
resetStyleCounters();
171-
resetCustomClipProjectionCounters();
172-
}
173-
174167
void resetMainObjectCounters()
175168
{
176169
inMemMainObjectCount = 0u;
@@ -184,18 +177,20 @@ struct DrawBuffersFiller
184177

185178
inMemGeometryBufferSize = 0u;
186179
currentGeometryBufferSize = 0u;
180+
181+
clipProjectionStackTopAddressInGPU = InvalidClipProjectionAddress;
187182
}
188183

189-
void resetStyleCounters()
184+
void resetLineStyleCounters()
190185
{
191186
currentLineStylesCount = 0u;
192187
inMemLineStylesCount = 0u;
193188
}
194189

195-
void resetCustomClipProjectionCounters()
190+
MainObject* getMainObject(uint32_t idx)
196191
{
197-
currentClipProjectionDataCount = 0u;
198-
inMemClipProjectionDataCount = 0u;
192+
MainObject* mainObjsArray = reinterpret_cast<MainObject*>(cpuDrawBuffers.mainObjectsBuffer->getPointer());
193+
return &mainObjsArray[idx];
199194
}
200195

201196
smart_refctd_ptr<IUtilities> m_utilities;
@@ -219,9 +214,8 @@ struct DrawBuffersFiller
219214
uint32_t currentLineStylesCount = 0u;
220215
uint32_t maxLineStyles = 0u;
221216

222-
uint32_t inMemClipProjectionDataCount = 0u;
223-
uint32_t currentClipProjectionDataCount = 0u;
224-
uint32_t maxClipProjectionData = 0u;
225-
226217
uint64_t geometryBufferAddress = 0u; // Actual BDA offset 0 of the gpu buffer
218+
219+
std::stack<ClipProjectionData> clipProjectionStack;
220+
uint64_t clipProjectionStackTopAddressInGPU = InvalidClipProjectionAddress;
227221
};

62_CAD/Hatch.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ std::array<double, 2> Hatch::Segment::intersect(const Segment& other) const
320320
return result;
321321
}
322322

323-
Hatch::Hatch(std::span<CPolyline> lines, const MajorAxis majorAxis, int32_t& debugStep, std::function<void(CPolyline, CPULineStyle)> debugOutput /* tmp */)
323+
Hatch::Hatch(std::span<CPolyline> lines, const MajorAxis majorAxis, int32_t& debugStep, std::function<void(CPolyline, LineStyleInfo)> debugOutput /* tmp */)
324324
{
325325
intersectionAmounts = std::vector<uint32_t>();
326326
// this threshsold is used to decide when to consider minor position to be
@@ -350,12 +350,12 @@ Hatch::Hatch(std::span<CPolyline> lines, const MajorAxis majorAxis, int32_t& deb
350350
beziers.push_back(tmpBezier);
351351
outputPolyline.addQuadBeziers(beziers);
352352

353-
CPULineStyle cpuLineStyle;
354-
cpuLineStyle.screenSpaceLineWidth = 4.0f;
355-
cpuLineStyle.worldSpaceLineWidth = 0.0f;
356-
cpuLineStyle.color = color;
353+
LineStyleInfo lineStyleInfo;
354+
lineStyleInfo.screenSpaceLineWidth = 4.0f;
355+
lineStyleInfo.worldSpaceLineWidth = 0.0f;
356+
lineStyleInfo.color = color;
357357

358-
debugOutput(outputPolyline, cpuLineStyle);
358+
debugOutput(outputPolyline, lineStyleInfo);
359359
};
360360

361361
auto drawDebugLine = [&](float64_t2 start, float64_t2 end, float32_t4 color)
@@ -366,12 +366,12 @@ Hatch::Hatch(std::span<CPolyline> lines, const MajorAxis majorAxis, int32_t& deb
366366
points.push_back(end);
367367
outputPolyline.addLinePoints(points);
368368

369-
CPULineStyle cpuLineStyle;
370-
cpuLineStyle.screenSpaceLineWidth = 2.0f;
371-
cpuLineStyle.worldSpaceLineWidth = 0.0f;
372-
cpuLineStyle.color = color;
369+
LineStyleInfo lineStyleInfo;
370+
lineStyleInfo.screenSpaceLineWidth = 2.0f;
371+
lineStyleInfo.worldSpaceLineWidth = 0.0f;
372+
lineStyleInfo.color = color;
373373

374-
debugOutput(outputPolyline, cpuLineStyle);
374+
debugOutput(outputPolyline, lineStyleInfo);
375375
};
376376
#endif
377377

62_CAD/Hatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Hatch
5454
// checks if it's a straight line e.g. if you're sweeping along y axis the it's a line parallel to x
5555
bool isStraightLineConstantMajor() const;
5656
};
57-
Hatch(std::span<CPolyline> lines, const MajorAxis majorAxis, int32_t& debugStep, std::function<void(CPolyline, CPULineStyle)> debugOutput /* tmp */);
57+
Hatch(std::span<CPolyline> lines, const MajorAxis majorAxis, int32_t& debugStep, std::function<void(CPolyline, LineStyleInfo)> debugOutput /* tmp */);
5858
// (temporary)
5959
Hatch(std::vector<CurveHatchBox>&& in_hatchBoxes) :
6060
hatchBoxes(std::move(in_hatchBoxes))

62_CAD/Polyline.h

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "curves.h"
99

1010
// holds values for `LineStyle` struct and caculates stipple pattern re values, cant think of better name
11-
struct CPULineStyle
11+
struct LineStyleInfo
1212
{
1313
static constexpr int32_t InvalidStipplePatternSize = -1;
1414
static constexpr double InvalidShapeOffset = nbl::hlsl::numeric_limits<double>::infinity;
@@ -208,7 +208,7 @@ struct CPULineStyle
208208

209209
float calculateStretchValue(float64_t arcLen) const
210210
{
211-
float ret = 1.0f + CPULineStyle::PatternEpsilon; // we stretch a little but more, this is to avoid clipped sdf numerical precision errors at the end of the line when we need it to be consistent (last pixels in a line or curve need to be in draw section or gap if end of pattern is in draw section or gap respectively)
211+
float ret = 1.0f + LineStyleInfo::PatternEpsilon; // we stretch a little but more, this is to avoid clipped sdf numerical precision errors at the end of the line when we need it to be consistent (last pixels in a line or curve need to be in draw section or gap if end of pattern is in draw section or gap respectively)
212212
if (stretchToFit)
213213
{
214214
const bool singleRigidSegment = rigidShapeSegment() && isSingleSegment(); // we shouldn't apply any stretching if we only have one rigid stipple segment(either all draw or all gap(invisible)
@@ -238,12 +238,12 @@ struct CPULineStyle
238238
else
239239
{
240240
// here we calculate the stretch value so that the pattern ends when the line/curve ends.
241-
// below `+ CPULineStyle::PhaseShiftEpsilon`, stretches the value a little more behaves as if arcLen is += epsilon * patternLen.
241+
// below `+ LineStyleInfo::PhaseShiftEpsilon`, stretches the value a little more behaves as if arcLen is += epsilon * patternLen.
242242
// because we need it to be consistent (last pixels in a line or curve need to be in draw section or gap if end of pattern is in draw section or gap respectively)
243243
// example: when we need to fit a pattern onto a curve, and the pattern ends at a non-draw section
244244
// the erros in the computations using phaseShift and stretch could incorrectly flag the last pixels of the curve to be in the pattern's next draw section but we needed it to end on a non draw section
245245
// when stretching a little more it will ensure the clipping does it's job so that we don't get dots at the end of the line.
246-
ret = static_cast<float>((arcLen * reciprocalStipplePatternLen + CPULineStyle::PatternEpsilon) / nSegments);
246+
ret = static_cast<float>((arcLen * reciprocalStipplePatternLen + LineStyleInfo::PatternEpsilon) / nSegments);
247247
}
248248
}
249249
}
@@ -327,12 +327,6 @@ struct CPULineStyle
327327
inline bool isVisible() const { return stipplePatternSize != InvalidStipplePatternSize; }
328328
};
329329

330-
static_assert(sizeof(DrawObject) == 16u);
331-
static_assert(sizeof(MainObject) == 8u);
332-
static_assert(sizeof(Globals) == 128u);
333-
static_assert(sizeof(LineStyle) == 96u);
334-
static_assert(sizeof(ClipProjectionData) == 88u);
335-
336330
class CPolylineBase
337331
{
338332
public:
@@ -495,7 +489,7 @@ class CPolyline : public CPolylineBase
495489

496490
typedef std::function<void(const float64_t2& /*position*/, const float64_t2& /*direction*/, float32_t /*stretch*/)> AddShapeFunc;
497491

498-
void preprocessPolylineWithStyle(const CPULineStyle& lineStyle, const AddShapeFunc& addShape = {})
492+
void preprocessPolylineWithStyle(const LineStyleInfo& lineStyle, const AddShapeFunc& addShape = {})
499493
{
500494
//if (!lineStyle.isVisible())
501495
// return;
@@ -981,7 +975,7 @@ class CPolyline : public CPolylineBase
981975
// Manual CPU Styling: breaks the current polyline into more polylines based the stipple pattern
982976
// we could output a list/vector of polylines instead of using lambda but most of the time we need to work with the output and throw it away immediately.
983977
typedef std::function<void(const CPolyline& /*current stipple*/)> OutputPolylineFunc;
984-
void stippleBreakDown(const CPULineStyle& lineStyle, const OutputPolylineFunc& addPolyline) const
978+
void stippleBreakDown(const LineStyleInfo& lineStyle, const OutputPolylineFunc& addPolyline) const
985979
{
986980
if (!lineStyle.isVisible())
987981
return;
@@ -1640,7 +1634,7 @@ class CPolyline : public CPolylineBase
16401634
connectorNormalInfos.push_back(connectorNormalInfoAtP2);
16411635
}
16421636

1643-
std::vector<PolylineConnector> buildConnectors(const CPULineStyle& lineStyle, bool isClosedPolygon)
1637+
std::vector<PolylineConnector> buildConnectors(const LineStyleInfo& lineStyle, bool isClosedPolygon)
16441638
{
16451639
std::vector<PolylineConnector> connectors;
16461640

@@ -1701,15 +1695,15 @@ class CPolyline : public CPolylineBase
17011695
}
17021696
}
17031697

1704-
bool checkIfInDrawSection(const CPULineStyle& lineStyle, float normalizedPlaceInPattern)
1698+
bool checkIfInDrawSection(const LineStyleInfo& lineStyle, float normalizedPlaceInPattern)
17051699
{
17061700
const uint32_t patternIdx = lineStyle.getPatternIdxFromNormalizedPosition(normalizedPlaceInPattern);
17071701
// odd patternIdx means a "no draw section" and current candidate should split into two nearest draw sections
17081702
return !(patternIdx & 0x1);
17091703
}
17101704

17111705
void constructMiterIfVisible(
1712-
const CPULineStyle& lineStyle,
1706+
const LineStyleInfo& lineStyle,
17131707
const PolylineConnectorNormalHelperInfo& prevLine,
17141708
const PolylineConnectorNormalHelperInfo& nextLine,
17151709
bool isMiterClosingPolyline,

62_CAD/common.hlsl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@ enum class MajorAxis : uint32_t
2424
// Consists of multiple DrawObjects
2525
struct MainObject
2626
{
27-
// TODO[Erfan]: probably have objectType here as well?
2827
uint32_t styleIdx;
29-
uint32_t clipProjectionIdx;
28+
uint32_t pad; // do I even need this?
29+
uint64_t clipProjectionAddress;
3030
};
3131

3232
struct DrawObject
3333
{
34-
// TODO: use struct bitfields in after DXC update and see if the invalid spirv bug still exists
35-
uint32_t type_subsectionIdx; // packed to uint16 into uint32
34+
uint32_t type_subsectionIdx; // packed two uint16 into uint32
3635
uint32_t mainObjIndex;
3736
uint64_t geometryAddress;
3837
};
@@ -193,8 +192,8 @@ NBL_CONSTEXPR uint32_t MainObjectIdxBits = 24u; // It will be packed next to alp
193192
NBL_CONSTEXPR uint32_t AlphaBits = 32u - MainObjectIdxBits;
194193
NBL_CONSTEXPR uint32_t MaxIndexableMainObjects = (1u << MainObjectIdxBits) - 1u;
195194
NBL_CONSTEXPR uint32_t InvalidMainObjectIdx = MaxIndexableMainObjects;
196-
NBL_CONSTEXPR uint32_t InvalidClipProjectionIdx = 0xffffffff;
197-
NBL_CONSTEXPR uint32_t UseDefaultClipProjectionIdx = InvalidClipProjectionIdx;
195+
NBL_CONSTEXPR uint64_t InvalidClipProjectionAddress = nbl::hlsl::numeric_limits<uint64_t>::max;
196+
NBL_CONSTEXPR uint32_t InvalidTextureIdx = nbl::hlsl::numeric_limits<uint32_t>::max;
198197
NBL_CONSTEXPR MajorAxis SelectedMajorAxis = MajorAxis::MAJOR_Y;
199198
// TODO: get automatic version working on HLSL
200199
NBL_CONSTEXPR MajorAxis SelectedMinorAxis = MajorAxis::MAJOR_X; //(MajorAxis) (1 - (uint32_t) SelectedMajorAxis);
@@ -435,9 +434,8 @@ struct PSInput
435434
// Set 0 - Scene Data and Globals, buffer bindings don't change the buffers only get updated
436435
[[vk::binding(0, 0)]] ConstantBuffer<Globals> globals : register(b0);
437436
[[vk::binding(1, 0)]] StructuredBuffer<DrawObject> drawObjects : register(t0);
438-
[[vk::binding(2, 0)]] StructuredBuffer<LineStyle> lineStyles : register(t1);
439-
[[vk::binding(3, 0)]] StructuredBuffer<MainObject> mainObjects : register(t2);
440-
[[vk::binding(4, 0)]] StructuredBuffer<ClipProjectionData> customClipProjections : register(t3);
437+
[[vk::binding(2, 0)]] StructuredBuffer<MainObject> mainObjects : register(t1);
438+
[[vk::binding(3, 0)]] StructuredBuffer<LineStyle> lineStyles : register(t2);
441439

442440
// Set 1 - Window dependant data which has higher update frequency due to multiple windows and resize need image recreation and descriptor writes
443441
[[vk::binding(0, 1)]] globallycoherent RWTexture2D<uint> pseudoStencil : register(u0);

0 commit comments

Comments
 (0)