• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2020 Red Hat.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  **************************************************************************/
25 
26 #include "util/u_math.h"
27 #include "util/u_memory.h"
28 #include "pipe/p_defines.h"
29 #include "p_tessellator.h"
30 #include "tessellator.hpp"
31 
32 #include <new>
33 
34 namespace pipe_tessellator_wrap
35 {
36    /// Wrapper class for the CHWTessellator reference tessellator from MSFT
37    /// This class will store data not originally stored in CHWTessellator
38    class pipe_ts : private CHWTessellator
39    {
40    private:
41       typedef CHWTessellator SUPER;
42       enum pipe_prim_type    prim_mode;
43       PIPE_ALIGN_VAR(32) float     domain_points_u[MAX_POINT_COUNT];
44       PIPE_ALIGN_VAR(32) float     domain_points_v[MAX_POINT_COUNT];
45       uint32_t               num_domain_points;
46 
47    public:
Init(enum pipe_prim_type tes_prim_mode,enum pipe_tess_spacing ts_spacing,bool tes_vertex_order_cw,bool tes_point_mode)48       void Init(enum pipe_prim_type tes_prim_mode,
49                 enum pipe_tess_spacing ts_spacing,
50                 bool tes_vertex_order_cw, bool tes_point_mode)
51       {
52          static PIPE_TESSELLATOR_PARTITIONING CVT_TS_D3D_PARTITIONING[] = {
53                                                                             PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD,  // PIPE_TESS_SPACING_ODD
54                                                                             PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, // PIPE_TESS_SPACING_EVEN
55                                                                             PIPE_TESSELLATOR_PARTITIONING_INTEGER,         // PIPE_TESS_SPACING_EQUAL
56          };
57 
58          PIPE_TESSELLATOR_OUTPUT_PRIMITIVE out_prim;
59          if (tes_point_mode)
60             out_prim = PIPE_TESSELLATOR_OUTPUT_POINT;
61          else if (tes_prim_mode == PIPE_PRIM_LINES)
62             out_prim = PIPE_TESSELLATOR_OUTPUT_LINE;
63          else if (tes_vertex_order_cw)
64             out_prim = PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CW;
65          else
66             out_prim = PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CCW;
67 
68          SUPER::Init(CVT_TS_D3D_PARTITIONING[ts_spacing],
69                      out_prim);
70 
71          prim_mode          = tes_prim_mode;
72          num_domain_points = 0;
73       }
74 
Tessellate(const struct pipe_tessellation_factors * tess_factors,struct pipe_tessellator_data * tess_data)75       void Tessellate(const struct pipe_tessellation_factors *tess_factors,
76                       struct pipe_tessellator_data *tess_data)
77       {
78          switch (prim_mode)
79             {
80             case PIPE_PRIM_QUADS:
81                SUPER::TessellateQuadDomain(
82                                            tess_factors->outer_tf[0],
83                                            tess_factors->outer_tf[1],
84                                            tess_factors->outer_tf[2],
85                                            tess_factors->outer_tf[3],
86                                            tess_factors->inner_tf[0],
87                                            tess_factors->inner_tf[1]);
88                break;
89 
90             case PIPE_PRIM_TRIANGLES:
91                SUPER::TessellateTriDomain(
92                                           tess_factors->outer_tf[0],
93                                           tess_factors->outer_tf[1],
94                                           tess_factors->outer_tf[2],
95                                           tess_factors->inner_tf[0]);
96                break;
97 
98             case PIPE_PRIM_LINES:
99                SUPER::TessellateIsoLineDomain(
100                                               tess_factors->outer_tf[0],
101                                               tess_factors->outer_tf[1]);
102                break;
103 
104             default:
105                assert(0);
106                return;
107             }
108 
109          num_domain_points = (uint32_t)SUPER::GetPointCount();
110 
111          DOMAIN_POINT *points = SUPER::GetPoints();
112          for (uint32_t i = 0; i < num_domain_points; i++) {
113             domain_points_u[i] = points[i].u;
114             domain_points_v[i] = points[i].v;
115          }
116          tess_data->num_domain_points = num_domain_points;
117          tess_data->domain_points_u = &domain_points_u[0];
118          tess_data->domain_points_v = &domain_points_v[0];
119 
120          tess_data->num_indices = (uint32_t)SUPER::GetIndexCount();
121 
122          tess_data->indices = (uint32_t*)SUPER::GetIndices();
123       }
124    };
125 } // namespace Tessellator
126 
127 /* allocate tessellator */
128 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)129 p_tess_init(enum pipe_prim_type tes_prim_mode,
130             enum pipe_tess_spacing spacing,
131             bool tes_vertex_order_cw, bool tes_point_mode)
132 {
133    void *mem;
134    using pipe_tessellator_wrap::pipe_ts;
135 
136    mem = align_malloc(sizeof(pipe_ts), 256);
137 
138    pipe_ts* tessellator = new (mem) pipe_ts();
139 
140    tessellator->Init(tes_prim_mode, spacing, tes_vertex_order_cw, tes_point_mode);
141 
142    return (struct pipe_tessellator *)tessellator;
143 }
144 
145 /* destroy tessellator */
p_tess_destroy(struct pipe_tessellator * pipe_tess)146 void p_tess_destroy(struct pipe_tessellator *pipe_tess)
147 {
148    using pipe_tessellator_wrap::pipe_ts;
149    pipe_ts *tessellator = (pipe_ts*)pipe_tess;
150 
151    tessellator->~pipe_ts();
152    align_free(tessellator);
153 }
154 
155 /* perform tessellation */
p_tessellate(struct pipe_tessellator * pipe_tess,const struct pipe_tessellation_factors * tess_factors,struct pipe_tessellator_data * tess_data)156 void p_tessellate(struct pipe_tessellator *pipe_tess,
157                   const struct pipe_tessellation_factors *tess_factors,
158                   struct pipe_tessellator_data *tess_data)
159 {
160    using pipe_tessellator_wrap::pipe_ts;
161    pipe_ts *tessellator = (pipe_ts*)pipe_tess;
162 
163    tessellator->Tessellate(tess_factors, tess_data);
164 }
165 
166