Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

svga_state.c 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. #include "util/u_bitmask.h"
  26. #include "util/u_debug.h"
  27. #include "pipe/p_defines.h"
  28. #include "util/u_memory.h"
  29. #include "draw/draw_context.h"
  30. #include "svga_context.h"
  31. #include "svga_screen.h"
  32. #include "svga_state.h"
  33. #include "svga_draw.h"
  34. #include "svga_cmd.h"
  35. #include "svga_hw_reg.h"
  36. /* This is just enough to decide whether we need to use the draw
  37. * module (swtnl) or not.
  38. */
  39. static const struct svga_tracked_state *need_swtnl_state[] =
  40. {
  41. &svga_update_need_swvfetch,
  42. &svga_update_need_pipeline,
  43. &svga_update_need_swtnl,
  44. NULL
  45. };
  46. /* Atoms to update hardware state prior to emitting a clear or draw
  47. * packet.
  48. */
  49. static const struct svga_tracked_state *hw_clear_state[] =
  50. {
  51. &svga_hw_scissor,
  52. &svga_hw_viewport,
  53. &svga_hw_framebuffer,
  54. NULL
  55. };
  56. /* Atoms to update hardware state prior to emitting a draw packet.
  57. */
  58. static const struct svga_tracked_state *hw_draw_state[] =
  59. {
  60. &svga_need_tgsi_transform,
  61. &svga_hw_fs,
  62. &svga_hw_gs,
  63. &svga_hw_vs,
  64. &svga_hw_rss,
  65. &svga_hw_sampler, /* VGPU10 */
  66. &svga_hw_sampler_bindings, /* VGPU10 */
  67. &svga_hw_tss, /* pre-VGPU10 */
  68. &svga_hw_tss_binding, /* pre-VGPU10 */
  69. &svga_hw_clip_planes,
  70. &svga_hw_vdecl,
  71. &svga_hw_fs_constants,
  72. &svga_hw_gs_constants,
  73. &svga_hw_vs_constants,
  74. NULL
  75. };
  76. static const struct svga_tracked_state *swtnl_draw_state[] =
  77. {
  78. &svga_update_swtnl_draw,
  79. &svga_update_swtnl_vdecl,
  80. NULL
  81. };
  82. /* Flattens the graph of state dependencies. Could swap the positions
  83. * of hw_clear_state and need_swtnl_state without breaking anything.
  84. */
  85. static const struct svga_tracked_state **state_levels[] =
  86. {
  87. need_swtnl_state,
  88. hw_clear_state,
  89. hw_draw_state,
  90. swtnl_draw_state
  91. };
  92. static unsigned check_state( unsigned a,
  93. unsigned b )
  94. {
  95. return (a & b);
  96. }
  97. static void accumulate_state( unsigned *a,
  98. unsigned b )
  99. {
  100. *a |= b;
  101. }
  102. static void xor_states( unsigned *result,
  103. unsigned a,
  104. unsigned b )
  105. {
  106. *result = a ^ b;
  107. }
  108. static enum pipe_error
  109. update_state(struct svga_context *svga,
  110. const struct svga_tracked_state *atoms[],
  111. unsigned *state)
  112. {
  113. #ifdef DEBUG
  114. boolean debug = TRUE;
  115. #else
  116. boolean debug = FALSE;
  117. #endif
  118. enum pipe_error ret = PIPE_OK;
  119. unsigned i;
  120. ret = svga_hwtnl_flush( svga->hwtnl );
  121. if (ret != PIPE_OK)
  122. return ret;
  123. if (debug) {
  124. /* Debug version which enforces various sanity checks on the
  125. * state flags which are generated and checked to help ensure
  126. * state atoms are ordered correctly in the list.
  127. */
  128. unsigned examined, prev;
  129. examined = 0;
  130. prev = *state;
  131. for (i = 0; atoms[i] != NULL; i++) {
  132. unsigned generated;
  133. assert(atoms[i]->dirty);
  134. assert(atoms[i]->update);
  135. if (check_state(*state, atoms[i]->dirty)) {
  136. if (0)
  137. debug_printf("update: %s\n", atoms[i]->name);
  138. ret = atoms[i]->update( svga, *state );
  139. if (ret != PIPE_OK)
  140. return ret;
  141. }
  142. /* generated = (prev ^ state)
  143. * if (examined & generated)
  144. * fail;
  145. */
  146. xor_states(&generated, prev, *state);
  147. if (check_state(examined, generated)) {
  148. debug_printf("state atom %s generated state already examined\n",
  149. atoms[i]->name);
  150. assert(0);
  151. }
  152. prev = *state;
  153. accumulate_state(&examined, atoms[i]->dirty);
  154. }
  155. }
  156. else {
  157. for (i = 0; atoms[i] != NULL; i++) {
  158. if (check_state(*state, atoms[i]->dirty)) {
  159. ret = atoms[i]->update( svga, *state );
  160. if (ret != PIPE_OK)
  161. return ret;
  162. }
  163. }
  164. }
  165. return PIPE_OK;
  166. }
  167. enum pipe_error
  168. svga_update_state(struct svga_context *svga, unsigned max_level)
  169. {
  170. struct svga_screen *screen = svga_screen(svga->pipe.screen);
  171. enum pipe_error ret = PIPE_OK;
  172. unsigned i;
  173. SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE);
  174. /* Check for updates to bound textures. This can't be done in an
  175. * atom as there is no flag which could provoke this test, and we
  176. * cannot create one.
  177. */
  178. if (svga->state.texture_timestamp != screen->texture_timestamp) {
  179. svga->state.texture_timestamp = screen->texture_timestamp;
  180. svga->dirty |= SVGA_NEW_TEXTURE;
  181. }
  182. for (i = 0; i <= max_level; i++) {
  183. svga->dirty |= svga->state.dirty[i];
  184. if (svga->dirty) {
  185. ret = update_state( svga,
  186. state_levels[i],
  187. &svga->dirty );
  188. if (ret != PIPE_OK)
  189. goto done;
  190. svga->state.dirty[i] = 0;
  191. }
  192. }
  193. for (; i < SVGA_STATE_MAX; i++)
  194. svga->state.dirty[i] |= svga->dirty;
  195. svga->dirty = 0;
  196. svga->hud.num_validations++;
  197. done:
  198. SVGA_STATS_TIME_POP(screen->sws);
  199. return ret;
  200. }
  201. void svga_update_state_retry( struct svga_context *svga,
  202. unsigned max_level )
  203. {
  204. enum pipe_error ret;
  205. ret = svga_update_state( svga, max_level );
  206. if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
  207. svga_context_flush(svga, NULL);
  208. ret = svga_update_state( svga, max_level );
  209. }
  210. assert( ret == PIPE_OK );
  211. }
  212. #define EMIT_RS(_rs, _count, _name, _value) \
  213. do { \
  214. _rs[_count].state = _name; \
  215. _rs[_count].uintValue = _value; \
  216. _count++; \
  217. } while (0)
  218. /* Setup any hardware state which will be constant through the life of
  219. * a context.
  220. */
  221. enum pipe_error svga_emit_initial_state( struct svga_context *svga )
  222. {
  223. if (svga_have_vgpu10(svga)) {
  224. SVGA3dRasterizerStateId id = util_bitmask_add(svga->rast_object_id_bm);
  225. enum pipe_error ret;
  226. /* XXX preliminary code */
  227. ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
  228. id,
  229. SVGA3D_FILLMODE_FILL,
  230. SVGA3D_CULL_NONE,
  231. 1, /* frontCounterClockwise */
  232. 0, /* depthBias */
  233. 0.0f, /* depthBiasClamp */
  234. 0.0f, /* slopeScaledDepthBiasClamp */
  235. 0, /* depthClampEnable */
  236. 0, /* scissorEnable */
  237. 0, /* multisampleEnable */
  238. 0, /* aalineEnable */
  239. 1.0f, /* lineWidth */
  240. 0, /* lineStippleEnable */
  241. 0, /* lineStippleFactor */
  242. 0, /* lineStipplePattern */
  243. 0); /* provokingVertexLast */
  244. assert(ret == PIPE_OK);
  245. ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, id);
  246. return ret;
  247. }
  248. else {
  249. SVGA3dRenderState *rs;
  250. unsigned count = 0;
  251. const unsigned COUNT = 2;
  252. enum pipe_error ret;
  253. ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
  254. if (ret != PIPE_OK)
  255. return ret;
  256. /* Always use D3D style coordinate space as this is the only one
  257. * which is implemented on all backends.
  258. */
  259. EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE,
  260. SVGA3D_COORDINATE_LEFTHANDED );
  261. EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
  262. assert( COUNT == count );
  263. SVGA_FIFOCommitAll( svga->swc );
  264. return PIPE_OK;
  265. }
  266. }