• 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       PIPE_ALIGN_VAR(32) uint32_t  indices[3][MAX_INDEX_COUNT / 3];
47 
48    public:
Init(enum pipe_prim_type tes_prim_mode,enum pipe_tess_spacing ts_spacing,bool tes_vertex_order_cw,bool tes_point_mode)49       void Init(enum pipe_prim_type tes_prim_mode,
50                 enum pipe_tess_spacing ts_spacing,
51                 bool tes_vertex_order_cw, bool tes_point_mode)
52       {
53          static D3D11_TESSELLATOR_PARTITIONING CVT_TS_D3D_PARTITIONING[] = {
54                                                                             D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD,  // PIPE_TESS_SPACING_ODD
55                                                                             D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, // PIPE_TESS_SPACING_EVEN
56                                                                             D3D11_TESSELLATOR_PARTITIONING_INTEGER,         // PIPE_TESS_SPACING_EQUAL
57          };
58 
59          D3D11_TESSELLATOR_OUTPUT_PRIMITIVE out_prim;
60          if (tes_point_mode)
61             out_prim = D3D11_TESSELLATOR_OUTPUT_POINT;
62          else if (tes_prim_mode == PIPE_PRIM_LINES)
63             out_prim = D3D11_TESSELLATOR_OUTPUT_LINE;
64          else if (tes_vertex_order_cw)
65             out_prim = D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW;
66          else
67             out_prim = D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW;
68 
69          SUPER::Init(CVT_TS_D3D_PARTITIONING[ts_spacing],
70                      out_prim);
71 
72          prim_mode          = tes_prim_mode;
73          num_domain_points = 0;
74       }
75 
Tessellate(const struct pipe_tessellation_factors * tess_factors,struct pipe_tessellator_data * tess_data)76       void Tessellate(const struct pipe_tessellation_factors *tess_factors,
77                       struct pipe_tessellator_data *tess_data)
78       {
79          switch (prim_mode)
80             {
81             case PIPE_PRIM_QUADS:
82                SUPER::TessellateQuadDomain(
83                                            tess_factors->outer_tf[0],
84                                            tess_factors->outer_tf[1],
85                                            tess_factors->outer_tf[2],
86                                            tess_factors->outer_tf[3],
87                                            tess_factors->inner_tf[0],
88                                            tess_factors->inner_tf[1]);
89                break;
90 
91             case PIPE_PRIM_TRIANGLES:
92                SUPER::TessellateTriDomain(
93                                           tess_factors->outer_tf[0],
94                                           tess_factors->outer_tf[1],
95                                           tess_factors->outer_tf[2],
96                                           tess_factors->inner_tf[0]);
97                break;
98 
99             case PIPE_PRIM_LINES:
100                SUPER::TessellateIsoLineDomain(
101                                               tess_factors->outer_tf[0],
102                                               tess_factors->outer_tf[1]);
103                break;
104 
105             default:
106                assert(0);
107                return;
108             }
109 
110          num_domain_points = (uint32_t)SUPER::GetPointCount();
111 
112          DOMAIN_POINT *points = SUPER::GetPoints();
113          for (uint32_t i = 0; i < num_domain_points; i++) {
114             domain_points_u[i] = points[i].u;
115             domain_points_v[i] = points[i].v;
116          }
117          tess_data->num_domain_points = num_domain_points;
118          tess_data->domain_points_u = &domain_points_u[0];
119          tess_data->domain_points_v = &domain_points_v[0];
120 
121          tess_data->num_indices = (uint32_t)SUPER::GetIndexCount();
122 
123          tess_data->indices = (uint32_t*)SUPER::GetIndices();
124       }
125    };
126 } // namespace Tessellator
127 
128 /* allocate tessellator */
129 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)130 p_tess_init(enum pipe_prim_type tes_prim_mode,
131             enum pipe_tess_spacing spacing,
132             bool tes_vertex_order_cw, bool tes_point_mode)
133 {
134    void *mem;
135    using pipe_tessellator_wrap::pipe_ts;
136 
137    mem = align_malloc(sizeof(pipe_ts), 256);
138 
139    pipe_ts* tessellator = new (mem) pipe_ts();
140 
141    tessellator->Init(tes_prim_mode, spacing, tes_vertex_order_cw, tes_point_mode);
142 
143    return (struct pipe_tessellator *)tessellator;
144 }
145 
146 /* destroy tessellator */
p_tess_destroy(struct pipe_tessellator * pipe_tess)147 void p_tess_destroy(struct pipe_tessellator *pipe_tess)
148 {
149    using pipe_tessellator_wrap::pipe_ts;
150    pipe_ts *tessellator = (pipe_ts*)pipe_tess;
151 
152    tessellator->~pipe_ts();
153    align_free(tessellator);
154 }
155 
156 /* perform tessellation */
p_tessellate(struct pipe_tessellator * pipe_tess,const struct pipe_tessellation_factors * tess_factors,struct pipe_tessellator_data * tess_data)157 void p_tessellate(struct pipe_tessellator *pipe_tess,
158                   const struct pipe_tessellation_factors *tess_factors,
159                   struct pipe_tessellator_data *tess_data)
160 {
161    using pipe_tessellator_wrap::pipe_ts;
162    pipe_ts *tessellator = (pipe_ts*)pipe_tess;
163 
164    tessellator->Tessellate(tess_factors, tess_data);
165 }
166 
167