| /* |
| Copyright (c) Microsoft Corporation |
| |
| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
| associated documentation files (the "Software"), to deal in the Software without restriction, |
| including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, |
| subject to the following conditions: |
| |
| The above copyright notice and this permission notice shall be included in all copies or substantial |
| portions of the Software. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
| NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #pragma once |
| //================================================================================================================================= |
| // Microsoft D3D11 Fixed Function Tessellator Reference - May 7, 2012 |
| // amar.patel@microsoft.com |
| // |
| // CHWTessellator demonstrates what is expected of hardware in the D3D11 fixed function Tessellator stage. Hardware |
| // implementers need only look at this class. |
| // |
| // CHLSLTessellator is a wrapper for CHWTessellator, representing the effect of shader code that will |
| // be autogenerated by HLSL in the Hull Shader, both for plumbing data around, and to precondition TessFactor values before they |
| // are passed to the hardware (such as deriving inside TessFactors from edge TessFactors). The algorithms used |
| // in CHLSLTessellator are subject to change, but since they represent shader code auto-generated by the HLSL compiler, |
| // CHLSLTessellator has no effect on hardware design at all. Note the HLSL compiler will expose all the raw hardware |
| // control illustrated by CHWTessellator for those who don't need the helper functionality illustrated by CHLSLTessellator. |
| // |
| // Usage: (1) Create either a CHLSLTessellator or CHWTessellator object, depending on which you want to verify. |
| // (2) Call C*Tessellator::Init() |
| // (3) Call C*Tessellator::Tessellate[IsoLine|Tri|Quad]Domain() |
| // - Here you pass in TessFactors (how much to tessellate) |
| // (4) Call C*Tessellator::GetPointCount(), C*Tessellator::GetIndexCount() to see how much data was generated. |
| // (5) Call C*Tessellator::GetPoints() and C*Tessellator::GetIndices() to get pointers to the data. |
| // The pointers are fixed for the lifetime of the object (storage for max tessellation), |
| // so if you ::Tessellate again, the data in the buffers is overwritten. |
| // (6) There are various other Get() methods to retrieve TessFactors that have been processed from |
| // what you passed in at step 3. You can retrieve separate TessFactors that the tessellator |
| // produced after clamping but before rounding, and also after rounding (say in pow2 mode). |
| // These numbers can be useful information if you are geomorphing displacement maps. |
| // (7) Goto Step 2 or 3 if you want to animate TessFactors or tessellate a different patch |
| // |
| // Code implementation details: |
| // |
| // There is lots of headroom to make this code run faster on CPUs. It was written merely as a reference for |
| // what results hardware should produce, with CPU performance not a consideration. It is nice that this implementation |
| // only generates the exact number of vertices needed (no duplicates) in the output vertex buffer. Also, the number |
| // of calculations done for each U/V domain coordinate is minimized by doing some precalculation of some patch or edge |
| // invariant numbers (see TESS_FACTOR_CONTEXT). All the vertex coordinate calculations could be computed with as much |
| // parallelism as you like. Similarly the calculation of connectivity itself is highly parallelizable, and can also |
| // be done independent of the vertex calculations. |
| // |
| //================================================================================================================================= |
| |
| #define PIPE_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR 1 |
| #define PIPE_TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR 63 |
| #define PIPE_TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR 2 |
| #define PIPE_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR 64 |
| |
| #define PIPE_TESSELLATOR_MIN_ISOLINE_DENSITY_TESSELLATION_FACTOR 1 |
| #define PIPE_TESSELLATOR_MAX_ISOLINE_DENSITY_TESSELLATION_FACTOR 64 |
| |
| #define PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR 64 // max of even and odd tessFactors |
| |
| #define MAX_POINT_COUNT ((PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR+1)*(PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR+1)) |
| #define MAX_INDEX_COUNT (PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR*PIPE_TESSELLATOR_MAX_TESSELLATION_FACTOR*2*3) |
| |
| //================================================================================================================================= |
| // Data types for the caller |
| //================================================================================================================================= |
| enum PIPE_TESSELLATOR_PARTITIONING |
| { |
| PIPE_TESSELLATOR_PARTITIONING_INTEGER, |
| PIPE_TESSELLATOR_PARTITIONING_POW2, |
| PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, |
| PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN |
| }; |
| |
| enum PIPE_TESSELLATOR_REDUCTION |
| { |
| PIPE_TESSELLATOR_REDUCTION_MIN, |
| PIPE_TESSELLATOR_REDUCTION_MAX, |
| PIPE_TESSELLATOR_REDUCTION_AVERAGE |
| }; |
| |
| enum PIPE_TESSELLATOR_QUAD_REDUCTION_AXIS |
| { |
| PIPE_TESSELLATOR_QUAD_REDUCTION_1_AXIS, |
| PIPE_TESSELLATOR_QUAD_REDUCTION_2_AXIS |
| }; |
| |
| enum PIPE_TESSELLATOR_OUTPUT_PRIMITIVE |
| { |
| PIPE_TESSELLATOR_OUTPUT_POINT, |
| PIPE_TESSELLATOR_OUTPUT_LINE, |
| PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CW, |
| PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CCW, |
| }; |
| |
| typedef struct DOMAIN_POINT |
| { |
| float u; |
| float v; // for tri, w = 1 - u - v; |
| } DOMAIN_POINT; |
| |
| //================================================================================================================================= |
| // CHWTessellator: D3D11 Tessellation Fixed Function Hardware Reference |
| //================================================================================================================================= |
| typedef unsigned int FXP; // fixed point number |
| |
| class CHWTessellator |
| { |
| |
| //--------------------------------------------------------------------------------------------------------------------------------- |
| public: |
| void Init( PIPE_TESSELLATOR_PARTITIONING partitioning, |
| PIPE_TESSELLATOR_OUTPUT_PRIMITIVE outputPrimitive); |
| |
| void TessellateIsoLineDomain( float TessFactor_V_LineDensity, |
| float TessFactor_U_LineDetail ); |
| |
| void TessellateTriDomain( float TessFactor_Ueq0, |
| float TessFactor_Veq0, |
| float TessFactor_Weq0, |
| float TessFactor_Inside ); |
| |
| void TessellateQuadDomain( float TessFactor_Ueq0, |
| float TessFactor_Veq0, |
| float TessFactor_Ueq1, |
| float TessFactor_Veq1, |
| float TessFactor_InsideU, |
| float TessFactor_InsideV ); |
| |
| int GetPointCount(); |
| int GetIndexCount(); |
| |
| DOMAIN_POINT* GetPoints(); // Get CHWTessellator owned pointer to vertices (UV values). |
| // Pointer is fixed for lifetime of CHWTessellator object. |
| int* GetIndices(); // Get CHWTessellator owned pointer to vertex indices. |
| // Pointer is fixed for lifetime of CHWTessellator object. |
| |
| CHWTessellator(); |
| ~CHWTessellator(); |
| //--------------------------------------------------------------------------------------------------------------------------------- |
| //============================================================================================================================= |
| // Some defines so that numbers are usually self commenting |
| //============================================================================================================================= |
| static const int U = 0; // points on a tri patch |
| static const int V = 1; |
| static const int W = 2; |
| static const int Ueq0 = 0; // edges on a tri patch |
| static const int Veq0 = 1; |
| static const int Weq0 = 2; |
| |
| static const int Ueq1 = 2; // edges on a quad patch: Ueq0, Veq0, Ueq1, Veq1 |
| static const int Veq1 = 3; |
| |
| static const int QUAD_AXES = 2; |
| static const int QUAD_EDGES = 4; |
| static const int TRI_EDGES = 3; |
| //============================================================================================================================= |
| |
| enum TESSELLATOR_PARITY // derived from PIPE_TESSELLATOR_PARTITIONING |
| { // (note: for integer tessellation, both parities are used) |
| TESSELLATOR_PARITY_EVEN, |
| TESSELLATOR_PARITY_ODD |
| }; |
| private: |
| TESSELLATOR_PARITY m_originalParity; // user chosen parity |
| TESSELLATOR_PARITY m_parity; // current parity: if allowing mix of even/odd during discrete |
| // tessellation, this can vary from the user defined parity |
| PIPE_TESSELLATOR_PARTITIONING m_originalPartitioning; // user chosen partitioning |
| PIPE_TESSELLATOR_PARTITIONING m_partitioning; // current partitioning. IsoLines overrides for line density |
| PIPE_TESSELLATOR_OUTPUT_PRIMITIVE m_outputPrimitive; |
| DOMAIN_POINT* m_Point; // array where we will store u/v's for the points we generate |
| int* m_Index; // array where we will store index topology |
| int m_NumPoints; |
| int m_NumIndices; |
| // PlacePointIn1D below is the workhorse for all position placement. |
| // It is code that could run as preamble in a Domain Shader, so the tessellator itself |
| // doesn't necessarily need to have floating point. |
| // Some per-TessFactor fixed context is needed, and that can be computed wherever |
| // the TessFactor reduction is done, perhaps as Hull Shader postamble - this is shared |
| // for all point evaluation. |
| typedef struct TESS_FACTOR_CONTEXT |
| { |
| FXP fxpInvNumSegmentsOnFloorTessFactor; |
| FXP fxpInvNumSegmentsOnCeilTessFactor; |
| FXP fxpHalfTessFactorFraction; |
| int numHalfTessFactorPoints; |
| int splitPointOnFloorHalfTessFactor; |
| } TESS_FACTOR_CONTEXT; |
| void ComputeTessFactorContext( FXP fxpTessFactor, TESS_FACTOR_CONTEXT& TessFactorCtx ); |
| void PlacePointIn1D( const TESS_FACTOR_CONTEXT& TessFactorCtx, int point, FXP& fxpLocation ); |
| |
| int NumPointsForTessFactor(FXP fxpTessFactor); |
| |
| // Tessellation parity control |
| bool Odd() {return (m_parity == TESSELLATOR_PARITY_ODD) ? true : false;} |
| void SetTessellationParity(TESSELLATOR_PARITY parity) {m_parity = parity;} |
| |
| // HWIntegerPartitioning() - hardware doesn't care about what pow2 partitioning is - the query below is true for |
| // both integer and pow2. |
| bool HWIntegerPartitioning() {return ((m_partitioning == PIPE_TESSELLATOR_PARTITIONING_INTEGER)|| |
| (m_partitioning == PIPE_TESSELLATOR_PARTITIONING_POW2)) ? true : false;} |
| |
| // Tesselation Partitioning control |
| void RestorePartitioning() {m_partitioning = m_originalPartitioning;}; |
| void OverridePartitioning(PIPE_TESSELLATOR_PARTITIONING partitioning) {m_partitioning = partitioning;} //isoline uses this for density |
| |
| // Call these to generate new points and indices. Max TessFactor storage is already allocated. |
| int DefinePoint(FXP u, FXP v, int pointStorageOffset); |
| void DefineIndex(int index, int indexStorageOffset); |
| void DefineClockwiseTriangle(int index0, int index1, int index2, int indexStorageBaseOffset); |
| |
| // Couple of trivial ways to generate index data just given points and no other connectivity. |
| void DumpAllPoints(); // Make point indices for point rendering mode - |
| // redundant, but just here for orthogonality. |
| void DumpAllPointsAsInOrderLineList(); // A debug visualization of all the points connected |
| // in the order they were generated. |
| // Asking to draw line topology on a tri or quad patch will do this |
| |
| |
| // The structures below define the data that is derived given input TessFactors and which |
| // is used by point generation and connectivity generation steps (each of which are independent) |
| typedef struct PROCESSED_TESS_FACTORS_ISOLINE |
| { |
| TESSELLATOR_PARITY lineDensityParity; |
| TESSELLATOR_PARITY lineDetailParity; |
| TESS_FACTOR_CONTEXT lineDensityTessFactorCtx; |
| TESS_FACTOR_CONTEXT lineDetailTessFactorCtx; |
| bool bPatchCulled; |
| int numPointsPerLine; |
| int numLines; |
| } PROCESSED_TESS_FACTORS_ISOLINE; |
| typedef struct PROCESSED_TESS_FACTORS_TRI |
| { |
| FXP outsideTessFactor[TRI_EDGES]; |
| FXP insideTessFactor; |
| TESSELLATOR_PARITY outsideTessFactorParity[TRI_EDGES]; |
| TESSELLATOR_PARITY insideTessFactorParity; |
| TESS_FACTOR_CONTEXT outsideTessFactorCtx[TRI_EDGES]; |
| TESS_FACTOR_CONTEXT insideTessFactorCtx; |
| bool bJustDoMinimumTessFactor; |
| bool bPatchCulled; |
| // Stuff below is just specific to the traversal order |
| // this code happens to use to generate points/lines |
| int numPointsForOutsideEdge[TRI_EDGES]; |
| int numPointsForInsideTessFactor; |
| int insideEdgePointBaseOffset; |
| } PROCESSED_TESS_FACTORS_TRI; |
| typedef struct PROCESSED_TESS_FACTORS_QUAD |
| { |
| FXP outsideTessFactor[QUAD_EDGES]; |
| FXP insideTessFactor[QUAD_AXES]; |
| TESSELLATOR_PARITY outsideTessFactorParity[QUAD_EDGES]; |
| TESSELLATOR_PARITY insideTessFactorParity[QUAD_AXES]; |
| TESS_FACTOR_CONTEXT outsideTessFactorCtx[QUAD_EDGES]; |
| TESS_FACTOR_CONTEXT insideTessFactorCtx[QUAD_AXES]; |
| bool bJustDoMinimumTessFactor; |
| bool bPatchCulled; |
| // Stuff below is just specific to the traversal order |
| // this code happens to use to generate points/lines |
| int numPointsForOutsideEdge[QUAD_EDGES]; |
| int numPointsForInsideTessFactor[QUAD_AXES]; |
| int insideEdgePointBaseOffset; |
| } PROCESSED_TESS_FACTORS_QUAD; |
| |
| // These are the workhorse functions for tessellation: |
| // (1) Process input TessFactors |
| // (2) Generate points |
| // (3) Generate connectivity (can be done in parallel to (2)) |
| void IsoLineProcessTessFactors( float TessFactor_V_LineDensity, float TessFactor_U_LineDetail, PROCESSED_TESS_FACTORS_ISOLINE& processedTessFactors ); |
| void IsoLineGeneratePoints( const PROCESSED_TESS_FACTORS_ISOLINE& processedTessFactors ); |
| void IsoLineGenerateConnectivity( const PROCESSED_TESS_FACTORS_ISOLINE& processedTessFactors ); |
| void TriProcessTessFactors( float tessFactor_Ueq0, float TessFactor_Veq0, float TessFactor_Weq0, float insideTessFactor, PROCESSED_TESS_FACTORS_TRI& processedTessFactors ); |
| void TriGeneratePoints( const PROCESSED_TESS_FACTORS_TRI& processedTessFactors ); |
| void TriGenerateConnectivity( const PROCESSED_TESS_FACTORS_TRI& processedTessFactors ); |
| void QuadProcessTessFactors( float tessFactor_Ueq0, float tessFactor_Veq0, float tessFactor_Ueq1, float tessFactor_Veq1, |
| float insideTessFactor_U, float insideTessFactor_V, PROCESSED_TESS_FACTORS_QUAD& processedTessFactors ); |
| void QuadGeneratePoints( const PROCESSED_TESS_FACTORS_QUAD& processedTessFactors ); |
| void QuadGenerateConnectivity( const PROCESSED_TESS_FACTORS_QUAD& processedTessFactors ); |
| |
| // Stitching |
| // --------- |
| // Given pointers to the beginning of 2 parallel rows of points, and TessFactors for each, stitch them. |
| // The assumption is the stitch is symmetric. |
| void StitchTransition(int baseIndexOffset, int insideEdgePointBaseOffset, int insideNumHalfTessFactorPoints, |
| TESSELLATOR_PARITY insideEdgeTessFactorParity, |
| int outsideEdgePointBaseOffset, int outsideNumHalfTessFactorPoints, |
| TESSELLATOR_PARITY outsideEdgeTessFactorParity ); |
| // The interior can just use a simpler stitch. |
| enum DIAGONALS |
| { |
| DIAGONALS_INSIDE_TO_OUTSIDE, |
| DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE, |
| DIAGONALS_MIRRORED |
| }; |
| |
| void StitchRegular(bool bTrapezoid, DIAGONALS diagonals, int baseIndexOffset, int numInsideEdgePoints, |
| int insideEdgePointBaseOffset, int outsideEdgePointBaseOffset); |
| |
| //--------------------------------------------------------------------------------------------------------------------------------- |
| // Index Patching |
| // -------------- |
| // The code below patches index values produces during triangulation, so triangulation doesn't have to know |
| // where points should go. I happened to never produce duplicate vertices, but the patching would |
| // be simpler if some duplicate vertices were introduced in practice. During point rendering mode however, |
| // it is not permitted for duplicate points to show up. |
| |
| // Since the points are generated in concentric rings, most of the time, the point locations are |
| // sequentially increasing in memory for each side of a ring, which the stitch can take advantage of. |
| // However, there are exceptions where the points are not sequentially increasing, such as |
| // the 4th row in a given ring, where the last point on the outside of each row is actually the beginning |
| // point. |
| // So we let the stitching code think it sees sequential vertices, and when it emits a vertex index, |
| // we patch it to be the real location. |
| int PatchIndexValue(int index); |
| typedef struct INDEX_PATCH_CONTEXT |
| { |
| int insidePointIndexDeltaToRealValue; |
| int insidePointIndexBadValue; |
| int insidePointIndexReplacementValue; |
| int outsidePointIndexPatchBase; |
| int outsidePointIndexDeltaToRealValue; |
| int outsidePointIndexBadValue; |
| int outsidePointIndexReplacementValue; |
| } INDEX_PATCH_CONTEXT; |
| void SetUsingPatchedIndices(bool bUsingPatchedIndices) {m_bUsingPatchedIndices = bUsingPatchedIndices;} |
| |
| // A second index patch we have to do handles the leftover strip of quads in the middle of an odd quad patch after |
| // finishing all the concentric rings. |
| // This also handles the leftover strip of points in the middle of an even quad |
| // patch, when stitching the row of triangles up the left side (V major quad) or bottom (U major quad) of the |
| // inner ring |
| typedef struct INDEX_PATCH_CONTEXT2 |
| { |
| int baseIndexToInvert; |
| int indexInversionEndPoint; |
| int cornerCaseBadValue; |
| int cornerCaseReplacementValue; |
| } INDEX_PATCH_CONTEXT2; |
| void SetUsingPatchedIndices2(bool bUsingPatchedIndices) {m_bUsingPatchedIndices2 = bUsingPatchedIndices;} |
| bool m_bUsingPatchedIndices; |
| bool m_bUsingPatchedIndices2; |
| INDEX_PATCH_CONTEXT m_IndexPatchContext; |
| INDEX_PATCH_CONTEXT2 m_IndexPatchContext2; |
| |
| }; |
| |
| //================================================================================================================================= |
| // CHLSLTessellator: PIPE Tessellation HLSL Tessellator Interface |
| // Demonstrates TessFactor preconditioning code auto-generated by HLSL. Subject to change, but this |
| // just represents the effect of shader code the HLSL compiler will generate in the Hull Shader, |
| // so it does not affect hardware design at all. |
| //================================================================================================================================= |
| class CHLSLTessellator : public CHWTessellator |
| { |
| public: |
| void Init( PIPE_TESSELLATOR_PARTITIONING partitioning, |
| PIPE_TESSELLATOR_REDUCTION insideTessFactorReduction, |
| PIPE_TESSELLATOR_QUAD_REDUCTION_AXIS quadInsideTessFactorReductionAxis, |
| PIPE_TESSELLATOR_OUTPUT_PRIMITIVE outputPrimitive); |
| |
| void TessellateIsoLineDomain( float TessFactor_V_LineDensity, |
| float TessFactor_U_LineDetail ); |
| |
| void TessellateTriDomain( float tessFactor_Ueq0, |
| float TessFactor_Veq0, |
| float TessFactor_Weq0, |
| float insideTessFactorScale /*[0..1]*/ ); |
| |
| void TessellateQuadDomain( float TessFactorUeq0, |
| float TessFactorVeq0, |
| float TessFactorUeq1, |
| float TessFactorVeq1, |
| float insideTessFactorScaleU /*[0..1]*/, |
| float insideTessFactorScaleV /*[0..1]*/ ); |
| |
| int GetPointCount() {return CHWTessellator::GetPointCount();}; |
| int GetIndexCount() {return CHWTessellator::GetIndexCount();} |
| |
| DOMAIN_POINT* GetPoints() {return CHWTessellator::GetPoints();} // Get CHLSLTessellator owned pointer to vertices (UV values). |
| // Pointer is fixed for lifetime of CHLSLTessellator object. |
| int* GetIndices() {return CHWTessellator::GetIndices();} // Get CHLSLTessellator owned pointer to vertex indices. |
| // Pointer is fixed for lifetime of CHLSLTessellator object. |
| |
| // Retrieve TessFactors actually used by the "hardware" |
| // This includes clamping to valid range, and more interestingly |
| // if integer or pow2 partitioning is being done, the rounded TessFactors can be retrieved. |
| // Getting the rounded TessFactors can be useful for geomorphing of displacement maps. |
| float GetIsoLineDensityTessFactor() {return m_LastComputedTessFactors[0];} |
| float GetIsoLineDetailTessFactor() {return m_LastComputedTessFactors[1];} |
| float GetTriUeq0TessFactor() {return m_LastComputedTessFactors[0];} |
| float GetTriVeq0TessFactor() {return m_LastComputedTessFactors[1];} |
| float GetTriWeq0TessFactor() {return m_LastComputedTessFactors[2];} |
| float GetTriInsideTessFactor() {return m_LastComputedTessFactors[3];} |
| float GetQuadUeq0TessFactor() {return m_LastComputedTessFactors[0];} |
| float GetQuadVeq0TessFactor() {return m_LastComputedTessFactors[1];} |
| float GetQuadUeq1TessFactor() {return m_LastComputedTessFactors[2];} |
| float GetQuadVeq1TessFactor() {return m_LastComputedTessFactors[3];} |
| float GetQuadInsideUTessFactor() {return m_LastComputedTessFactors[4];} |
| float GetQuadInsideVTessFactor() {return m_LastComputedTessFactors[5];} |
| float GetUnRoundedIsoLineDensityTessFactor() {return m_LastUnRoundedComputedTessFactors[0];} |
| float GetUnRoundedIsoLineDetailTessFactor() {return m_LastUnRoundedComputedTessFactors[1];} |
| float GetUnRoundedTriUeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[0];} |
| float GetUnRoundedTriVeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[1];} |
| float GetUnRoundedTriWeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[2];} |
| float GetUnRoundedTriInsideTessFactor() {return m_LastUnRoundedComputedTessFactors[3];} |
| float GetUnRoundedQuadUeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[0];} |
| float GetUnRoundedQuadVeq0TessFactor() {return m_LastUnRoundedComputedTessFactors[1];} |
| float GetUnRoundedQuadUeq1TessFactor() {return m_LastUnRoundedComputedTessFactors[2];} |
| float GetUnRoundedQuadVeq1TessFactor() {return m_LastUnRoundedComputedTessFactors[3];} |
| float GetUnRoundedQuadInsideUTessFactor() {return m_LastUnRoundedComputedTessFactors[4];} |
| float GetUnRoundedQuadInsideVTessFactor() {return m_LastUnRoundedComputedTessFactors[5];} |
| |
| CHLSLTessellator(); |
| //--------------------------------------------------------------------------------------------------------------------------------- |
| private: |
| TESSELLATOR_PARITY m_originalParity; // user chosen parity |
| TESSELLATOR_PARITY m_parity; // current parity: if allowing mix of even/odd during discrete |
| // tessellation, this can vary from the user defined parity |
| PIPE_TESSELLATOR_PARTITIONING m_originalPartitioning; // user chosen partitioning |
| PIPE_TESSELLATOR_PARTITIONING m_partitioning; // current partitioning. IsoLines overrides for line density |
| PIPE_TESSELLATOR_OUTPUT_PRIMITIVE m_outputPrimitive; |
| PIPE_TESSELLATOR_REDUCTION m_insideTessFactorReduction; |
| PIPE_TESSELLATOR_QUAD_REDUCTION_AXIS m_quadInsideTessFactorReductionAxis; |
| float m_LastComputedTessFactors[6]; // TessFactors used for last tessellation |
| float m_LastUnRoundedComputedTessFactors[6]; // TessFactors used for last tessellation (before they were rounded) |
| bool IntegerPartitioning() {return (m_partitioning == PIPE_TESSELLATOR_PARTITIONING_INTEGER) ? true : false;} |
| bool Pow2Partitioning() {return (m_partitioning == PIPE_TESSELLATOR_PARTITIONING_POW2)? true : false;} |
| void ClampTessFactor(float& TessFactor); |
| void RoundUpTessFactor(float& TessFactor); |
| void CleanupFloatTessFactor(float& input); // clamp float to [1.0f... +INF] (incl NaN->1.0f) |
| void ClampFloatTessFactorScale(float& input); // clamp float to [0.0f... +INF] (incl NaN->0.0f) |
| |
| // Tessellation parity control |
| bool Odd() {return (m_parity == TESSELLATOR_PARITY_ODD) ? true : false;} |
| void SetTessellationParity(TESSELLATOR_PARITY parity) {m_parity = parity;} |
| |
| // Tesselation Partitioning control |
| void RestorePartitioning() {m_partitioning = m_originalPartitioning;}; |
| void OverridePartitioning(PIPE_TESSELLATOR_PARTITIONING partitioning) {m_partitioning = partitioning;} //isoline uses this for density |
| |
| void IsoLineHLSLProcessTessFactors( float TessFactor_V_LineDensity, float TessFactor_U_LineDetail ); |
| void TriHLSLProcessTessFactors( float tessFactor_Ueq0, float TessFactor_Veq0, float TessFactor_Weq0, float insideTessFactor ); |
| void QuadHLSLProcessTessFactors( float TessFactor_Ueq0, float TessFactor_Veq0, float TessFactor_Ueq1, float TessFactor_Veq1, |
| float insideTessFactor_U, float insideTessFactor_V ); |
| |
| }; |
| |