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 33static void 34svga_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 50static void 51svga_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices) 52{ 53 struct svga_context *svga = svga_context(pipe); 54 55 svga->patch_vertices = patch_vertices; 56} 57 58 59static void * 60svga_create_tcs_state(struct pipe_context *pipe, 61 const struct pipe_shader_state *templ) 62{ 63 struct svga_context *svga = svga_context(pipe); 64 struct svga_tcs_shader *tcs; 65 66 tcs = CALLOC_STRUCT(svga_tcs_shader); 67 if (!tcs) 68 return NULL; 69 70 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETCS); 71 72 tcs->base.tokens = tgsi_dup_tokens(templ->tokens); 73 74 /* Collect basic info that we'll need later: 75 */ 76 tgsi_scan_shader(tcs->base.tokens, &tcs->base.info); 77 78 tcs->base.id = svga->debug.shader_id++; 79 80 tcs->generic_outputs = svga_get_generic_outputs_mask(&tcs->base.info); 81 82 SVGA_STATS_TIME_POP(svga_sws(svga)); 83 return tcs; 84} 85 86 87static void 88svga_bind_tcs_state(struct pipe_context *pipe, void *shader) 89{ 90 struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader; 91 struct svga_context *svga = svga_context(pipe); 92 93 if (tcs == svga->curr.tcs) 94 return; 95 96 svga->curr.tcs = tcs; 97 svga->dirty |= SVGA_NEW_TCS; 98} 99 100 101static void 102svga_delete_tcs_state(struct pipe_context *pipe, void *shader) 103{ 104 struct svga_context *svga = svga_context(pipe); 105 struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader; 106 struct svga_tcs_shader *next_tcs; 107 struct svga_shader_variant *variant, *tmp; 108 109 svga_hwtnl_flush_retry(svga); 110 111 assert(tcs->base.parent == NULL); 112 113 while (tcs) { 114 next_tcs = (struct svga_tcs_shader *)tcs->base.next; 115 for (variant = tcs->base.variants; variant; variant = tmp) { 116 tmp = variant->next; 117 118 /* Check if deleting currently bound shader */ 119 if (variant == svga->state.hw_draw.tcs) { 120 SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, NULL)); 121 svga->state.hw_draw.tcs = NULL; 122 } 123 124 svga_destroy_shader_variant(svga, variant); 125 } 126 127 FREE((void *)tcs->base.tokens); 128 FREE(tcs); 129 tcs = next_tcs; 130 } 131} 132 133 134void 135svga_cleanup_tcs_state(struct svga_context *svga) 136{ 137 if (svga->tcs.passthrough_tcs) { 138 svga_delete_tcs_state(&svga->pipe, svga->tcs.passthrough_tcs); 139 } 140} 141 142 143static void * 144svga_create_tes_state(struct pipe_context *pipe, 145 const struct pipe_shader_state *templ) 146{ 147 struct svga_context *svga = svga_context(pipe); 148 struct svga_tes_shader *tes; 149 150 tes = CALLOC_STRUCT(svga_tes_shader); 151 if (!tes) 152 return NULL; 153 154 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETES); 155 156 tes->base.tokens = tgsi_dup_tokens(templ->tokens); 157 158 /* Collect basic info that we'll need later: 159 */ 160 tgsi_scan_shader(tes->base.tokens, &tes->base.info); 161 162 tes->base.id = svga->debug.shader_id++; 163 164 tes->generic_inputs = svga_get_generic_inputs_mask(&tes->base.info); 165 166 SVGA_STATS_TIME_POP(svga_sws(svga)); 167 return tes; 168} 169 170 171static void 172svga_bind_tes_state(struct pipe_context *pipe, void *shader) 173{ 174 struct svga_tes_shader *tes = (struct svga_tes_shader *) shader; 175 struct svga_context *svga = svga_context(pipe); 176 177 if (tes == svga->curr.tes) 178 return; 179 180 svga->curr.tes = tes; 181 svga->dirty |= SVGA_NEW_TES; 182} 183 184 185static void 186svga_delete_tes_state(struct pipe_context *pipe, void *shader) 187{ 188 struct svga_context *svga = svga_context(pipe); 189 struct svga_tes_shader *tes = (struct svga_tes_shader *) shader; 190 struct svga_tes_shader *next_tes; 191 struct svga_shader_variant *variant, *tmp; 192 193 svga_hwtnl_flush_retry(svga); 194 195 assert(tes->base.parent == NULL); 196 197 while (tes) { 198 next_tes = (struct svga_tes_shader *)tes->base.next; 199 for (variant = tes->base.variants; variant; variant = tmp) { 200 tmp = variant->next; 201 202 /* Check if deleting currently bound shader */ 203 if (variant == svga->state.hw_draw.tes) { 204 SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, NULL)); 205 svga->state.hw_draw.tes = NULL; 206 } 207 208 svga_destroy_shader_variant(svga, variant); 209 } 210 211 FREE((void *)tes->base.tokens); 212 FREE(tes); 213 tes = next_tes; 214 } 215} 216 217 218void 219svga_init_ts_functions(struct svga_context *svga) 220{ 221 svga->pipe.set_tess_state = svga_set_tess_state; 222 svga->pipe.set_patch_vertices = svga_set_patch_vertices; 223 svga->pipe.create_tcs_state = svga_create_tcs_state; 224 svga->pipe.bind_tcs_state = svga_bind_tcs_state; 225 svga->pipe.delete_tcs_state = svga_delete_tcs_state; 226 svga->pipe.create_tes_state = svga_create_tes_state; 227 svga->pipe.bind_tes_state = svga_bind_tes_state; 228 svga->pipe.delete_tes_state = svga_delete_tes_state; 229} 230