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_bitmask.h" 27#include "util/u_debug.h" 28#include "pipe/p_defines.h" 29#include "util/u_memory.h" 30#include "draw/draw_context.h" 31 32#include "svga_context.h" 33#include "svga_screen.h" 34#include "svga_state.h" 35#include "svga_draw.h" 36#include "svga_cmd.h" 37#include "svga_hw_reg.h" 38 39/* This is just enough to decide whether we need to use the draw 40 * module (swtnl) or not. 41 */ 42static const struct svga_tracked_state *need_swtnl_state[] = 43{ 44 &svga_update_need_swvfetch, 45 &svga_update_need_pipeline, 46 &svga_update_need_swtnl, 47 NULL 48}; 49 50 51/* Atoms to update hardware state prior to emitting a clear or draw 52 * packet. 53 */ 54static const struct svga_tracked_state *hw_clear_state[] = 55{ 56 &svga_hw_scissor, 57 &svga_hw_viewport, 58 &svga_hw_framebuffer, 59 NULL 60}; 61 62 63/** 64 * Atoms to update hardware state prior to emitting a draw packet 65 * for VGPU9 device. 66 */ 67static const struct svga_tracked_state *hw_draw_state_vgpu9[] = 68{ 69 &svga_hw_fs, 70 &svga_hw_vs, 71 &svga_hw_rss, 72 &svga_hw_tss, 73 &svga_hw_tss_binding, 74 &svga_hw_clip_planes, 75 &svga_hw_vdecl, 76 &svga_hw_fs_constants, 77 &svga_hw_vs_constants, 78 NULL 79}; 80 81 82/** 83 * Atoms to update hardware state prior to emitting a draw packet 84 * for VGPU10 device. 85 * Geometry Shader is new to VGPU10. 86 * TSS and TSS bindings are replaced by sampler and sampler bindings. 87 */ 88static const struct svga_tracked_state *hw_draw_state_vgpu10[] = 89{ 90 &svga_need_tgsi_transform, 91 &svga_hw_fs, 92 &svga_hw_gs, 93 &svga_hw_vs, 94 &svga_hw_rss, 95 &svga_hw_sampler, 96 &svga_hw_sampler_bindings, 97 &svga_hw_clip_planes, 98 &svga_hw_vdecl, 99 &svga_hw_fs_constants, 100 &svga_hw_fs_constbufs, 101 &svga_hw_gs_constants, 102 &svga_hw_gs_constbufs, 103 &svga_hw_vs_constants, 104 &svga_hw_vs_constbufs, 105 NULL 106}; 107 108 109/** 110 * Atoms to update hardware state prior to emitting a draw packet 111 * for SM5 device. 112 * TCS and TES Shaders are new to SM5 device. 113 */ 114static const struct svga_tracked_state *hw_draw_state_sm5[] = 115{ 116 &svga_need_tgsi_transform, 117 &svga_hw_fs, 118 &svga_hw_gs, 119 &svga_hw_tes, 120 &svga_hw_tcs, 121 &svga_hw_vs, 122 &svga_hw_rss, 123 &svga_hw_sampler, 124 &svga_hw_sampler_bindings, 125 &svga_hw_clip_planes, 126 &svga_hw_vdecl, 127 &svga_hw_fs_constants, 128 &svga_hw_fs_constbufs, 129 &svga_hw_gs_constants, 130 &svga_hw_gs_constbufs, 131 &svga_hw_tes_constants, 132 &svga_hw_tes_constbufs, 133 &svga_hw_tcs_constants, 134 &svga_hw_tcs_constbufs, 135 &svga_hw_vs_constants, 136 &svga_hw_vs_constbufs, 137 NULL 138}; 139 140 141/** 142 * Atoms to update hardware state prior to emitting a draw packet 143 * for GL43 device which includes uav update. 144 */ 145static const struct svga_tracked_state *hw_draw_state_gl43[] = 146{ 147 &svga_need_tgsi_transform, 148 &svga_hw_uav, 149 &svga_need_rawbuf_srv, 150 &svga_hw_fs, 151 &svga_hw_gs, 152 &svga_hw_tes, 153 &svga_hw_tcs, 154 &svga_hw_vs, 155 &svga_hw_rss, 156 &svga_hw_sampler, 157 &svga_hw_sampler_bindings, 158 &svga_hw_clip_planes, 159 &svga_hw_vdecl, 160 &svga_hw_fs_constants, 161 &svga_hw_fs_constbufs, 162 &svga_hw_gs_constants, 163 &svga_hw_gs_constbufs, 164 &svga_hw_tes_constants, 165 &svga_hw_tes_constbufs, 166 &svga_hw_tcs_constants, 167 &svga_hw_tcs_constbufs, 168 &svga_hw_vs_constants, 169 &svga_hw_vs_constbufs, 170 NULL 171}; 172 173 174static const struct svga_tracked_state *swtnl_draw_state[] = 175{ 176 &svga_update_swtnl_draw, 177 &svga_update_swtnl_vdecl, 178 NULL 179}; 180 181 182/* Flattens the graph of state dependencies. Could swap the positions 183 * of hw_clear_state and need_swtnl_state without breaking anything. 184 */ 185static const struct svga_tracked_state **state_levels[] = 186{ 187 need_swtnl_state, 188 hw_clear_state, 189 NULL, /* hw_draw_state, to be set to the right version */ 190 swtnl_draw_state 191}; 192 193 194static uint64_t 195check_state(uint64_t a, uint64_t b) 196{ 197 return (a & b); 198} 199 200static void 201accumulate_state(uint64_t *a, uint64_t b) 202{ 203 *a |= b; 204} 205 206 207static void 208xor_states(uint64_t *result, uint64_t a, uint64_t b) 209{ 210 *result = a ^ b; 211} 212 213 214static enum pipe_error 215update_state(struct svga_context *svga, 216 const struct svga_tracked_state *atoms[], 217 uint64_t *state) 218{ 219#ifdef DEBUG 220 boolean debug = TRUE; 221#else 222 boolean debug = FALSE; 223#endif 224 enum pipe_error ret = PIPE_OK; 225 unsigned i; 226 227 ret = svga_hwtnl_flush( svga->hwtnl ); 228 if (ret != PIPE_OK) 229 return ret; 230 231 if (debug) { 232 /* Debug version which enforces various sanity checks on the 233 * state flags which are generated and checked to help ensure 234 * state atoms are ordered correctly in the list. 235 */ 236 uint64_t examined, prev; 237 238 examined = 0; 239 prev = *state; 240 241 for (i = 0; atoms[i] != NULL; i++) { 242 uint64_t generated; 243 244 assert(atoms[i]->dirty); 245 assert(atoms[i]->update); 246 247 if (check_state(*state, atoms[i]->dirty)) { 248 if (0) 249 debug_printf("update: %s\n", atoms[i]->name); 250 ret = atoms[i]->update( svga, *state ); 251 if (ret != PIPE_OK) 252 return ret; 253 } 254 255 /* generated = (prev ^ state) 256 * if (examined & generated) 257 * fail; 258 */ 259 xor_states(&generated, prev, *state); 260 if (check_state(examined, generated)) { 261 debug_printf("state atom %s generated state already examined\n", 262 atoms[i]->name); 263 assert(0); 264 } 265 266 prev = *state; 267 accumulate_state(&examined, atoms[i]->dirty); 268 } 269 } 270 else { 271 for (i = 0; atoms[i] != NULL; i++) { 272 if (check_state(*state, atoms[i]->dirty)) { 273 ret = atoms[i]->update( svga, *state ); 274 if (ret != PIPE_OK) 275 return ret; 276 } 277 } 278 } 279 280 return PIPE_OK; 281} 282 283 284enum pipe_error 285svga_update_state(struct svga_context *svga, unsigned max_level) 286{ 287 struct svga_screen *screen = svga_screen(svga->pipe.screen); 288 enum pipe_error ret = PIPE_OK; 289 unsigned i; 290 291 SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE); 292 293 /* Check for updates to bound textures. This can't be done in an 294 * atom as there is no flag which could provoke this test, and we 295 * cannot create one. 296 */ 297 if (svga->state.texture_timestamp != screen->texture_timestamp) { 298 svga->state.texture_timestamp = screen->texture_timestamp; 299 svga->dirty |= SVGA_NEW_TEXTURE; 300 } 301 302 for (i = 0; i <= max_level; i++) { 303 svga->dirty |= svga->state.dirty[i]; 304 305 if (svga->dirty) { 306 ret = update_state( svga, 307 state_levels[i], 308 &svga->dirty ); 309 if (ret != PIPE_OK) 310 goto done; 311 312 svga->state.dirty[i] = 0; 313 } 314 } 315 316 for (; i < SVGA_STATE_MAX; i++) 317 svga->state.dirty[i] |= svga->dirty; 318 319 svga->dirty = 0; 320 321 svga->hud.num_validations++; 322 323done: 324 SVGA_STATS_TIME_POP(screen->sws); 325 return ret; 326} 327 328 329/** 330 * Update state. If the first attempt fails, flush the command buffer 331 * and retry. 332 * \return true if success, false if second attempt fails. 333 */ 334bool 335svga_update_state_retry(struct svga_context *svga, unsigned max_level) 336{ 337 enum pipe_error ret; 338 339 SVGA_RETRY_OOM(svga, ret, svga_update_state( svga, max_level )); 340 341 return ret == PIPE_OK; 342} 343 344 345#define EMIT_RS(_rs, _count, _name, _value) \ 346do { \ 347 _rs[_count].state = _name; \ 348 _rs[_count].uintValue = _value; \ 349 _count++; \ 350} while (0) 351 352 353/* Setup any hardware state which will be constant through the life of 354 * a context. 355 */ 356enum pipe_error 357svga_emit_initial_state(struct svga_context *svga) 358{ 359 if (svga_have_vgpu10(svga)) { 360 SVGA3dRasterizerStateId id = util_bitmask_add(svga->rast_object_id_bm); 361 enum pipe_error ret; 362 363 /* XXX preliminary code */ 364 ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc, 365 id, 366 SVGA3D_FILLMODE_FILL, 367 SVGA3D_CULL_NONE, 368 1, /* frontCounterClockwise */ 369 0, /* depthBias */ 370 0.0f, /* depthBiasClamp */ 371 0.0f, /* slopeScaledDepthBiasClamp */ 372 0, /* depthClampEnable */ 373 0, /* scissorEnable */ 374 0, /* multisampleEnable */ 375 0, /* aalineEnable */ 376 1.0f, /* lineWidth */ 377 0, /* lineStippleEnable */ 378 0, /* lineStippleFactor */ 379 0, /* lineStipplePattern */ 380 0); /* provokingVertexLast */ 381 382 383 assert(ret == PIPE_OK); 384 385 ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, id); 386 return ret; 387 } 388 else { 389 SVGA3dRenderState *rs; 390 unsigned count = 0; 391 const unsigned COUNT = 2; 392 enum pipe_error ret; 393 394 ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT ); 395 if (ret != PIPE_OK) 396 return ret; 397 398 /* Always use D3D style coordinate space as this is the only one 399 * which is implemented on all backends. 400 */ 401 EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE, 402 SVGA3D_COORDINATE_LEFTHANDED ); 403 EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW ); 404 405 assert( COUNT == count ); 406 SVGA_FIFOCommitAll( svga->swc ); 407 408 return PIPE_OK; 409 } 410} 411 412 413void 414svga_init_tracked_state(struct svga_context *svga) 415{ 416 /* Set the hw_draw_state atom list to the one for the particular gpu version. 417 */ 418 state_levels[2] = 419 svga_have_gl43(svga) ? hw_draw_state_gl43 : 420 (svga_have_sm5(svga) ? hw_draw_state_sm5 : 421 ((svga_have_vgpu10(svga) ? hw_draw_state_vgpu10 : 422 hw_draw_state_vgpu9))); 423} 424 425 426static const struct svga_tracked_state *compute_state[] = 427{ 428 &svga_hw_cs_uav, 429 &svga_hw_cs_sampler, 430 &svga_hw_cs_sampler_bindings, 431 &svga_hw_cs, 432 &svga_hw_cs_constants, 433 &svga_hw_cs_constbufs, 434 NULL 435}; 436 437/** 438 * Update compute state. 439 * If the first attempt fails, flush the command buffer and retry. 440 * \return true if success, false if second attempt fails. 441 */ 442bool 443svga_update_compute_state(struct svga_context *svga) 444{ 445 enum pipe_error ret = PIPE_OK; 446 uint64_t compute_dirty = svga->dirty; 447 448 if (compute_dirty) { 449 SVGA_RETRY_OOM(svga, ret, update_state(svga, compute_state, 450 &compute_dirty)); 451 452 /* Set the dirty flag to the remaining dirty bits which are 453 * not processed in the compute pipeline. 454 */ 455 svga->dirty = compute_dirty; 456 } 457 458 return ret == PIPE_OK; 459} 460