Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/tessellator/tessellator.hpp
4565 views
1
/*
2
Copyright (c) Microsoft Corporation
3
4
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5
associated documentation files (the "Software"), to deal in the Software without restriction,
6
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
8
subject to the following conditions:
9
10
The above copyright notice and this permission notice shall be included in all copies or substantial
11
portions of the Software.
12
13
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
15
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
16
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
*/
19
20
#pragma once
21
//=================================================================================================================================
22
// Microsoft D3D11 Fixed Function Tessellator Reference - May 7, 2012
23
// [email protected]
24
//
25
// CHWTessellator demonstrates what is expected of hardware in the D3D11 fixed function Tessellator stage. Hardware
26
// implementers need only look at this class.
27
//
28
// CHLSLTessellator is a wrapper for CHWTessellator, representing the effect of shader code that will
29
// be autogenerated by HLSL in the Hull Shader, both for plumbing data around, and to precondition TessFactor values before they
30
// are passed to the hardware (such as deriving inside TessFactors from edge TessFactors). The algorithms used
31
// in CHLSLTessellator are subject to change, but since they represent shader code auto-generated by the HLSL compiler,
32
// CHLSLTessellator has no effect on hardware design at all. Note the HLSL compiler will expose all the raw hardware
33
// control illustrated by CHWTessellator for those who don't need the helper functionality illustrated by CHLSLTessellator.
34
//
35
// Usage: (1) Create either a CHLSLTessellator or CHWTessellator object, depending on which you want to verify.
36
// (2) Call C*Tessellator::Init()
37
// (3) Call C*Tessellator::Tessellate[IsoLine|Tri|Quad]Domain()
38
// - Here you pass in TessFactors (how much to tessellate)
39
// (4) Call C*Tessellator::GetPointCount(), C*Tessellator::GetIndexCount() to see how much data was generated.
40
// (5) Call C*Tessellator::GetPoints() and C*Tessellator::GetIndices() to get pointers to the data.
41
// The pointers are fixed for the lifetime of the object (storage for max tessellation),
42
// so if you ::Tessellate again, the data in the buffers is overwritten.
43
// (6) There are various other Get() methods to retrieve TessFactors that have been processed from
44
// what you passed in at step 3. You can retrieve separate TessFactors that the tessellator
45
// produced after clamping but before rounding, and also after rounding (say in pow2 mode).
46
// These numbers can be useful information if you are geomorphing displacement maps.
47
// (7) Goto Step 2 or 3 if you want to animate TessFactors or tessellate a different patch
48
//
49
// Code implementation details:
50
//
51
// There is lots of headroom to make this code run faster on CPUs. It was written merely as a reference for
52
// what results hardware should produce, with CPU performance not a consideration. It is nice that this implementation
53
// only generates the exact number of vertices needed (no duplicates) in the output vertex buffer. Also, the number
54
// of calculations done for each U/V domain coordinate is minimized by doing some precalculation of some patch or edge
55
// invariant numbers (see TESS_FACTOR_CONTEXT). All the vertex coordinate calculations could be computed with as much
56
// parallelism as you like. Similarly the calculation of connectivity itself is highly parallelizable, and can also
57
// be done independent of the vertex calculations.
58
//
59
//=================================================================================================================================
60
61
#define PIPE_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR 1
62
#define PIPE_TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR 63
63
#define PIPE_TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR 2
64
#define PIPE_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR 64
65
66
#define PIPE_TESSELLATOR_MIN_ISOLINE_DENSITY_TESSELLATION_FACTOR 1
67
#define PIPE_TESSELLATOR_MAX_ISOLINE_DENSITY_TESSELLATION_FACTOR 64
68
69
#define PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR 64 // max of even and odd tessFactors
70
71
#define MAX_POINT_COUNT ((PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR+1)*(PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR+1))
72
#define MAX_INDEX_COUNT (PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR*PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR*2*3)
73
74
//=================================================================================================================================
75
// Data types for the caller
76
//=================================================================================================================================
77
enum PIPE_TESSELLATOR_PARTITIONING
78
{
79
PIPE_TESSELLATOR_PARTITIONING_INTEGER,
80
PIPE_TESSELLATOR_PARTITIONING_POW2,
81
PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD,
82
PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN
83
};
84
85
enum PIPE_TESSELLATOR_REDUCTION
86
{
87
PIPE_TESSELLATOR_REDUCTION_MIN,
88
PIPE_TESSELLATOR_REDUCTION_MAX,
89
PIPE_TESSELLATOR_REDUCTION_AVERAGE
90
};
91
92
enum PIPE_TESSELLATOR_QUAD_REDUCTION_AXIS
93
{
94
PIPE_TESSELLATOR_QUAD_REDUCTION_1_AXIS,
95
PIPE_TESSELLATOR_QUAD_REDUCTION_2_AXIS
96
};
97
98
enum PIPE_TESSELLATOR_OUTPUT_PRIMITIVE
99
{
100
PIPE_TESSELLATOR_OUTPUT_POINT,
101
PIPE_TESSELLATOR_OUTPUT_LINE,
102
PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CW,
103
PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CCW,
104
};
105
106
typedef struct DOMAIN_POINT
107
{
108
float u;
109
float v; // for tri, w = 1 - u - v;
110
} DOMAIN_POINT;
111
112
//=================================================================================================================================
113
// CHWTessellator: D3D11 Tessellation Fixed Function Hardware Reference
114
//=================================================================================================================================
115
typedef unsigned int FXP; // fixed point number
116
117
class CHWTessellator
118
{
119
120
//---------------------------------------------------------------------------------------------------------------------------------
121
public:
122
void Init( PIPE_TESSELLATOR_PARTITIONING partitioning,
123
PIPE_TESSELLATOR_OUTPUT_PRIMITIVE outputPrimitive);
124
125
void TessellateIsoLineDomain( float TessFactor_V_LineDensity,
126
float TessFactor_U_LineDetail );
127
128
void TessellateTriDomain( float TessFactor_Ueq0,
129
float TessFactor_Veq0,
130
float TessFactor_Weq0,
131
float TessFactor_Inside );
132
133
void TessellateQuadDomain( float TessFactor_Ueq0,
134
float TessFactor_Veq0,
135
float TessFactor_Ueq1,
136
float TessFactor_Veq1,
137
float TessFactor_InsideU,
138
float TessFactor_InsideV );
139
140
int GetPointCount();
141
int GetIndexCount();
142
143
DOMAIN_POINT* GetPoints(); // Get CHWTessellator owned pointer to vertices (UV values).
144
// Pointer is fixed for lifetime of CHWTessellator object.
145
int* GetIndices(); // Get CHWTessellator owned pointer to vertex indices.
146
// Pointer is fixed for lifetime of CHWTessellator object.
147
148
CHWTessellator();
149
~CHWTessellator();
150
//---------------------------------------------------------------------------------------------------------------------------------
151
//=============================================================================================================================
152
// Some defines so that numbers are usually self commenting
153
//=============================================================================================================================
154
static const int U = 0; // points on a tri patch
155
static const int V = 1;
156
static const int W = 2;
157
static const int Ueq0 = 0; // edges on a tri patch
158
static const int Veq0 = 1;
159
static const int Weq0 = 2;
160
161
static const int Ueq1 = 2; // edges on a quad patch: Ueq0, Veq0, Ueq1, Veq1
162
static const int Veq1 = 3;
163
164
static const int QUAD_AXES = 2;
165
static const int QUAD_EDGES = 4;
166
static const int TRI_EDGES = 3;
167
//=============================================================================================================================
168
169
enum TESSELLATOR_PARITY // derived from PIPE_TESSELLATOR_PARTITIONING
170
{ // (note: for integer tessellation, both parities are used)
171
TESSELLATOR_PARITY_EVEN,
172
TESSELLATOR_PARITY_ODD
173
};
174
private:
175
TESSELLATOR_PARITY m_originalParity; // user chosen parity
176
TESSELLATOR_PARITY m_parity; // current parity: if allowing mix of even/odd during discrete
177
// tessellation, this can vary from the user defined parity
178
PIPE_TESSELLATOR_PARTITIONING m_originalPartitioning; // user chosen partitioning
179
PIPE_TESSELLATOR_PARTITIONING m_partitioning; // current partitioning. IsoLines overrides for line density
180
PIPE_TESSELLATOR_OUTPUT_PRIMITIVE m_outputPrimitive;
181
DOMAIN_POINT* m_Point; // array where we will store u/v's for the points we generate
182
int* m_Index; // array where we will store index topology
183
int m_NumPoints;
184
int m_NumIndices;
185
// PlacePointIn1D below is the workhorse for all position placement.
186
// It is code that could run as preamble in a Domain Shader, so the tessellator itself
187
// doesn't necessarily need to have floating point.
188
// Some per-TessFactor fixed context is needed, and that can be computed wherever
189
// the TessFactor reduction is done, perhaps as Hull Shader postamble - this is shared
190
// for all point evaluation.
191
typedef struct TESS_FACTOR_CONTEXT
192
{
193
FXP fxpInvNumSegmentsOnFloorTessFactor;
194
FXP fxpInvNumSegmentsOnCeilTessFactor;
195
FXP fxpHalfTessFactorFraction;
196
int numHalfTessFactorPoints;
197
int splitPointOnFloorHalfTessFactor;
198
} TESS_FACTOR_CONTEXT;
199
void ComputeTessFactorContext( FXP fxpTessFactor, TESS_FACTOR_CONTEXT& TessFactorCtx );
200
void PlacePointIn1D( const TESS_FACTOR_CONTEXT& TessFactorCtx, int point, FXP& fxpLocation );
201
202
int NumPointsForTessFactor(FXP fxpTessFactor);
203
204
// Tessellation parity control
205
bool Odd() {return (m_parity == TESSELLATOR_PARITY_ODD) ? true : false;}
206
void SetTessellationParity(TESSELLATOR_PARITY parity) {m_parity = parity;}
207
208
// HWIntegerPartitioning() - hardware doesn't care about what pow2 partitioning is - the query below is true for
209
// both integer and pow2.
210
bool HWIntegerPartitioning() {return ((m_partitioning == PIPE_TESSELLATOR_PARTITIONING_INTEGER)||
211
(m_partitioning == PIPE_TESSELLATOR_PARTITIONING_POW2)) ? true : false;}
212
213
// Tesselation Partitioning control
214
void RestorePartitioning() {m_partitioning = m_originalPartitioning;};
215
void OverridePartitioning(PIPE_TESSELLATOR_PARTITIONING partitioning) {m_partitioning = partitioning;} //isoline uses this for density
216
217
// Call these to generate new points and indices. Max TessFactor storage is already allocated.
218
int DefinePoint(FXP u, FXP v, int pointStorageOffset);
219
void DefineIndex(int index, int indexStorageOffset);
220
void DefineClockwiseTriangle(int index0, int index1, int index2, int indexStorageBaseOffset);
221
222
// Couple of trivial ways to generate index data just given points and no other connectivity.
223
void DumpAllPoints(); // Make point indices for point rendering mode -
224
// redundant, but just here for orthogonality.
225
void DumpAllPointsAsInOrderLineList(); // A debug visualization of all the points connected
226
// in the order they were generated.
227
// Asking to draw line topology on a tri or quad patch will do this
228
229
230
// The structures below define the data that is derived given input TessFactors and which
231
// is used by point generation and connectivity generation steps (each of which are independent)
232
typedef struct PROCESSED_TESS_FACTORS_ISOLINE
233
{
234
TESSELLATOR_PARITY lineDensityParity;
235
TESSELLATOR_PARITY lineDetailParity;
236
TESS_FACTOR_CONTEXT lineDensityTessFactorCtx;
237
TESS_FACTOR_CONTEXT lineDetailTessFactorCtx;
238
bool bPatchCulled;
239
int numPointsPerLine;
240
int numLines;
241
} PROCESSED_TESS_FACTORS_ISOLINE;
242
typedef struct PROCESSED_TESS_FACTORS_TRI
243
{
244
FXP outsideTessFactor[TRI_EDGES];
245
FXP insideTessFactor;
246
TESSELLATOR_PARITY outsideTessFactorParity[TRI_EDGES];
247
TESSELLATOR_PARITY insideTessFactorParity;
248
TESS_FACTOR_CONTEXT outsideTessFactorCtx[TRI_EDGES];
249
TESS_FACTOR_CONTEXT insideTessFactorCtx;
250
bool bJustDoMinimumTessFactor;
251
bool bPatchCulled;
252
// Stuff below is just specific to the traversal order
253
// this code happens to use to generate points/lines
254
int numPointsForOutsideEdge[TRI_EDGES];
255
int numPointsForInsideTessFactor;
256
int insideEdgePointBaseOffset;
257
} PROCESSED_TESS_FACTORS_TRI;
258
typedef struct PROCESSED_TESS_FACTORS_QUAD
259
{
260
FXP outsideTessFactor[QUAD_EDGES];
261
FXP insideTessFactor[QUAD_AXES];
262
TESSELLATOR_PARITY outsideTessFactorParity[QUAD_EDGES];
263
TESSELLATOR_PARITY insideTessFactorParity[QUAD_AXES];
264
TESS_FACTOR_CONTEXT outsideTessFactorCtx[QUAD_EDGES];
265
TESS_FACTOR_CONTEXT insideTessFactorCtx[QUAD_AXES];
266
bool bJustDoMinimumTessFactor;
267
bool bPatchCulled;
268
// Stuff below is just specific to the traversal order
269
// this code happens to use to generate points/lines
270
int numPointsForOutsideEdge[QUAD_EDGES];
271
int numPointsForInsideTessFactor[QUAD_AXES];
272
int insideEdgePointBaseOffset;
273
} PROCESSED_TESS_FACTORS_QUAD;
274
275
// These are the workhorse functions for tessellation:
276
// (1) Process input TessFactors
277
// (2) Generate points
278
// (3) Generate connectivity (can be done in parallel to (2))
279
void IsoLineProcessTessFactors( float TessFactor_V_LineDensity, float TessFactor_U_LineDetail, PROCESSED_TESS_FACTORS_ISOLINE& processedTessFactors );
280
void IsoLineGeneratePoints( const PROCESSED_TESS_FACTORS_ISOLINE& processedTessFactors );
281
void IsoLineGenerateConnectivity( const PROCESSED_TESS_FACTORS_ISOLINE& processedTessFactors );
282
void TriProcessTessFactors( float tessFactor_Ueq0, float TessFactor_Veq0, float TessFactor_Weq0, float insideTessFactor, PROCESSED_TESS_FACTORS_TRI& processedTessFactors );
283
void TriGeneratePoints( const PROCESSED_TESS_FACTORS_TRI& processedTessFactors );
284
void TriGenerateConnectivity( const PROCESSED_TESS_FACTORS_TRI& processedTessFactors );
285
void QuadProcessTessFactors( float tessFactor_Ueq0, float tessFactor_Veq0, float tessFactor_Ueq1, float tessFactor_Veq1,
286
float insideTessFactor_U, float insideTessFactor_V, PROCESSED_TESS_FACTORS_QUAD& processedTessFactors );
287
void QuadGeneratePoints( const PROCESSED_TESS_FACTORS_QUAD& processedTessFactors );
288
void QuadGenerateConnectivity( const PROCESSED_TESS_FACTORS_QUAD& processedTessFactors );
289
290
// Stitching
291
// ---------
292
// Given pointers to the beginning of 2 parallel rows of points, and TessFactors for each, stitch them.
293
// The assumption is the stitch is symmetric.
294
void StitchTransition(int baseIndexOffset, int insideEdgePointBaseOffset, int insideNumHalfTessFactorPoints,
295
TESSELLATOR_PARITY insideEdgeTessFactorParity,
296
int outsideEdgePointBaseOffset, int outsideNumHalfTessFactorPoints,
297
TESSELLATOR_PARITY outsideEdgeTessFactorParity );
298
// The interior can just use a simpler stitch.
299
enum DIAGONALS
300
{
301
DIAGONALS_INSIDE_TO_OUTSIDE,
302
DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE,
303
DIAGONALS_MIRRORED
304
};
305
306
void StitchRegular(bool bTrapezoid, DIAGONALS diagonals, int baseIndexOffset, int numInsideEdgePoints,
307
int insideEdgePointBaseOffset, int outsideEdgePointBaseOffset);
308
309
//---------------------------------------------------------------------------------------------------------------------------------
310
// Index Patching
311
// --------------
312
// The code below patches index values produces during triangulation, so triangulation doesn't have to know
313
// where points should go. I happened to never produce duplicate vertices, but the patching would
314
// be simpler if some duplicate vertices were introduced in practice. During point rendering mode however,
315
// it is not permitted for duplicate points to show up.
316
317
// Since the points are generated in concentric rings, most of the time, the point locations are
318
// sequentially increasing in memory for each side of a ring, which the stitch can take advantage of.
319
// However, there are exceptions where the points are not sequentially increasing, such as
320
// the 4th row in a given ring, where the last point on the outside of each row is actually the beginning
321
// point.
322
// So we let the stitching code think it sees sequential vertices, and when it emits a vertex index,
323
// we patch it to be the real location.
324
int PatchIndexValue(int index);
325
typedef struct INDEX_PATCH_CONTEXT
326
{
327
int insidePointIndexDeltaToRealValue;
328
int insidePointIndexBadValue;
329
int insidePointIndexReplacementValue;
330
int outsidePointIndexPatchBase;
331
int outsidePointIndexDeltaToRealValue;
332
int outsidePointIndexBadValue;
333
int outsidePointIndexReplacementValue;
334
} INDEX_PATCH_CONTEXT;
335
void SetUsingPatchedIndices(bool bUsingPatchedIndices) {m_bUsingPatchedIndices = bUsingPatchedIndices;}
336
337
// A second index patch we have to do handles the leftover strip of quads in the middle of an odd quad patch after
338
// finishing all the concentric rings.
339
// This also handles the leftover strip of points in the middle of an even quad
340
// patch, when stitching the row of triangles up the left side (V major quad) or bottom (U major quad) of the
341
// inner ring
342
typedef struct INDEX_PATCH_CONTEXT2
343
{
344
int baseIndexToInvert;
345
int indexInversionEndPoint;
346
int cornerCaseBadValue;
347
int cornerCaseReplacementValue;
348
} INDEX_PATCH_CONTEXT2;
349
void SetUsingPatchedIndices2(bool bUsingPatchedIndices) {m_bUsingPatchedIndices2 = bUsingPatchedIndices;}
350
bool m_bUsingPatchedIndices;
351
bool m_bUsingPatchedIndices2;
352
INDEX_PATCH_CONTEXT m_IndexPatchContext;
353
INDEX_PATCH_CONTEXT2 m_IndexPatchContext2;
354
355
};
356
357
//=================================================================================================================================
358
// CHLSLTessellator: PIPE Tessellation HLSL Tessellator Interface
359
// Demonstrates TessFactor preconditioning code auto-generated by HLSL. Subject to change, but this
360
// just represents the effect of shader code the HLSL compiler will generate in the Hull Shader,
361
// so it does not affect hardware design at all.
362
//=================================================================================================================================
363
class CHLSLTessellator : public CHWTessellator
364
{
365
public:
366
void Init( PIPE_TESSELLATOR_PARTITIONING partitioning,
367
PIPE_TESSELLATOR_REDUCTION insideTessFactorReduction,
368
PIPE_TESSELLATOR_QUAD_REDUCTION_AXIS quadInsideTessFactorReductionAxis,
369
PIPE_TESSELLATOR_OUTPUT_PRIMITIVE outputPrimitive);
370
371
void TessellateIsoLineDomain( float TessFactor_V_LineDensity,
372
float TessFactor_U_LineDetail );
373
374
void TessellateTriDomain( float tessFactor_Ueq0,
375
float TessFactor_Veq0,
376
float TessFactor_Weq0,
377
float insideTessFactorScale /*[0..1]*/ );
378
379
void TessellateQuadDomain( float TessFactorUeq0,
380
float TessFactorVeq0,
381
float TessFactorUeq1,
382
float TessFactorVeq1,
383
float insideTessFactorScaleU /*[0..1]*/,
384
float insideTessFactorScaleV /*[0..1]*/ );
385
386
int GetPointCount() {return CHWTessellator::GetPointCount();};
387
int GetIndexCount() {return CHWTessellator::GetIndexCount();}
388
389
DOMAIN_POINT* GetPoints() {return CHWTessellator::GetPoints();} // Get CHLSLTessellator owned pointer to vertices (UV values).
390
// Pointer is fixed for lifetime of CHLSLTessellator object.
391
int* GetIndices() {return CHWTessellator::GetIndices();} // Get CHLSLTessellator owned pointer to vertex indices.
392
// Pointer is fixed for lifetime of CHLSLTessellator object.
393
394
// Retrieve TessFactors actually used by the "hardware"
395
// This includes clamping to valid range, and more interestingly
396
// if integer or pow2 partitioning is being done, the rounded TessFactors can be retrieved.
397
// Getting the rounded TessFactors can be useful for geomorphing of displacement maps.
398
float GetIsoLineDensityTessFactor() {return m_LastComputedTessFactors[0];}
399
float GetIsoLineDetailTessFactor() {return m_LastComputedTessFactors[1];}
400
float GetTriUeq0TessFactor() {return m_LastComputedTessFactors[0];}
401
float GetTriVeq0TessFactor() {return m_LastComputedTessFactors[1];}
402
float GetTriWeq0TessFactor() {return m_LastComputedTessFactors[2];}
403
float GetTriInsideTessFactor() {return m_LastComputedTessFactors[3];}
404
float GetQuadUeq0TessFactor() {return m_LastComputedTessFactors[0];}
405
float GetQuadVeq0TessFactor() {return m_LastComputedTessFactors[1];}
406
float GetQuadUeq1TessFactor() {return m_LastComputedTessFactors[2];}
407
float GetQuadVeq1TessFactor() {return m_LastComputedTessFactors[3];}
408
float GetQuadInsideUTessFactor() {return m_LastComputedTessFactors[4];}
409
float GetQuadInsideVTessFactor() {return m_LastComputedTessFactors[5];}
410
float GetUnRoundedIsoLineDensityTessFactor() {return m_LastUnRoundedComputedTessFactors[0];}
411
float GetUnRoundedIsoLineDetailTessFactor() {return m_LastUnRoundedComputedTessFactors[1];}
412
float GetUnRoundedTriUeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[0];}
413
float GetUnRoundedTriVeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[1];}
414
float GetUnRoundedTriWeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[2];}
415
float GetUnRoundedTriInsideTessFactor() {return m_LastUnRoundedComputedTessFactors[3];}
416
float GetUnRoundedQuadUeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[0];}
417
float GetUnRoundedQuadVeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[1];}
418
float GetUnRoundedQuadUeq1TessFactor() {return m_LastUnRoundedComputedTessFactors[2];}
419
float GetUnRoundedQuadVeq1TessFactor() {return m_LastUnRoundedComputedTessFactors[3];}
420
float GetUnRoundedQuadInsideUTessFactor() {return m_LastUnRoundedComputedTessFactors[4];}
421
float GetUnRoundedQuadInsideVTessFactor() {return m_LastUnRoundedComputedTessFactors[5];}
422
423
CHLSLTessellator();
424
//---------------------------------------------------------------------------------------------------------------------------------
425
private:
426
TESSELLATOR_PARITY m_originalParity; // user chosen parity
427
TESSELLATOR_PARITY m_parity; // current parity: if allowing mix of even/odd during discrete
428
// tessellation, this can vary from the user defined parity
429
PIPE_TESSELLATOR_PARTITIONING m_originalPartitioning; // user chosen partitioning
430
PIPE_TESSELLATOR_PARTITIONING m_partitioning; // current partitioning. IsoLines overrides for line density
431
PIPE_TESSELLATOR_OUTPUT_PRIMITIVE m_outputPrimitive;
432
PIPE_TESSELLATOR_REDUCTION m_insideTessFactorReduction;
433
PIPE_TESSELLATOR_QUAD_REDUCTION_AXIS m_quadInsideTessFactorReductionAxis;
434
float m_LastComputedTessFactors[6]; // TessFactors used for last tessellation
435
float m_LastUnRoundedComputedTessFactors[6]; // TessFactors used for last tessellation (before they were rounded)
436
bool IntegerPartitioning() {return (m_partitioning == PIPE_TESSELLATOR_PARTITIONING_INTEGER) ? true : false;}
437
bool Pow2Partitioning() {return (m_partitioning == PIPE_TESSELLATOR_PARTITIONING_POW2)? true : false;}
438
void ClampTessFactor(float& TessFactor);
439
void RoundUpTessFactor(float& TessFactor);
440
void CleanupFloatTessFactor(float& input); // clamp float to [1.0f... +INF] (incl NaN->1.0f)
441
void ClampFloatTessFactorScale(float& input); // clamp float to [0.0f... +INF] (incl NaN->0.0f)
442
443
// Tessellation parity control
444
bool Odd() {return (m_parity == TESSELLATOR_PARITY_ODD) ? true : false;}
445
void SetTessellationParity(TESSELLATOR_PARITY parity) {m_parity = parity;}
446
447
// Tesselation Partitioning control
448
void RestorePartitioning() {m_partitioning = m_originalPartitioning;};
449
void OverridePartitioning(PIPE_TESSELLATOR_PARTITIONING partitioning) {m_partitioning = partitioning;} //isoline uses this for density
450
451
void IsoLineHLSLProcessTessFactors( float TessFactor_V_LineDensity, float TessFactor_U_LineDetail );
452
void TriHLSLProcessTessFactors( float tessFactor_Ueq0, float TessFactor_Veq0, float TessFactor_Weq0, float insideTessFactor );
453
void QuadHLSLProcessTessFactors( float TessFactor_Ueq0, float TessFactor_Veq0, float TessFactor_Ueq1, float TessFactor_Veq1,
454
float insideTessFactor_U, float insideTessFactor_V );
455
456
};
457
458
459