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 "draw/draw_context.h" 27 #include "draw/draw_vbuf.h" 28 #include "util/u_bitmask.h" 29 #include "util/u_inlines.h" 30 #include "pipe/p_state.h" 31 32 #include "svga_cmd.h" 33 #include "svga_context.h" 34 #include "svga_shader.h" 35 #include "svga_swtnl.h" 36 #include "svga_state.h" 37 #include "svga_tgsi.h" 38 #include "svga_swtnl_private.h" 39 40 41 #define SVGA_POINT_ADJ_X -0.375f 42 #define SVGA_POINT_ADJ_Y -0.5f 43 44 #define SVGA_LINE_ADJ_X -0.5f 45 #define SVGA_LINE_ADJ_Y -0.5f 46 47 #define SVGA_TRIANGLE_ADJ_X -0.375f 48 #define SVGA_TRIANGLE_ADJ_Y -0.5f 49 50 51 static void set_draw_viewport( struct svga_context *svga ) 52 { 53 struct pipe_viewport_state vp = svga->curr.viewport; 54 float adjx = 0.0f; 55 float adjy = 0.0f; 56 57 if (svga_have_vgpu10(svga)) { 58 if (svga->curr.reduced_prim == PIPE_PRIM_TRIANGLES) { 59 adjy = 0.25; 60 } 61 } 62 else { 63 switch (svga->curr.reduced_prim) { 64 case PIPE_PRIM_POINTS: 65 adjx = SVGA_POINT_ADJ_X; 66 adjy = SVGA_POINT_ADJ_Y; 67 break; 68 case PIPE_PRIM_LINES: 69 /* XXX: This is to compensate for the fact that wide lines are 70 * going to be drawn with triangles, but we're not catching all 71 * cases where that will happen. 72 */ 73 if (svga->curr.rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES) 74 { 75 adjx = SVGA_LINE_ADJ_X + 0.175f; 76 adjy = SVGA_LINE_ADJ_Y - 0.175f; 77 } 78 else { 79 adjx = SVGA_LINE_ADJ_X; 80 adjy = SVGA_LINE_ADJ_Y; 81 } 82 break; 83 case PIPE_PRIM_TRIANGLES: 84 adjx += SVGA_TRIANGLE_ADJ_X; 85 adjy += SVGA_TRIANGLE_ADJ_Y; 86 break; 87 } 88 } 89 90 vp.translate[0] += adjx; 91 vp.translate[1] += adjy; 92 93 draw_set_viewport_states(svga->swtnl.draw, 0, 1, &vp); 94 } 95 96 static enum pipe_error 97 update_swtnl_draw( struct svga_context *svga, 98 unsigned dirty ) 99 { 100 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLUPDATEDRAW); 101 102 draw_flush( svga->swtnl.draw ); 103 104 if (dirty & SVGA_NEW_VS) 105 draw_bind_vertex_shader(svga->swtnl.draw, 106 svga->curr.vs->draw_shader); 107 108 if (dirty & SVGA_NEW_FS) 109 draw_bind_fragment_shader(svga->swtnl.draw, 110 svga->curr.fs->draw_shader); 111 112 if (dirty & SVGA_NEW_VBUFFER) 113 draw_set_vertex_buffers(svga->swtnl.draw, 0, 114 svga->curr.num_vertex_buffers, 115 svga->curr.vb); 116 117 if (dirty & SVGA_NEW_VELEMENT) 118 draw_set_vertex_elements(svga->swtnl.draw, 119 svga->curr.velems->count, 120 svga->curr.velems->velem ); 121 122 if (dirty & SVGA_NEW_CLIP) 123 draw_set_clip_state(svga->swtnl.draw, 124 &svga->curr.clip); 125 126 if (dirty & (SVGA_NEW_VIEWPORT | 127 SVGA_NEW_REDUCED_PRIMITIVE | 128 SVGA_NEW_RAST)) 129 set_draw_viewport( svga ); 130 131 if (dirty & SVGA_NEW_RAST) 132 draw_set_rasterizer_state(svga->swtnl.draw, 133 &svga->curr.rast->templ, 134 (void *) svga->curr.rast); 135 136 /* Tell the draw module how deep the Z/depth buffer is. 137 * 138 * If no depth buffer is bound, send the utility function the 139 * format for no bound depth (PIPE_FORMAT_NONE). 140 */ 141 if (dirty & SVGA_NEW_FRAME_BUFFER) 142 draw_set_zs_format(svga->swtnl.draw, 143 (svga->curr.framebuffer.zsbuf) ? 144 svga->curr.framebuffer.zsbuf->format : PIPE_FORMAT_NONE); 145 146 SVGA_STATS_TIME_POP(svga_sws(svga)); 147 return PIPE_OK; 148 } 149 150 151 struct svga_tracked_state svga_update_swtnl_draw = 152 { 153 "update draw module state", 154 (SVGA_NEW_VS | 155 SVGA_NEW_VBUFFER | 156 SVGA_NEW_VELEMENT | 157 SVGA_NEW_CLIP | 158 SVGA_NEW_VIEWPORT | 159 SVGA_NEW_RAST | 160 SVGA_NEW_FRAME_BUFFER | 161 SVGA_NEW_REDUCED_PRIMITIVE), 162 update_swtnl_draw 163 }; 164 165 166 static SVGA3dSurfaceFormat 167 translate_vertex_format(SVGA3dDeclType format) 168 { 169 switch (format) { 170 case SVGA3D_DECLTYPE_FLOAT1: 171 return SVGA3D_R32_FLOAT; 172 case SVGA3D_DECLTYPE_FLOAT2: 173 return SVGA3D_R32G32_FLOAT; 174 case SVGA3D_DECLTYPE_FLOAT3: 175 return SVGA3D_R32G32B32_FLOAT; 176 case SVGA3D_DECLTYPE_FLOAT4: 177 return SVGA3D_R32G32B32A32_FLOAT; 178 default: 179 assert(!"Unexpected format in translate_vertex_format()"); 180 return SVGA3D_R32G32B32A32_FLOAT; 181 } 182 } 183 184 185 static SVGA3dElementLayoutId 186 svga_vdecl_to_input_element(struct svga_context *svga, 187 const SVGA3dVertexDecl *vdecl, unsigned num_decls) 188 { 189 SVGA3dElementLayoutId id; 190 SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS]; 191 enum pipe_error ret; 192 unsigned i; 193 194 assert(num_decls <= PIPE_MAX_ATTRIBS); 195 assert(svga_have_vgpu10(svga)); 196 197 for (i = 0; i < num_decls; i++) { 198 elements[i].inputSlot = 0; /* vertex buffer index */ 199 elements[i].alignedByteOffset = vdecl[i].array.offset; 200 elements[i].format = translate_vertex_format(vdecl[i].identity.type); 201 elements[i].inputSlotClass = SVGA3D_INPUT_PER_VERTEX_DATA; 202 elements[i].instanceDataStepRate = 0; 203 elements[i].inputRegister = i; 204 } 205 206 id = util_bitmask_add(svga->input_element_object_id_bm); 207 208 ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, num_decls, id, elements); 209 if (ret != PIPE_OK) { 210 svga_context_flush(svga, NULL); 211 ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, num_decls, id, elements); 212 assert(ret == PIPE_OK); 213 } 214 215 return id; 216 } 217 218 219 enum pipe_error 220 svga_swtnl_update_vdecl( struct svga_context *svga ) 221 { 222 struct svga_vbuf_render *svga_render = svga_vbuf_render(svga->swtnl.backend); 223 struct draw_context *draw = svga->swtnl.draw; 224 struct vertex_info *vinfo = &svga_render->vertex_info; 225 SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS]; 226 struct svga_fragment_shader *fs = svga->curr.fs; 227 int offset = 0; 228 int nr_decls = 0; 229 int src; 230 unsigned i; 231 int any_change; 232 233 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLUPDATEVDECL); 234 235 memset(vinfo, 0, sizeof(*vinfo)); 236 memset(vdecl, 0, sizeof(vdecl)); 237 238 draw_prepare_shader_outputs(draw); 239 240 /* always add position */ 241 src = draw_find_shader_output(draw, TGSI_SEMANTIC_POSITION, 0); 242 draw_emit_vertex_attr(vinfo, EMIT_4F, src); 243 vinfo->attrib[0].emit = EMIT_4F; 244 vdecl[0].array.offset = offset; 245 vdecl[0].identity.method = SVGA3D_DECLMETHOD_DEFAULT; 246 vdecl[0].identity.type = SVGA3D_DECLTYPE_FLOAT4; 247 vdecl[0].identity.usage = SVGA3D_DECLUSAGE_POSITIONT; 248 vdecl[0].identity.usageIndex = 0; 249 offset += 16; 250 nr_decls++; 251 252 for (i = 0; i < fs->base.info.num_inputs; i++) { 253 const unsigned sem_name = fs->base.info.input_semantic_name[i]; 254 const unsigned sem_index = fs->base.info.input_semantic_index[i]; 255 256 src = draw_find_shader_output(draw, sem_name, sem_index); 257 258 vdecl[nr_decls].array.offset = offset; 259 vdecl[nr_decls].identity.usageIndex = sem_index; 260 261 switch (sem_name) { 262 case TGSI_SEMANTIC_COLOR: 263 draw_emit_vertex_attr(vinfo, EMIT_4F, src); 264 vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_COLOR; 265 vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4; 266 offset += 16; 267 nr_decls++; 268 break; 269 case TGSI_SEMANTIC_GENERIC: 270 draw_emit_vertex_attr(vinfo, EMIT_4F, src); 271 vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD; 272 vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4; 273 vdecl[nr_decls].identity.usageIndex = 274 svga_remap_generic_index(fs->generic_remap_table, sem_index); 275 offset += 16; 276 nr_decls++; 277 break; 278 case TGSI_SEMANTIC_FOG: 279 draw_emit_vertex_attr(vinfo, EMIT_1F, src); 280 vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD; 281 vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT1; 282 assert(vdecl[nr_decls].identity.usageIndex == 0); 283 offset += 4; 284 nr_decls++; 285 break; 286 case TGSI_SEMANTIC_POSITION: 287 /* generated internally, not a vertex shader output */ 288 break; 289 default: 290 assert(0); 291 } 292 } 293 294 draw_compute_vertex_size(vinfo); 295 296 svga_render->vdecl_count = nr_decls; 297 for (i = 0; i < svga_render->vdecl_count; i++) { 298 vdecl[i].array.stride = offset; 299 } 300 301 any_change = memcmp(svga_render->vdecl, vdecl, sizeof(vdecl)); 302 303 if (svga_have_vgpu10(svga)) { 304 enum pipe_error ret; 305 306 if (!any_change && svga_render->layout_id != SVGA3D_INVALID_ID) { 307 goto done; 308 } 309 310 if (svga_render->layout_id != SVGA3D_INVALID_ID) { 311 /* destroy old */ 312 ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, 313 svga_render->layout_id); 314 if (ret != PIPE_OK) { 315 svga_context_flush(svga, NULL); 316 ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, 317 svga_render->layout_id); 318 assert(ret == PIPE_OK); 319 } 320 321 /** 322 * reset current layout id state after the element layout is 323 * destroyed, so that if a new layout has the same layout id, we 324 * will know to re-issue the SetInputLayout command. 325 */ 326 if (svga->state.hw_draw.layout_id == svga_render->layout_id) 327 svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID; 328 329 util_bitmask_clear(svga->input_element_object_id_bm, 330 svga_render->layout_id); 331 } 332 333 svga_render->layout_id = 334 svga_vdecl_to_input_element(svga, vdecl, nr_decls); 335 336 /* bind new */ 337 if (svga->state.hw_draw.layout_id != svga_render->layout_id) { 338 ret = SVGA3D_vgpu10_SetInputLayout(svga->swc, svga_render->layout_id); 339 if (ret != PIPE_OK) { 340 svga_context_flush(svga, NULL); 341 ret = SVGA3D_vgpu10_SetInputLayout(svga->swc, 342 svga_render->layout_id); 343 assert(ret == PIPE_OK); 344 } 345 346 svga->state.hw_draw.layout_id = svga_render->layout_id; 347 } 348 } 349 else { 350 if (!any_change) 351 goto done; 352 } 353 354 memcpy(svga_render->vdecl, vdecl, sizeof(vdecl)); 355 svga->swtnl.new_vdecl = TRUE; 356 357 done: 358 SVGA_STATS_TIME_POP(svga_sws(svga)); 359 return PIPE_OK; 360 } 361 362 363 static enum pipe_error 364 update_swtnl_vdecl( struct svga_context *svga, 365 unsigned dirty ) 366 { 367 return svga_swtnl_update_vdecl( svga ); 368 } 369 370 371 struct svga_tracked_state svga_update_swtnl_vdecl = 372 { 373 "update draw module vdecl", 374 (SVGA_NEW_VS | 375 SVGA_NEW_FS), 376 update_swtnl_vdecl 377 }; 378