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 29 30 #include "svga_context.h" 31 #include "svga_state.h" 32 #include "svga_debug.h" 33 #include "svga_hw_reg.h" 34 35 /*********************************************************************** 36 */ 37 38 39 /** 40 * Given a gallium vertex element format, return the corresponding SVGA3D 41 * format. Return SVGA3D_DECLTYPE_MAX for unsupported gallium formats. 42 */ 43 static INLINE SVGA3dDeclType 44 svga_translate_vertex_format(enum pipe_format format) 45 { 46 switch (format) { 47 case PIPE_FORMAT_R32_FLOAT: return SVGA3D_DECLTYPE_FLOAT1; 48 case PIPE_FORMAT_R32G32_FLOAT: return SVGA3D_DECLTYPE_FLOAT2; 49 case PIPE_FORMAT_R32G32B32_FLOAT: return SVGA3D_DECLTYPE_FLOAT3; 50 case PIPE_FORMAT_R32G32B32A32_FLOAT: return SVGA3D_DECLTYPE_FLOAT4; 51 case PIPE_FORMAT_B8G8R8A8_UNORM: return SVGA3D_DECLTYPE_D3DCOLOR; 52 case PIPE_FORMAT_R8G8B8A8_USCALED: return SVGA3D_DECLTYPE_UBYTE4; 53 case PIPE_FORMAT_R16G16_SSCALED: return SVGA3D_DECLTYPE_SHORT2; 54 case PIPE_FORMAT_R16G16B16A16_SSCALED: return SVGA3D_DECLTYPE_SHORT4; 55 case PIPE_FORMAT_R8G8B8A8_UNORM: return SVGA3D_DECLTYPE_UBYTE4N; 56 case PIPE_FORMAT_R16G16_SNORM: return SVGA3D_DECLTYPE_SHORT2N; 57 case PIPE_FORMAT_R16G16B16A16_SNORM: return SVGA3D_DECLTYPE_SHORT4N; 58 case PIPE_FORMAT_R16G16_UNORM: return SVGA3D_DECLTYPE_USHORT2N; 59 case PIPE_FORMAT_R16G16B16A16_UNORM: return SVGA3D_DECLTYPE_USHORT4N; 60 case PIPE_FORMAT_R10G10B10X2_USCALED: return SVGA3D_DECLTYPE_UDEC3; 61 case PIPE_FORMAT_R10G10B10X2_SNORM: return SVGA3D_DECLTYPE_DEC3N; 62 case PIPE_FORMAT_R16G16_FLOAT: return SVGA3D_DECLTYPE_FLOAT16_2; 63 case PIPE_FORMAT_R16G16B16A16_FLOAT: return SVGA3D_DECLTYPE_FLOAT16_4; 64 65 default: 66 /* There are many formats without hardware support. This case 67 * will be hit regularly, meaning we'll need swvfetch. 68 */ 69 return SVGA3D_DECLTYPE_MAX; 70 } 71 } 72 73 74 static enum pipe_error 75 update_need_swvfetch( struct svga_context *svga, 76 unsigned dirty ) 77 { 78 unsigned i; 79 boolean need_swvfetch = FALSE; 80 81 if (!svga->curr.velems) { 82 /* No vertex elements bound. */ 83 return 0; 84 } 85 86 for (i = 0; i < svga->curr.velems->count; i++) { 87 svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.velems->velem[i].src_format); 88 if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) { 89 /* Unsupported format - use software fetch */ 90 need_swvfetch = TRUE; 91 break; 92 } 93 } 94 95 if (need_swvfetch != svga->state.sw.need_swvfetch) { 96 svga->state.sw.need_swvfetch = need_swvfetch; 97 svga->dirty |= SVGA_NEW_NEED_SWVFETCH; 98 } 99 100 return PIPE_OK; 101 } 102 103 struct svga_tracked_state svga_update_need_swvfetch = 104 { 105 "update need_swvfetch", 106 ( SVGA_NEW_VELEMENT ), 107 update_need_swvfetch 108 }; 109 110 111 /*********************************************************************** 112 */ 113 114 static enum pipe_error 115 update_need_pipeline( struct svga_context *svga, 116 unsigned dirty ) 117 { 118 119 boolean need_pipeline = FALSE; 120 struct svga_vertex_shader *vs = svga->curr.vs; 121 122 /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE 123 */ 124 if (svga->curr.rast->need_pipeline & (1 << svga->curr.reduced_prim)) { 125 SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (0x%x) & prim (0x%x)\n", 126 __FUNCTION__, 127 svga->curr.rast->need_pipeline, 128 (1 << svga->curr.reduced_prim) ); 129 SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline tris (%s), lines (%s), points (%s)\n", 130 __FUNCTION__, 131 svga->curr.rast->need_pipeline_tris_str, 132 svga->curr.rast->need_pipeline_lines_str, 133 svga->curr.rast->need_pipeline_points_str); 134 need_pipeline = TRUE; 135 } 136 137 /* EDGEFLAGS 138 */ 139 if (vs && vs->base.info.writes_edgeflag) { 140 SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __FUNCTION__); 141 need_pipeline = TRUE; 142 } 143 144 /* SVGA_NEW_FS, SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE 145 */ 146 if (svga->curr.reduced_prim == PIPE_PRIM_POINTS) { 147 unsigned sprite_coord_gen = svga->curr.rast->templ.sprite_coord_enable; 148 unsigned generic_inputs = 149 svga->curr.fs ? svga->curr.fs->generic_inputs : 0; 150 151 if (sprite_coord_gen && 152 (generic_inputs & ~sprite_coord_gen)) { 153 /* The fragment shader is using some generic inputs that are 154 * not being replaced by auto-generated point/sprite coords (and 155 * auto sprite coord generation is turned on). 156 * The SVGA3D interface does not support that: if we enable 157 * SVGA3D_RS_POINTSPRITEENABLE it gets enabled for _all_ 158 * texture coordinate sets. 159 * To solve this, we have to use the draw-module's wide/sprite 160 * point stage. 161 */ 162 need_pipeline = TRUE; 163 } 164 } 165 166 if (need_pipeline != svga->state.sw.need_pipeline) { 167 svga->state.sw.need_pipeline = need_pipeline; 168 svga->dirty |= SVGA_NEW_NEED_PIPELINE; 169 } 170 171 /* DEBUG */ 172 if (0 && svga->state.sw.need_pipeline) 173 debug_printf("sw.need_pipeline = %d\n", svga->state.sw.need_pipeline); 174 175 return PIPE_OK; 176 } 177 178 179 struct svga_tracked_state svga_update_need_pipeline = 180 { 181 "need pipeline", 182 (SVGA_NEW_RAST | 183 SVGA_NEW_FS | 184 SVGA_NEW_VS | 185 SVGA_NEW_REDUCED_PRIMITIVE), 186 update_need_pipeline 187 }; 188 189 190 /*********************************************************************** 191 */ 192 193 static enum pipe_error 194 update_need_swtnl( struct svga_context *svga, 195 unsigned dirty ) 196 { 197 boolean need_swtnl; 198 199 if (svga->debug.no_swtnl) { 200 svga->state.sw.need_swvfetch = FALSE; 201 svga->state.sw.need_pipeline = FALSE; 202 } 203 204 need_swtnl = (svga->state.sw.need_swvfetch || 205 svga->state.sw.need_pipeline); 206 207 if (svga->debug.force_swtnl) { 208 need_swtnl = TRUE; 209 } 210 211 /* 212 * Some state changes the draw module does makes us believe we 213 * we don't need swtnl. This causes the vdecl code to pickup 214 * the wrong buffers and vertex formats. Try trivial/line-wide. 215 */ 216 if (svga->state.sw.in_swtnl_draw) 217 need_swtnl = TRUE; 218 219 if (need_swtnl != svga->state.sw.need_swtnl) { 220 SVGA_DBG(DEBUG_SWTNL|DEBUG_PERF, 221 "%s: need_swvfetch %s, need_pipeline %s\n", 222 __FUNCTION__, 223 svga->state.sw.need_swvfetch ? "true" : "false", 224 svga->state.sw.need_pipeline ? "true" : "false"); 225 226 svga->state.sw.need_swtnl = need_swtnl; 227 svga->dirty |= SVGA_NEW_NEED_SWTNL; 228 svga->swtnl.new_vdecl = TRUE; 229 } 230 231 return PIPE_OK; 232 } 233 234 235 struct svga_tracked_state svga_update_need_swtnl = 236 { 237 "need swtnl", 238 (SVGA_NEW_NEED_PIPELINE | 239 SVGA_NEW_NEED_SWVFETCH), 240 update_need_swtnl 241 }; 242