• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**********************************************************
2  * Copyright 2018-2020 VMware, Inc.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  **********************************************************/
25 
26 #include "pipe/p_context.h"
27 #include "util/u_memory.h"
28 #include "tgsi/tgsi_parse.h"
29 
30 #include "svga_context.h"
31 #include "svga_shader.h"
32 
33 static void
svga_set_tess_state(struct pipe_context * pipe,const float default_outer_level[4],const float default_inner_level[2])34 svga_set_tess_state(struct pipe_context *pipe,
35                     const float default_outer_level[4],
36                     const float default_inner_level[2])
37 {
38    struct svga_context *svga = svga_context(pipe);
39    unsigned i;
40 
41    for (i = 0; i < 4; i++) {
42       svga->curr.default_tesslevels[i] = default_outer_level[i];
43    }
44    for (i = 0; i < 2; i++) {
45       svga->curr.default_tesslevels[i + 4] = default_inner_level[i];
46    }
47 }
48 
49 
50 static void *
svga_create_tcs_state(struct pipe_context * pipe,const struct pipe_shader_state * templ)51 svga_create_tcs_state(struct pipe_context *pipe,
52                       const struct pipe_shader_state *templ)
53 {
54    struct svga_context *svga = svga_context(pipe);
55    struct svga_tcs_shader *tcs;
56 
57    tcs = CALLOC_STRUCT(svga_tcs_shader);
58    if (!tcs)
59       return NULL;
60 
61    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETCS);
62 
63    tcs->base.tokens = tgsi_dup_tokens(templ->tokens);
64 
65    /* Collect basic info that we'll need later:
66     */
67    tgsi_scan_shader(tcs->base.tokens, &tcs->base.info);
68 
69    tcs->base.id = svga->debug.shader_id++;
70 
71    tcs->generic_outputs = svga_get_generic_outputs_mask(&tcs->base.info);
72 
73    SVGA_STATS_TIME_POP(svga_sws(svga));
74    return tcs;
75 }
76 
77 
78 static void
svga_bind_tcs_state(struct pipe_context * pipe,void * shader)79 svga_bind_tcs_state(struct pipe_context *pipe, void *shader)
80 {
81    struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader;
82    struct svga_context *svga = svga_context(pipe);
83 
84    if (tcs == svga->curr.tcs)
85       return;
86 
87    svga->curr.tcs = tcs;
88    svga->dirty |= SVGA_NEW_TCS;
89 }
90 
91 
92 static void
svga_delete_tcs_state(struct pipe_context * pipe,void * shader)93 svga_delete_tcs_state(struct pipe_context *pipe, void *shader)
94 {
95    struct svga_context *svga = svga_context(pipe);
96    struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader;
97    struct svga_tcs_shader *next_tcs;
98    struct svga_shader_variant *variant, *tmp;
99 
100    svga_hwtnl_flush_retry(svga);
101 
102    assert(tcs->base.parent == NULL);
103 
104    while (tcs) {
105       next_tcs = (struct svga_tcs_shader *)tcs->base.next;
106       for (variant = tcs->base.variants; variant; variant = tmp) {
107          tmp = variant->next;
108 
109          /* Check if deleting currently bound shader */
110          if (variant == svga->state.hw_draw.tcs) {
111             SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, NULL));
112             svga->state.hw_draw.tcs = NULL;
113          }
114 
115          svga_destroy_shader_variant(svga, variant);
116       }
117 
118       FREE((void *)tcs->base.tokens);
119       FREE(tcs);
120       tcs = next_tcs;
121    }
122 }
123 
124 
125 void
svga_cleanup_tcs_state(struct svga_context * svga)126 svga_cleanup_tcs_state(struct svga_context *svga)
127 {
128    if (svga->tcs.passthrough_tcs) {
129       svga_delete_tcs_state(&svga->pipe, svga->tcs.passthrough_tcs);
130    }
131 }
132 
133 
134 static void *
svga_create_tes_state(struct pipe_context * pipe,const struct pipe_shader_state * templ)135 svga_create_tes_state(struct pipe_context *pipe,
136                       const struct pipe_shader_state *templ)
137 {
138    struct svga_context *svga = svga_context(pipe);
139    struct svga_tes_shader *tes;
140 
141    tes = CALLOC_STRUCT(svga_tes_shader);
142    if (!tes)
143       return NULL;
144 
145    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETES);
146 
147    tes->base.tokens = tgsi_dup_tokens(templ->tokens);
148 
149    /* Collect basic info that we'll need later:
150     */
151    tgsi_scan_shader(tes->base.tokens, &tes->base.info);
152 
153    tes->base.id = svga->debug.shader_id++;
154 
155    tes->generic_inputs = svga_get_generic_inputs_mask(&tes->base.info);
156 
157    SVGA_STATS_TIME_POP(svga_sws(svga));
158    return tes;
159 }
160 
161 
162 static void
svga_bind_tes_state(struct pipe_context * pipe,void * shader)163 svga_bind_tes_state(struct pipe_context *pipe, void *shader)
164 {
165    struct svga_tes_shader *tes = (struct svga_tes_shader *) shader;
166    struct svga_context *svga = svga_context(pipe);
167 
168    if (tes == svga->curr.tes)
169       return;
170 
171    svga->curr.tes = tes;
172    svga->dirty |= SVGA_NEW_TES;
173 }
174 
175 
176 static void
svga_delete_tes_state(struct pipe_context * pipe,void * shader)177 svga_delete_tes_state(struct pipe_context *pipe, void *shader)
178 {
179    struct svga_context *svga = svga_context(pipe);
180    struct svga_tes_shader *tes = (struct svga_tes_shader *) shader;
181    struct svga_tes_shader *next_tes;
182    struct svga_shader_variant *variant, *tmp;
183 
184    svga_hwtnl_flush_retry(svga);
185 
186    assert(tes->base.parent == NULL);
187 
188    while (tes) {
189       next_tes = (struct svga_tes_shader *)tes->base.next;
190       for (variant = tes->base.variants; variant; variant = tmp) {
191          tmp = variant->next;
192 
193          /* Check if deleting currently bound shader */
194          if (variant == svga->state.hw_draw.tes) {
195             SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, NULL));
196             svga->state.hw_draw.tes = NULL;
197          }
198 
199          svga_destroy_shader_variant(svga, variant);
200       }
201 
202       FREE((void *)tes->base.tokens);
203       FREE(tes);
204       tes = next_tes;
205    }
206 }
207 
208 
209 void
svga_init_ts_functions(struct svga_context * svga)210 svga_init_ts_functions(struct svga_context *svga)
211 {
212    svga->pipe.set_tess_state = svga_set_tess_state;
213    svga->pipe.create_tcs_state = svga_create_tcs_state;
214    svga->pipe.bind_tcs_state = svga_bind_tcs_state;
215    svga->pipe.delete_tcs_state = svga_delete_tcs_state;
216    svga->pipe.create_tes_state = svga_create_tes_state;
217    svga->pipe.bind_tes_state = svga_bind_tes_state;
218    svga->pipe.delete_tes_state = svga_delete_tes_state;
219 }
220