1 /********************************************************** 2 * Copyright 2008-2009 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 "pipe/p_state.h" 28 #include "svga_context.h" 29 #include "svga_shader.h" 30 #include "svga_state.h" 31 #include "svga_debug.h" 32 #include "svga_hw_reg.h" 33 34 35 static enum pipe_error 36 update_need_swvfetch(struct svga_context *svga, unsigned dirty) 37 { 38 if (!svga->curr.velems) { 39 /* No vertex elements bound. */ 40 return PIPE_OK; 41 } 42 43 if (svga->state.sw.need_swvfetch != svga->curr.velems->need_swvfetch) { 44 svga->state.sw.need_swvfetch = svga->curr.velems->need_swvfetch; 45 svga->dirty |= SVGA_NEW_NEED_SWVFETCH; 46 } 47 48 return PIPE_OK; 49 } 50 51 struct svga_tracked_state svga_update_need_swvfetch = 52 { 53 "update need_swvfetch", 54 ( SVGA_NEW_VELEMENT ), 55 update_need_swvfetch 56 }; 57 58 59 60 static enum pipe_error 61 update_need_pipeline(struct svga_context *svga, unsigned dirty) 62 { 63 boolean need_pipeline = FALSE; 64 struct svga_vertex_shader *vs = svga->curr.vs; 65 const char *reason = ""; 66 67 /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE 68 */ 69 if (svga->curr.rast->need_pipeline & (1 << svga->curr.reduced_prim)) { 70 SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (0x%x) & prim (0x%x)\n", 71 __FUNCTION__, 72 svga->curr.rast->need_pipeline, 73 (1 << svga->curr.reduced_prim) ); 74 SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline tris (%s), lines (%s), points (%s)\n", 75 __FUNCTION__, 76 svga->curr.rast->need_pipeline_tris_str, 77 svga->curr.rast->need_pipeline_lines_str, 78 svga->curr.rast->need_pipeline_points_str); 79 need_pipeline = TRUE; 80 81 switch (svga->curr.reduced_prim) { 82 case PIPE_PRIM_POINTS: 83 reason = svga->curr.rast->need_pipeline_points_str; 84 break; 85 case PIPE_PRIM_LINES: 86 reason = svga->curr.rast->need_pipeline_lines_str; 87 break; 88 case PIPE_PRIM_TRIANGLES: 89 reason = svga->curr.rast->need_pipeline_tris_str; 90 break; 91 default: 92 assert(!"Unexpected reduced prim type"); 93 } 94 } 95 96 /* EDGEFLAGS 97 */ 98 if (vs && vs->base.info.writes_edgeflag) { 99 SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __FUNCTION__); 100 need_pipeline = TRUE; 101 reason = "edge flags"; 102 } 103 104 /* SVGA_NEW_FS, SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE 105 */ 106 if (svga->curr.reduced_prim == PIPE_PRIM_POINTS) { 107 unsigned sprite_coord_gen = svga->curr.rast->templ.sprite_coord_enable; 108 unsigned generic_inputs = 109 svga->curr.fs ? svga->curr.fs->generic_inputs : 0; 110 111 if (!svga_have_vgpu10(svga) && sprite_coord_gen && 112 (generic_inputs & ~sprite_coord_gen)) { 113 /* The fragment shader is using some generic inputs that are 114 * not being replaced by auto-generated point/sprite coords (and 115 * auto sprite coord generation is turned on). 116 * The SVGA3D interface does not support that: if we enable 117 * SVGA3D_RS_POINTSPRITEENABLE it gets enabled for _all_ 118 * texture coordinate sets. 119 * To solve this, we have to use the draw-module's wide/sprite 120 * point stage. 121 */ 122 need_pipeline = TRUE; 123 reason = "point sprite coordinate generation"; 124 } 125 } 126 127 if (need_pipeline != svga->state.sw.need_pipeline) { 128 svga->state.sw.need_pipeline = need_pipeline; 129 svga->dirty |= SVGA_NEW_NEED_PIPELINE; 130 } 131 132 /* DEBUG */ 133 if (0 && svga->state.sw.need_pipeline) 134 debug_printf("sw.need_pipeline = %d\n", svga->state.sw.need_pipeline); 135 136 if (svga->state.sw.need_pipeline) { 137 assert(reason); 138 pipe_debug_message(&svga->debug.callback, FALLBACK, 139 "Using semi-fallback for %s", reason); 140 } 141 142 return PIPE_OK; 143 } 144 145 146 struct svga_tracked_state svga_update_need_pipeline = 147 { 148 "need pipeline", 149 (SVGA_NEW_RAST | 150 SVGA_NEW_FS | 151 SVGA_NEW_VS | 152 SVGA_NEW_REDUCED_PRIMITIVE), 153 update_need_pipeline 154 }; 155 156 157 static enum pipe_error 158 update_need_swtnl(struct svga_context *svga, unsigned dirty) 159 { 160 boolean need_swtnl; 161 162 if (svga->debug.no_swtnl) { 163 svga->state.sw.need_swvfetch = FALSE; 164 svga->state.sw.need_pipeline = FALSE; 165 } 166 167 need_swtnl = (svga->state.sw.need_swvfetch || 168 svga->state.sw.need_pipeline); 169 170 if (svga->debug.force_swtnl) { 171 need_swtnl = TRUE; 172 } 173 174 /* 175 * Some state changes the draw module does makes us believe we 176 * we don't need swtnl. This causes the vdecl code to pickup 177 * the wrong buffers and vertex formats. Try trivial/line-wide. 178 */ 179 if (svga->state.sw.in_swtnl_draw) 180 need_swtnl = TRUE; 181 182 if (need_swtnl != svga->state.sw.need_swtnl) { 183 SVGA_DBG(DEBUG_SWTNL|DEBUG_PERF, 184 "%s: need_swvfetch %s, need_pipeline %s\n", 185 __FUNCTION__, 186 svga->state.sw.need_swvfetch ? "true" : "false", 187 svga->state.sw.need_pipeline ? "true" : "false"); 188 189 svga->state.sw.need_swtnl = need_swtnl; 190 svga->dirty |= SVGA_NEW_NEED_SWTNL; 191 svga->swtnl.new_vdecl = TRUE; 192 } 193 194 return PIPE_OK; 195 } 196 197 198 struct svga_tracked_state svga_update_need_swtnl = 199 { 200 "need swtnl", 201 (SVGA_NEW_NEED_PIPELINE | 202 SVGA_NEW_NEED_SWVFETCH), 203 update_need_swtnl 204 }; 205