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