mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 17:40:11 +01:00
gallium/auxiliary: add the microsoft tessellator and a pipe wrapper.
This adds the same tessellator code that swr uses, swr should move to using this copy, unfortunately that wasn't trivial on my first look. The p_tessellator wrapper wraps it in a form that is a useful interface for draw. Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3841>
This commit is contained in:
parent
bf16ff3172
commit
bd0188f9ea
6 changed files with 3419 additions and 0 deletions
|
|
@ -154,6 +154,10 @@ C_SOURCES := \
|
||||||
rtasm/rtasm_execmem.h \
|
rtasm/rtasm_execmem.h \
|
||||||
rtasm/rtasm_x86sse.c \
|
rtasm/rtasm_x86sse.c \
|
||||||
rtasm/rtasm_x86sse.h \
|
rtasm/rtasm_x86sse.h \
|
||||||
|
tessellator/p_tessellator.cpp \
|
||||||
|
tessellator/p_tessellator.h \
|
||||||
|
tessellator/tessellator.cpp \
|
||||||
|
tessellator/tessellator.hpp \
|
||||||
tgsi/tgsi_aa_point.c \
|
tgsi/tgsi_aa_point.c \
|
||||||
tgsi/tgsi_aa_point.h \
|
tgsi/tgsi_aa_point.h \
|
||||||
tgsi/tgsi_build.c \
|
tgsi/tgsi_build.c \
|
||||||
|
|
|
||||||
|
|
@ -419,6 +419,10 @@ if with_llvm
|
||||||
'draw/draw_llvm_sample.c',
|
'draw/draw_llvm_sample.c',
|
||||||
'draw/draw_pt_fetch_shade_pipeline_llvm.c',
|
'draw/draw_pt_fetch_shade_pipeline_llvm.c',
|
||||||
'draw/draw_vs_llvm.c',
|
'draw/draw_vs_llvm.c',
|
||||||
|
'tessellator/tessellator.cpp',
|
||||||
|
'tessellator/tessellator.hpp',
|
||||||
|
'tessellator/p_tessellator.cpp',
|
||||||
|
'tessellator/p_tessellator.h',
|
||||||
'nir/nir_to_tgsi_info.c',
|
'nir/nir_to_tgsi_info.c',
|
||||||
'nir/nir_to_tgsi_info.h',
|
'nir/nir_to_tgsi_info.h',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
166
src/gallium/auxiliary/tessellator/p_tessellator.cpp
Normal file
166
src/gallium/auxiliary/tessellator/p_tessellator.cpp
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2020 Red Hat.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "util/u_math.h"
|
||||||
|
#include "util/u_memory.h"
|
||||||
|
#include "pipe/p_defines.h"
|
||||||
|
#include "p_tessellator.h"
|
||||||
|
#include "tessellator.hpp"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
namespace pipe_tessellator_wrap
|
||||||
|
{
|
||||||
|
/// Wrapper class for the CHWTessellator reference tessellator from MSFT
|
||||||
|
/// This class will store data not originally stored in CHWTessellator
|
||||||
|
class pipe_ts : private CHWTessellator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef CHWTessellator SUPER;
|
||||||
|
enum pipe_prim_type prim_mode;
|
||||||
|
PIPE_ALIGN_VAR(32) float domain_points_u[MAX_POINT_COUNT];
|
||||||
|
PIPE_ALIGN_VAR(32) float domain_points_v[MAX_POINT_COUNT];
|
||||||
|
uint32_t num_domain_points;
|
||||||
|
PIPE_ALIGN_VAR(32) uint32_t indices[3][MAX_INDEX_COUNT / 3];
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Init(enum pipe_prim_type tes_prim_mode,
|
||||||
|
enum pipe_tess_spacing ts_spacing,
|
||||||
|
bool tes_vertex_order_cw, bool tes_point_mode)
|
||||||
|
{
|
||||||
|
static D3D11_TESSELLATOR_PARTITIONING CVT_TS_D3D_PARTITIONING[] = {
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, // PIPE_TESS_SPACING_ODD
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, // PIPE_TESS_SPACING_EVEN
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING_INTEGER, // PIPE_TESS_SPACING_EQUAL
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D11_TESSELLATOR_OUTPUT_PRIMITIVE out_prim;
|
||||||
|
if (tes_point_mode)
|
||||||
|
out_prim = D3D11_TESSELLATOR_OUTPUT_POINT;
|
||||||
|
else if (tes_prim_mode == PIPE_PRIM_LINES)
|
||||||
|
out_prim = D3D11_TESSELLATOR_OUTPUT_LINE;
|
||||||
|
else if (tes_vertex_order_cw)
|
||||||
|
out_prim = D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW;
|
||||||
|
else
|
||||||
|
out_prim = D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW;
|
||||||
|
|
||||||
|
SUPER::Init(CVT_TS_D3D_PARTITIONING[ts_spacing],
|
||||||
|
out_prim);
|
||||||
|
|
||||||
|
prim_mode = tes_prim_mode;
|
||||||
|
num_domain_points = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tessellate(const struct pipe_tessellation_factors *tess_factors,
|
||||||
|
struct pipe_tessellator_data *tess_data)
|
||||||
|
{
|
||||||
|
switch (prim_mode)
|
||||||
|
{
|
||||||
|
case PIPE_PRIM_QUADS:
|
||||||
|
SUPER::TessellateQuadDomain(
|
||||||
|
tess_factors->outer_tf[0],
|
||||||
|
tess_factors->outer_tf[1],
|
||||||
|
tess_factors->outer_tf[2],
|
||||||
|
tess_factors->outer_tf[3],
|
||||||
|
tess_factors->inner_tf[0],
|
||||||
|
tess_factors->inner_tf[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIPE_PRIM_TRIANGLES:
|
||||||
|
SUPER::TessellateTriDomain(
|
||||||
|
tess_factors->outer_tf[0],
|
||||||
|
tess_factors->outer_tf[1],
|
||||||
|
tess_factors->outer_tf[2],
|
||||||
|
tess_factors->inner_tf[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIPE_PRIM_LINES:
|
||||||
|
SUPER::TessellateIsoLineDomain(
|
||||||
|
tess_factors->outer_tf[0],
|
||||||
|
tess_factors->outer_tf[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_domain_points = (uint32_t)SUPER::GetPointCount();
|
||||||
|
|
||||||
|
DOMAIN_POINT *points = SUPER::GetPoints();
|
||||||
|
for (uint32_t i = 0; i < num_domain_points; i++) {
|
||||||
|
domain_points_u[i] = points[i].u;
|
||||||
|
domain_points_v[i] = points[i].v;
|
||||||
|
}
|
||||||
|
tess_data->num_domain_points = num_domain_points;
|
||||||
|
tess_data->domain_points_u = &domain_points_u[0];
|
||||||
|
tess_data->domain_points_v = &domain_points_v[0];
|
||||||
|
|
||||||
|
tess_data->num_indices = (uint32_t)SUPER::GetIndexCount();
|
||||||
|
|
||||||
|
tess_data->indices = (uint32_t*)SUPER::GetIndices();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace Tessellator
|
||||||
|
|
||||||
|
/* allocate tessellator */
|
||||||
|
struct pipe_tessellator *
|
||||||
|
p_tess_init(enum pipe_prim_type tes_prim_mode,
|
||||||
|
enum pipe_tess_spacing spacing,
|
||||||
|
bool tes_vertex_order_cw, bool tes_point_mode)
|
||||||
|
{
|
||||||
|
void *mem;
|
||||||
|
using pipe_tessellator_wrap::pipe_ts;
|
||||||
|
|
||||||
|
mem = align_malloc(sizeof(pipe_ts), 256);
|
||||||
|
|
||||||
|
pipe_ts* tessellator = new (mem) pipe_ts();
|
||||||
|
|
||||||
|
tessellator->Init(tes_prim_mode, spacing, tes_vertex_order_cw, tes_point_mode);
|
||||||
|
|
||||||
|
return (struct pipe_tessellator *)tessellator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destroy tessellator */
|
||||||
|
void p_tess_destroy(struct pipe_tessellator *pipe_tess)
|
||||||
|
{
|
||||||
|
using pipe_tessellator_wrap::pipe_ts;
|
||||||
|
pipe_ts *tessellator = (pipe_ts*)pipe_tess;
|
||||||
|
|
||||||
|
tessellator->~pipe_ts();
|
||||||
|
align_free(tessellator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* perform tessellation */
|
||||||
|
void p_tessellate(struct pipe_tessellator *pipe_tess,
|
||||||
|
const struct pipe_tessellation_factors *tess_factors,
|
||||||
|
struct pipe_tessellator_data *tess_data)
|
||||||
|
{
|
||||||
|
using pipe_tessellator_wrap::pipe_ts;
|
||||||
|
pipe_ts *tessellator = (pipe_ts*)pipe_tess;
|
||||||
|
|
||||||
|
tessellator->Tessellate(tess_factors, tess_data);
|
||||||
|
}
|
||||||
|
|
||||||
69
src/gallium/auxiliary/tessellator/p_tessellator.h
Normal file
69
src/gallium/auxiliary/tessellator/p_tessellator.h
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2020 Red Hat.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef PIPE_TESSELLATOR_H
|
||||||
|
#define PIPE_TESSELLATOR_H
|
||||||
|
|
||||||
|
#include "pipe/p_defines.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct pipe_tessellator;
|
||||||
|
struct pipe_tessellation_factors
|
||||||
|
{
|
||||||
|
float outer_tf[4];
|
||||||
|
float inner_tf[2];
|
||||||
|
float pad[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pipe_tessellator_data
|
||||||
|
{
|
||||||
|
uint32_t num_indices;
|
||||||
|
uint32_t num_domain_points;
|
||||||
|
|
||||||
|
uint32_t *indices;
|
||||||
|
float *domain_points_u;
|
||||||
|
float *domain_points_v;
|
||||||
|
// For Tri: domain_points_w[i] = 1.0f - domain_points_u[i] - domain_points_v[i]
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Allocate and initialize a new tessellation context
|
||||||
|
struct pipe_tessellator *p_tess_init(enum pipe_prim_type tes_prim_mode,
|
||||||
|
enum pipe_tess_spacing spacing,
|
||||||
|
bool tes_vertex_order_cw, bool tes_point_mode);
|
||||||
|
/// Destroy & de-allocate tessellation context
|
||||||
|
void p_tess_destroy(struct pipe_tessellator *pipe_ts);
|
||||||
|
|
||||||
|
|
||||||
|
/// Perform Tessellation
|
||||||
|
void p_tessellate(struct pipe_tessellator *pipe_ts,
|
||||||
|
const struct pipe_tessellation_factors *tess_factors,
|
||||||
|
struct pipe_tessellator_data *tess_data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
2705
src/gallium/auxiliary/tessellator/tessellator.cpp
Normal file
2705
src/gallium/auxiliary/tessellator/tessellator.cpp
Normal file
File diff suppressed because it is too large
Load diff
471
src/gallium/auxiliary/tessellator/tessellator.hpp
Normal file
471
src/gallium/auxiliary/tessellator/tessellator.hpp
Normal file
|
|
@ -0,0 +1,471 @@
|
||||||
|
/*
|
||||||
|
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 D3D11_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR 1
|
||||||
|
#define D3D11_TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR 63
|
||||||
|
#define D3D11_TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR 2
|
||||||
|
#define D3D11_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR 64
|
||||||
|
|
||||||
|
#define D3D11_TESSELLATOR_MIN_ISOLINE_DENSITY_TESSELLATION_FACTOR 1
|
||||||
|
#define D3D11_TESSELLATOR_MAX_ISOLINE_DENSITY_TESSELLATION_FACTOR 64
|
||||||
|
|
||||||
|
#define D3D11_TESSELLATOR_MAX_TESSELLATION_FACTOR 64 // max of even and odd tessFactors
|
||||||
|
|
||||||
|
#define MAX_POINT_COUNT ((D3D11_TESSELLATOR_MAX_TESSELLATION_FACTOR+1)*(D3D11_TESSELLATOR_MAX_TESSELLATION_FACTOR+1))
|
||||||
|
#define MAX_INDEX_COUNT (D3D11_TESSELLATOR_MAX_TESSELLATION_FACTOR*D3D11_TESSELLATOR_MAX_TESSELLATION_FACTOR*2*3)
|
||||||
|
|
||||||
|
//=================================================================================================================================
|
||||||
|
// Data types for the caller
|
||||||
|
//=================================================================================================================================
|
||||||
|
enum D3D11_TESSELLATOR_PARTITIONING
|
||||||
|
{
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING_INTEGER,
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING_POW2,
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD,
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN
|
||||||
|
};
|
||||||
|
|
||||||
|
enum D3D11_TESSELLATOR_REDUCTION
|
||||||
|
{
|
||||||
|
D3D11_TESSELLATOR_REDUCTION_MIN,
|
||||||
|
D3D11_TESSELLATOR_REDUCTION_MAX,
|
||||||
|
D3D11_TESSELLATOR_REDUCTION_AVERAGE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum D3D11_TESSELLATOR_QUAD_REDUCTION_AXIS
|
||||||
|
{
|
||||||
|
D3D11_TESSELLATOR_QUAD_REDUCTION_1_AXIS,
|
||||||
|
D3D11_TESSELLATOR_QUAD_REDUCTION_2_AXIS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum D3D11_TESSELLATOR_OUTPUT_PRIMITIVE
|
||||||
|
{
|
||||||
|
D3D11_TESSELLATOR_OUTPUT_POINT,
|
||||||
|
D3D11_TESSELLATOR_OUTPUT_LINE,
|
||||||
|
D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW,
|
||||||
|
D3D11_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( D3D11_TESSELLATOR_PARTITIONING partitioning,
|
||||||
|
D3D11_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.
|
||||||
|
|
||||||
|
#define ALLOW_XBOX_360_COMPARISON // Different vertex splitting order. This is NOT D3D11 behavior, just available here for comparison.
|
||||||
|
// Setting this define true just allows the XBox split style to be enabled via
|
||||||
|
// SetXBox360Mode() below, but by default this XBox360 mode still always starts off DISABLED.
|
||||||
|
// The XBox360 always splits from the center of an edge (D3D11 uses ruler function). Splitting
|
||||||
|
// from the center causes sliver triangles in transition areas, which cause numerous problems.
|
||||||
|
// Note the XBox360 only supports adaptive tessellation via fractional_even partitioning,
|
||||||
|
// though this #define lets you try the XBox vertex splitting order with any of the
|
||||||
|
// partitioning modes: even, odd, integer or pow2.
|
||||||
|
#ifdef ALLOW_XBOX_360_COMPARISON
|
||||||
|
void SetXBox360Mode(bool bXboxMode) {m_bXBox360Mode = bXboxMode;}
|
||||||
|
#endif
|
||||||
|
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 D3D11_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
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING m_originalPartitioning; // user chosen partitioning
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING m_partitioning; // current partitioning. IsoLines overrides for line density
|
||||||
|
D3D11_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;
|
||||||
|
#ifdef ALLOW_XBOX_360_COMPARISON
|
||||||
|
bool m_bXBox360Mode;
|
||||||
|
#endif
|
||||||
|
// 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 == D3D11_TESSELLATOR_PARTITIONING_INTEGER)||
|
||||||
|
(m_partitioning == D3D11_TESSELLATOR_PARTITIONING_POW2)) ? true : false;}
|
||||||
|
|
||||||
|
// Tesselation Partitioning control
|
||||||
|
void RestorePartitioning() {m_partitioning = m_originalPartitioning;};
|
||||||
|
void OverridePartitioning(D3D11_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: D3D11 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( D3D11_TESSELLATOR_PARTITIONING partitioning,
|
||||||
|
D3D11_TESSELLATOR_REDUCTION insideTessFactorReduction,
|
||||||
|
D3D11_TESSELLATOR_QUAD_REDUCTION_AXIS quadInsideTessFactorReductionAxis,
|
||||||
|
D3D11_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
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING m_originalPartitioning; // user chosen partitioning
|
||||||
|
D3D11_TESSELLATOR_PARTITIONING m_partitioning; // current partitioning. IsoLines overrides for line density
|
||||||
|
D3D11_TESSELLATOR_OUTPUT_PRIMITIVE m_outputPrimitive;
|
||||||
|
D3D11_TESSELLATOR_REDUCTION m_insideTessFactorReduction;
|
||||||
|
D3D11_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 == D3D11_TESSELLATOR_PARTITIONING_INTEGER) ? true : false;}
|
||||||
|
bool Pow2Partitioning() {return (m_partitioning == D3D11_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(D3D11_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 );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue