1/********************************************************** 2 * Copyright 2018-2022 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 "nir/nir_to_tgsi.h" 27#include "pipe/p_context.h" 28#include "util/u_memory.h" 29#include "tgsi/tgsi_parse.h" 30 31#include "svga_context.h" 32#include "svga_shader.h" 33 34static void 35svga_set_tess_state(struct pipe_context *pipe, 36 const float default_outer_level[4], 37 const float default_inner_level[2]) 38{ 39 struct svga_context *svga = svga_context(pipe); 40 unsigned i; 41 42 for (i = 0; i < 4; i++) { 43 svga->curr.default_tesslevels[i] = default_outer_level[i]; 44 } 45 for (i = 0; i < 2; i++) { 46 svga->curr.default_tesslevels[i + 4] = default_inner_level[i]; 47 } 48} 49 50 51static void 52svga_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices) 53{ 54 struct svga_context *svga = svga_context(pipe); 55 56 svga->patch_vertices = patch_vertices; 57} 58 59 60static void * 61svga_create_tcs_state(struct pipe_context *pipe, 62 const struct pipe_shader_state *templ) 63{ 64 struct svga_context *svga = svga_context(pipe); 65 struct svga_tcs_shader *tcs; 66 67 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETCS); 68 69 tcs = (struct svga_tcs_shader *) 70 svga_create_shader(pipe, templ, PIPE_SHADER_TESS_CTRL, 71 sizeof(struct svga_tcs_shader)); 72 if (!tcs) 73 goto done; 74 75done: 76 SVGA_STATS_TIME_POP(svga_sws(svga)); 77 (void) svga; /* silence unused var warning */ 78 79 return tcs; 80} 81 82 83static void 84svga_bind_tcs_state(struct pipe_context *pipe, void *shader) 85{ 86 struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader; 87 struct svga_context *svga = svga_context(pipe); 88 89 if (tcs == svga->curr.tcs) 90 return; 91 92 svga->curr.tcs = tcs; 93 svga->dirty |= SVGA_NEW_TCS; 94} 95 96 97static void 98svga_delete_tcs_state(struct pipe_context *pipe, void *shader) 99{ 100 struct svga_context *svga = svga_context(pipe); 101 struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader; 102 struct svga_tcs_shader *next_tcs; 103 struct svga_shader_variant *variant, *tmp; 104 105 svga_hwtnl_flush_retry(svga); 106 107 assert(tcs->base.parent == NULL); 108 109 while (tcs) { 110 next_tcs = (struct svga_tcs_shader *)tcs->base.next; 111 for (variant = tcs->base.variants; variant; variant = tmp) { 112 tmp = variant->next; 113 114 /* Check if deleting currently bound shader */ 115 if (variant == svga->state.hw_draw.tcs) { 116 SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, NULL)); 117 svga->state.hw_draw.tcs = NULL; 118 } 119 120 svga_destroy_shader_variant(svga, variant); 121 } 122 123 FREE((void *)tcs->base.tokens); 124 FREE(tcs); 125 tcs = next_tcs; 126 } 127} 128 129 130void 131svga_cleanup_tcs_state(struct svga_context *svga) 132{ 133 if (svga->tcs.passthrough_tcs) { 134 svga_delete_tcs_state(&svga->pipe, svga->tcs.passthrough_tcs); 135 } 136} 137 138 139static void * 140svga_create_tes_state(struct pipe_context *pipe, 141 const struct pipe_shader_state *templ) 142{ 143 struct svga_context *svga = svga_context(pipe); 144 struct svga_tes_shader *tes; 145 146 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETES); 147 148 tes = (struct svga_tes_shader *) 149 svga_create_shader(pipe, templ, PIPE_SHADER_TESS_EVAL, 150 sizeof(struct svga_tes_shader)); 151 152 if (!tes) 153 goto done; 154 155done: 156 SVGA_STATS_TIME_POP(svga_sws(svga)); 157 (void) svga; /* silence unused var warning */ 158 159 return tes; 160} 161 162 163static void 164svga_bind_tes_state(struct pipe_context *pipe, void *shader) 165{ 166 struct svga_tes_shader *tes = (struct svga_tes_shader *) shader; 167 struct svga_context *svga = svga_context(pipe); 168 169 if (tes == svga->curr.tes) 170 return; 171 172 svga->curr.tes = tes; 173 svga->dirty |= SVGA_NEW_TES; 174} 175 176 177static void 178svga_delete_tes_state(struct pipe_context *pipe, void *shader) 179{ 180 struct svga_context *svga = svga_context(pipe); 181 struct svga_tes_shader *tes = (struct svga_tes_shader *) shader; 182 struct svga_tes_shader *next_tes; 183 struct svga_shader_variant *variant, *tmp; 184 185 svga_hwtnl_flush_retry(svga); 186 187 assert(tes->base.parent == NULL); 188 189 while (tes) { 190 next_tes = (struct svga_tes_shader *)tes->base.next; 191 for (variant = tes->base.variants; variant; variant = tmp) { 192 tmp = variant->next; 193 194 /* Check if deleting currently bound shader */ 195 if (variant == svga->state.hw_draw.tes) { 196 SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, NULL)); 197 svga->state.hw_draw.tes = NULL; 198 } 199 200 svga_destroy_shader_variant(svga, variant); 201 } 202 203 FREE((void *)tes->base.tokens); 204 FREE(tes); 205 tes = next_tes; 206 } 207} 208 209 210void 211svga_init_ts_functions(struct svga_context *svga) 212{ 213 svga->pipe.set_tess_state = svga_set_tess_state; 214 svga->pipe.set_patch_vertices = svga_set_patch_vertices; 215 svga->pipe.create_tcs_state = svga_create_tcs_state; 216 svga->pipe.bind_tcs_state = svga_bind_tcs_state; 217 svga->pipe.delete_tcs_state = svga_delete_tcs_state; 218 svga->pipe.create_tes_state = svga_create_tes_state; 219 svga->pipe.bind_tes_state = svga_bind_tes_state; 220 svga->pipe.delete_tes_state = svga_delete_tes_state; 221} 222