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 "util/u_inlines.h" 27bf215546Sopenharmony_ci#include "util/u_memory.h" 28bf215546Sopenharmony_ci#include "util/u_simple_shaders.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "svga_context.h" 31bf215546Sopenharmony_ci#include "svga_cmd.h" 32bf215546Sopenharmony_ci#include "svga_tgsi.h" 33bf215546Sopenharmony_ci#include "svga_shader.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistatic void 37bf215546Sopenharmony_cimake_tcs_key(struct svga_context *svga, struct svga_compile_key *key) 38bf215546Sopenharmony_ci{ 39bf215546Sopenharmony_ci struct svga_tcs_shader *tcs = svga->curr.tcs; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci memset(key, 0, sizeof *key); 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci /* 44bf215546Sopenharmony_ci * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER 45bf215546Sopenharmony_ci */ 46bf215546Sopenharmony_ci svga_init_shader_key_common(svga, PIPE_SHADER_TESS_CTRL, &tcs->base, key); 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci /* SVGA_NEW_TCS_PARAM */ 49bf215546Sopenharmony_ci key->tcs.vertices_per_patch = svga->curr.vertices_per_patch; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci /* The tessellator parameters come from the layout section in the 52bf215546Sopenharmony_ci * tessellation evaluation shader. Get these parameters from the 53bf215546Sopenharmony_ci * current tessellation evaluation shader variant. 54bf215546Sopenharmony_ci * Note: this requires the tessellation evaluation shader to be 55bf215546Sopenharmony_ci * compiled first. 56bf215546Sopenharmony_ci */ 57bf215546Sopenharmony_ci struct svga_tes_variant *tes = svga_tes_variant(svga->state.hw_draw.tes); 58bf215546Sopenharmony_ci key->tcs.prim_mode = tes->prim_mode; 59bf215546Sopenharmony_ci key->tcs.spacing = tes->spacing; 60bf215546Sopenharmony_ci key->tcs.vertices_order_cw = tes->vertices_order_cw; 61bf215546Sopenharmony_ci key->tcs.point_mode = tes->point_mode; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci /* The number of control point output from tcs is determined by the 64bf215546Sopenharmony_ci * number of control point input expected in tes. If tes does not expect 65bf215546Sopenharmony_ci * any control point input, then vertices_per_patch in the tes key will 66bf215546Sopenharmony_ci * be 0, otherwise it will contain the number of vertices out as specified 67bf215546Sopenharmony_ci * in the tcs property. 68bf215546Sopenharmony_ci */ 69bf215546Sopenharmony_ci key->tcs.vertices_out = tes->base.key.tes.vertices_per_patch; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci if (svga->tcs.passthrough) 72bf215546Sopenharmony_ci key->tcs.passthrough = 1; 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci /* tcs is always followed by tes */ 77bf215546Sopenharmony_ci key->last_vertex_stage = 0; 78bf215546Sopenharmony_ci} 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_cistatic enum pipe_error 82bf215546Sopenharmony_ciemit_hw_tcs(struct svga_context *svga, uint64_t dirty) 83bf215546Sopenharmony_ci{ 84bf215546Sopenharmony_ci struct svga_shader_variant *variant; 85bf215546Sopenharmony_ci struct svga_tcs_shader *tcs = svga->curr.tcs; 86bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 87bf215546Sopenharmony_ci struct svga_compile_key key; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci assert(svga_have_sm5(svga)); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITTCS); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci if (!tcs) { 94bf215546Sopenharmony_ci /* If there is no active tcs, then there should not be 95bf215546Sopenharmony_ci * active tes either 96bf215546Sopenharmony_ci */ 97bf215546Sopenharmony_ci assert(!svga->curr.tes); 98bf215546Sopenharmony_ci if (svga->state.hw_draw.tcs != NULL) { 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci /** The previous tessellation control shader is made inactive. 101bf215546Sopenharmony_ci * Needs to unbind the tessellation control shader. 102bf215546Sopenharmony_ci */ 103bf215546Sopenharmony_ci ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, NULL); 104bf215546Sopenharmony_ci if (ret != PIPE_OK) 105bf215546Sopenharmony_ci goto done; 106bf215546Sopenharmony_ci svga->state.hw_draw.tcs = NULL; 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci goto done; 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci make_tcs_key(svga, &key); 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci /* See if we already have a TCS variant that matches the key */ 114bf215546Sopenharmony_ci variant = svga_search_shader_key(&tcs->base, &key); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci if (!variant) { 117bf215546Sopenharmony_ci ret = svga_compile_shader(svga, &tcs->base, &key, &variant); 118bf215546Sopenharmony_ci if (ret != PIPE_OK) 119bf215546Sopenharmony_ci goto done; 120bf215546Sopenharmony_ci } 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci if (variant != svga->state.hw_draw.tcs) { 123bf215546Sopenharmony_ci /* Bind the new variant */ 124bf215546Sopenharmony_ci ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, variant); 125bf215546Sopenharmony_ci if (ret != PIPE_OK) 126bf215546Sopenharmony_ci goto done; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci svga->rebind.flags.tcs = FALSE; 129bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_TCS_VARIANT; 130bf215546Sopenharmony_ci svga->state.hw_draw.tcs = variant; 131bf215546Sopenharmony_ci } 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_cidone: 134bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 135bf215546Sopenharmony_ci return ret; 136bf215546Sopenharmony_ci} 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tcs = 140bf215546Sopenharmony_ci{ 141bf215546Sopenharmony_ci "tessellation control shader (hwtnl)", 142bf215546Sopenharmony_ci (SVGA_NEW_VS | 143bf215546Sopenharmony_ci SVGA_NEW_TCS | 144bf215546Sopenharmony_ci SVGA_NEW_TES | 145bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_BINDING | 146bf215546Sopenharmony_ci SVGA_NEW_SAMPLER | 147bf215546Sopenharmony_ci SVGA_NEW_RAST | 148bf215546Sopenharmony_ci SVGA_NEW_TCS_RAW_BUFFER), 149bf215546Sopenharmony_ci emit_hw_tcs 150bf215546Sopenharmony_ci}; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_cistatic void 154bf215546Sopenharmony_cimake_tes_key(struct svga_context *svga, struct svga_compile_key *key) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci struct svga_tes_shader *tes = svga->curr.tes; 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci memset(key, 0, sizeof *key); 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci /* 161bf215546Sopenharmony_ci * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER 162bf215546Sopenharmony_ci */ 163bf215546Sopenharmony_ci svga_init_shader_key_common(svga, PIPE_SHADER_TESS_EVAL, &tes->base, key); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci assert(svga->curr.tcs); 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci key->tes.vertices_per_patch = tes->base.info.tes.reads_control_point ? 168bf215546Sopenharmony_ci svga->curr.tcs->base.info.tcs.vertices_out : 0; 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci key->tes.need_prescale = svga->state.hw_clear.prescale[0].enabled && 171bf215546Sopenharmony_ci (svga->curr.gs == NULL); 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci /* tcs emits tessellation factors as extra outputs. 174bf215546Sopenharmony_ci * Since tes depends on them, save the tessFactor output index 175bf215546Sopenharmony_ci * from tcs in the tes compile key, so that if a different 176bf215546Sopenharmony_ci * tcs is bound and if the tessFactor index is different, 177bf215546Sopenharmony_ci * a different tes variant will be generated. 178bf215546Sopenharmony_ci */ 179bf215546Sopenharmony_ci key->tes.tessfactor_index = svga->curr.tcs->base.info.num_outputs; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci /* This is the last vertex stage if there is no geometry shader. */ 184bf215546Sopenharmony_ci key->last_vertex_stage = !svga->curr.gs; 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci key->tes.need_tessinner = svga->curr.tcs->base.info.tcs.writes_tess_factor; 187bf215546Sopenharmony_ci key->tes.need_tessouter = svga->curr.tcs->base.info.tcs.writes_tess_factor; 188bf215546Sopenharmony_ci} 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_cistatic void 192bf215546Sopenharmony_ciget_passthrough_tcs(struct svga_context *svga) 193bf215546Sopenharmony_ci{ 194bf215546Sopenharmony_ci if (svga->tcs.passthrough_tcs && 195bf215546Sopenharmony_ci svga->tcs.vs == svga->curr.vs && 196bf215546Sopenharmony_ci svga->tcs.tes == svga->curr.tes && 197bf215546Sopenharmony_ci svga->tcs.vertices_per_patch == svga->curr.vertices_per_patch) { 198bf215546Sopenharmony_ci svga->pipe.bind_tcs_state(&svga->pipe, 199bf215546Sopenharmony_ci svga->tcs.passthrough_tcs); 200bf215546Sopenharmony_ci } 201bf215546Sopenharmony_ci else { 202bf215546Sopenharmony_ci struct svga_tcs_shader *new_tcs; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci /* delete older passthrough shader*/ 205bf215546Sopenharmony_ci if (svga->tcs.passthrough_tcs) { 206bf215546Sopenharmony_ci svga->pipe.delete_tcs_state(&svga->pipe, 207bf215546Sopenharmony_ci svga->tcs.passthrough_tcs); 208bf215546Sopenharmony_ci } 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci new_tcs = (struct svga_tcs_shader *) 211bf215546Sopenharmony_ci util_make_tess_ctrl_passthrough_shader(&svga->pipe, 212bf215546Sopenharmony_ci svga->curr.vs->base.tgsi_info.num_outputs, 213bf215546Sopenharmony_ci svga->curr.tes->base.tgsi_info.num_inputs, 214bf215546Sopenharmony_ci svga->curr.vs->base.tgsi_info.output_semantic_name, 215bf215546Sopenharmony_ci svga->curr.vs->base.tgsi_info.output_semantic_index, 216bf215546Sopenharmony_ci svga->curr.tes->base.tgsi_info.input_semantic_name, 217bf215546Sopenharmony_ci svga->curr.tes->base.tgsi_info.input_semantic_index, 218bf215546Sopenharmony_ci svga->curr.vertices_per_patch); 219bf215546Sopenharmony_ci svga->pipe.bind_tcs_state(&svga->pipe, new_tcs); 220bf215546Sopenharmony_ci svga->tcs.passthrough_tcs = new_tcs; 221bf215546Sopenharmony_ci svga->tcs.vs = svga->curr.vs; 222bf215546Sopenharmony_ci svga->tcs.tes = svga->curr.tes; 223bf215546Sopenharmony_ci svga->tcs.vertices_per_patch = svga->curr.vertices_per_patch; 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci struct pipe_constant_buffer cb; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci cb.buffer = NULL; 229bf215546Sopenharmony_ci cb.user_buffer = (void *) svga->curr.default_tesslevels; 230bf215546Sopenharmony_ci cb.buffer_offset = 0; 231bf215546Sopenharmony_ci cb.buffer_size = 2 * 4 * sizeof(float); 232bf215546Sopenharmony_ci svga->pipe.set_constant_buffer(&svga->pipe, PIPE_SHADER_TESS_CTRL, 0, false, &cb); 233bf215546Sopenharmony_ci} 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_cistatic enum pipe_error 237bf215546Sopenharmony_ciemit_hw_tes(struct svga_context *svga, uint64_t dirty) 238bf215546Sopenharmony_ci{ 239bf215546Sopenharmony_ci struct svga_shader_variant *variant; 240bf215546Sopenharmony_ci struct svga_tes_shader *tes = svga->curr.tes; 241bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 242bf215546Sopenharmony_ci struct svga_compile_key key; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci assert(svga_have_sm5(svga)); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITTES); 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci if (!tes) { 249bf215546Sopenharmony_ci /* The GL spec implies that TES is optional when there's a TCS, 250bf215546Sopenharmony_ci * but that's apparently a spec error. Assert if we have a TCS 251bf215546Sopenharmony_ci * but no TES. 252bf215546Sopenharmony_ci */ 253bf215546Sopenharmony_ci assert(!svga->curr.tcs); 254bf215546Sopenharmony_ci if (svga->state.hw_draw.tes != NULL) { 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci /** The previous tessellation evaluation shader is made inactive. 257bf215546Sopenharmony_ci * Needs to unbind the tessellation evaluation shader. 258bf215546Sopenharmony_ci */ 259bf215546Sopenharmony_ci ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, NULL); 260bf215546Sopenharmony_ci if (ret != PIPE_OK) 261bf215546Sopenharmony_ci goto done; 262bf215546Sopenharmony_ci svga->state.hw_draw.tes = NULL; 263bf215546Sopenharmony_ci } 264bf215546Sopenharmony_ci goto done; 265bf215546Sopenharmony_ci } 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci if (!svga->curr.tcs) { 268bf215546Sopenharmony_ci /* TES state is processed before the TCS 269bf215546Sopenharmony_ci * shader and that's why we're checking for and creating the 270bf215546Sopenharmony_ci * passthough TCS in the emit_hw_tes() function. 271bf215546Sopenharmony_ci */ 272bf215546Sopenharmony_ci get_passthrough_tcs(svga); 273bf215546Sopenharmony_ci svga->tcs.passthrough = TRUE; 274bf215546Sopenharmony_ci } 275bf215546Sopenharmony_ci else { 276bf215546Sopenharmony_ci svga->tcs.passthrough = FALSE; 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci make_tes_key(svga, &key); 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci /* See if we already have a TES variant that matches the key */ 282bf215546Sopenharmony_ci variant = svga_search_shader_key(&tes->base, &key); 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci if (!variant) { 285bf215546Sopenharmony_ci ret = svga_compile_shader(svga, &tes->base, &key, &variant); 286bf215546Sopenharmony_ci if (ret != PIPE_OK) 287bf215546Sopenharmony_ci goto done; 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci if (variant != svga->state.hw_draw.tes) { 291bf215546Sopenharmony_ci /* Bind the new variant */ 292bf215546Sopenharmony_ci ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, variant); 293bf215546Sopenharmony_ci if (ret != PIPE_OK) 294bf215546Sopenharmony_ci goto done; 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci svga->rebind.flags.tes = FALSE; 297bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_TES_VARIANT; 298bf215546Sopenharmony_ci svga->state.hw_draw.tes = variant; 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_cidone: 302bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 303bf215546Sopenharmony_ci return ret; 304bf215546Sopenharmony_ci} 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tes = 308bf215546Sopenharmony_ci{ 309bf215546Sopenharmony_ci "tessellation evaluation shader (hwtnl)", 310bf215546Sopenharmony_ci /* TBD SVGA_NEW_VS/SVGA_NEW_FS/SVGA_NEW_GS are required or not*/ 311bf215546Sopenharmony_ci (SVGA_NEW_VS | 312bf215546Sopenharmony_ci SVGA_NEW_FS | 313bf215546Sopenharmony_ci SVGA_NEW_GS | 314bf215546Sopenharmony_ci SVGA_NEW_TCS | 315bf215546Sopenharmony_ci SVGA_NEW_TES | 316bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_BINDING | 317bf215546Sopenharmony_ci SVGA_NEW_SAMPLER | 318bf215546Sopenharmony_ci SVGA_NEW_RAST | 319bf215546Sopenharmony_ci SVGA_NEW_TES_RAW_BUFFER), 320bf215546Sopenharmony_ci emit_hw_tes 321bf215546Sopenharmony_ci}; 322