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