1 /********************************************************** 2 * Copyright 2014 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 "util/u_inlines.h" 27 #include "util/u_memory.h" 28 #include "util/u_bitmask.h" 29 #include "translate/translate.h" 30 #include "tgsi/tgsi_ureg.h" 31 32 #include "svga_context.h" 33 #include "svga_cmd.h" 34 #include "svga_shader.h" 35 #include "svga_tgsi.h" 36 #include "svga_streamout.h" 37 #include "svga_format.h" 38 39 /** 40 * If we fail to compile a geometry shader we'll use a dummy/fallback shader 41 * that simply emits the incoming vertices. 42 */ 43 static const struct tgsi_token * 44 get_dummy_geometry_shader(void) 45 { 46 //XXX 47 return NULL; 48 } 49 50 51 static struct svga_shader_variant * 52 translate_geometry_program(struct svga_context *svga, 53 const struct svga_geometry_shader *gs, 54 const struct svga_compile_key *key) 55 { 56 assert(svga_have_vgpu10(svga)); 57 return svga_tgsi_vgpu10_translate(svga, &gs->base, key, 58 PIPE_SHADER_GEOMETRY); 59 } 60 61 62 /** 63 * Translate TGSI shader into an svga shader variant. 64 */ 65 static enum pipe_error 66 compile_gs(struct svga_context *svga, 67 struct svga_geometry_shader *gs, 68 const struct svga_compile_key *key, 69 struct svga_shader_variant **out_variant) 70 { 71 struct svga_shader_variant *variant; 72 enum pipe_error ret = PIPE_ERROR; 73 74 variant = translate_geometry_program(svga, gs, key); 75 if (!variant) { 76 /* some problem during translation, try the dummy shader */ 77 const struct tgsi_token *dummy = get_dummy_geometry_shader(); 78 if (!dummy) { 79 return PIPE_ERROR_OUT_OF_MEMORY; 80 } 81 debug_printf("Failed to compile geometry shader, using dummy shader instead.\n"); 82 FREE((void *) gs->base.tokens); 83 gs->base.tokens = dummy; 84 variant = translate_geometry_program(svga, gs, key); 85 if (!variant) { 86 return PIPE_ERROR; 87 } 88 } 89 90 ret = svga_define_shader(svga, SVGA3D_SHADERTYPE_GS, variant); 91 if (ret != PIPE_OK) { 92 svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_GS, variant); 93 return ret; 94 } 95 96 *out_variant = variant; 97 98 return PIPE_OK; 99 } 100 101 102 static void 103 make_gs_key(struct svga_context *svga, struct svga_compile_key *key) 104 { 105 struct svga_geometry_shader *gs = svga->curr.gs; 106 107 memset(key, 0, sizeof *key); 108 109 /* 110 * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER 111 */ 112 svga_init_shader_key_common(svga, PIPE_SHADER_GEOMETRY, key); 113 114 memcpy(key->generic_remap_table, gs->generic_remap_table, 115 sizeof(gs->generic_remap_table)); 116 117 key->gs.vs_generic_outputs = svga->curr.vs->generic_outputs; 118 119 key->gs.need_prescale = svga->state.hw_clear.prescale.enabled; 120 121 key->gs.writes_psize = gs->base.info.writes_psize; 122 key->gs.wide_point = gs->wide_point; 123 key->sprite_coord_enable = svga->curr.rast->templ.sprite_coord_enable; 124 key->sprite_origin_lower_left = (svga->curr.rast->templ.sprite_coord_mode 125 == PIPE_SPRITE_COORD_LOWER_LEFT); 126 127 /* SVGA_NEW_RAST */ 128 key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable; 129 } 130 131 132 /** 133 * svga_reemit_gs_bindings - Reemit the geometry shader bindings 134 */ 135 enum pipe_error 136 svga_reemit_gs_bindings(struct svga_context *svga) 137 { 138 enum pipe_error ret; 139 struct svga_winsys_gb_shader *gbshader = NULL; 140 SVGA3dShaderId shaderId = SVGA3D_INVALID_ID; 141 142 assert(svga->rebind.flags.gs); 143 assert(svga_have_gb_objects(svga)); 144 145 /* Geometry Shader is only supported in vgpu10 */ 146 assert(svga_have_vgpu10(svga)); 147 148 if (svga->state.hw_draw.gs) { 149 gbshader = svga->state.hw_draw.gs->gb_shader; 150 shaderId = svga->state.hw_draw.gs->id; 151 } 152 153 if (!svga_need_to_rebind_resources(svga)) { 154 ret = svga->swc->resource_rebind(svga->swc, NULL, gbshader, 155 SVGA_RELOC_READ); 156 goto out; 157 } 158 159 ret = SVGA3D_vgpu10_SetShader(svga->swc, SVGA3D_SHADERTYPE_GS, 160 gbshader, shaderId); 161 162 out: 163 if (ret != PIPE_OK) 164 return ret; 165 166 svga->rebind.flags.gs = FALSE; 167 return PIPE_OK; 168 } 169 170 static enum pipe_error 171 emit_hw_gs(struct svga_context *svga, unsigned dirty) 172 { 173 struct svga_shader_variant *variant; 174 struct svga_geometry_shader *gs = svga->curr.gs; 175 enum pipe_error ret = PIPE_OK; 176 struct svga_compile_key key; 177 178 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITGS); 179 180 /* If there's a user-defined GS, we should have a pointer to a derived 181 * GS. This should have been resolved in update_tgsi_transform(). 182 */ 183 if (svga->curr.user_gs) 184 assert(svga->curr.gs); 185 186 if (!gs) { 187 if (svga->state.hw_draw.gs != NULL) { 188 189 /** The previous geometry shader is made inactive. 190 * Needs to unbind the geometry shader. 191 */ 192 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL); 193 svga->state.hw_draw.gs = NULL; 194 } 195 goto done; 196 } 197 198 /* If there is stream output info for this geometry shader, then use 199 * it instead of the one from the vertex shader. 200 */ 201 if (svga_have_gs_streamout(svga)) { 202 svga_set_stream_output(svga, gs->base.stream_output); 203 } 204 else if (!svga_have_vs_streamout(svga)) { 205 /* turn off stream out */ 206 svga_set_stream_output(svga, NULL); 207 } 208 209 /* SVGA_NEW_NEED_SWTNL */ 210 if (svga->state.sw.need_swtnl && !svga_have_vgpu10(svga)) { 211 /* No geometry shader is needed */ 212 variant = NULL; 213 } 214 else { 215 make_gs_key(svga, &key); 216 217 /* See if we already have a GS variant that matches the key */ 218 variant = svga_search_shader_key(&gs->base, &key); 219 220 if (!variant) { 221 ret = compile_gs(svga, gs, &key, &variant); 222 if (ret != PIPE_OK) 223 goto done; 224 225 /* insert the new variant at head of linked list */ 226 assert(variant); 227 variant->next = gs->base.variants; 228 gs->base.variants = variant; 229 } 230 } 231 232 if (variant != svga->state.hw_draw.gs) { 233 /* Bind the new variant */ 234 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, variant); 235 if (ret != PIPE_OK) 236 goto done; 237 238 svga->rebind.flags.gs = FALSE; 239 svga->dirty |= SVGA_NEW_GS_VARIANT; 240 svga->state.hw_draw.gs = variant; 241 } 242 243 done: 244 SVGA_STATS_TIME_POP(svga_sws(svga)); 245 return ret; 246 } 247 248 struct svga_tracked_state svga_hw_gs = 249 { 250 "geometry shader (hwtnl)", 251 (SVGA_NEW_VS | 252 SVGA_NEW_FS | 253 SVGA_NEW_GS | 254 SVGA_NEW_TEXTURE_BINDING | 255 SVGA_NEW_SAMPLER | 256 SVGA_NEW_RAST | 257 SVGA_NEW_NEED_SWTNL), 258 emit_hw_gs 259 }; 260