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.

nv40_state.c 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. #include "pipe/p_state.h"
  2. #include "pipe/p_defines.h"
  3. #include "util/u_inlines.h"
  4. #include "draw/draw_context.h"
  5. #include "tgsi/tgsi_parse.h"
  6. #include "nv40_context.h"
  7. #include "nv40_state.h"
  8. static void *
  9. nv40_blend_state_create(struct pipe_context *pipe,
  10. const struct pipe_blend_state *cso)
  11. {
  12. struct nv40_context *nv40 = nv40_context(pipe);
  13. struct nouveau_grobj *curie = nv40->screen->curie;
  14. struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso));
  15. struct nouveau_stateobj *so = so_new(5, 8, 0);
  16. if (cso->rt[0].blend_enable) {
  17. so_method(so, curie, NV40TCL_BLEND_ENABLE, 3);
  18. so_data (so, 1);
  19. so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) |
  20. nvgl_blend_func(cso->rt[0].rgb_src_factor));
  21. so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 |
  22. nvgl_blend_func(cso->rt[0].rgb_dst_factor));
  23. so_method(so, curie, NV40TCL_BLEND_EQUATION, 1);
  24. so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func) << 16 |
  25. nvgl_blend_eqn(cso->rt[0].rgb_func));
  26. } else {
  27. so_method(so, curie, NV40TCL_BLEND_ENABLE, 1);
  28. so_data (so, 0);
  29. }
  30. so_method(so, curie, NV40TCL_COLOR_MASK, 1);
  31. so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) |
  32. ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) |
  33. ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) |
  34. ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0)));
  35. if (cso->logicop_enable) {
  36. so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 2);
  37. so_data (so, 1);
  38. so_data (so, nvgl_logicop_func(cso->logicop_func));
  39. } else {
  40. so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 1);
  41. so_data (so, 0);
  42. }
  43. so_method(so, curie, NV40TCL_DITHER_ENABLE, 1);
  44. so_data (so, cso->dither ? 1 : 0);
  45. so_ref(so, &bso->so);
  46. so_ref(NULL, &so);
  47. bso->pipe = *cso;
  48. return (void *)bso;
  49. }
  50. static void
  51. nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso)
  52. {
  53. struct nv40_context *nv40 = nv40_context(pipe);
  54. nv40->blend = hwcso;
  55. nv40->dirty |= NV40_NEW_BLEND;
  56. }
  57. static void
  58. nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso)
  59. {
  60. struct nv40_blend_state *bso = hwcso;
  61. so_ref(NULL, &bso->so);
  62. FREE(bso);
  63. }
  64. static INLINE unsigned
  65. wrap_mode(unsigned wrap) {
  66. unsigned ret;
  67. switch (wrap) {
  68. case PIPE_TEX_WRAP_REPEAT:
  69. ret = NV40TCL_TEX_WRAP_S_REPEAT;
  70. break;
  71. case PIPE_TEX_WRAP_MIRROR_REPEAT:
  72. ret = NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT;
  73. break;
  74. case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
  75. ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_EDGE;
  76. break;
  77. case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
  78. ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER;
  79. break;
  80. case PIPE_TEX_WRAP_CLAMP:
  81. ret = NV40TCL_TEX_WRAP_S_CLAMP;
  82. break;
  83. case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
  84. ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
  85. break;
  86. case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
  87. ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
  88. break;
  89. case PIPE_TEX_WRAP_MIRROR_CLAMP:
  90. ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
  91. break;
  92. default:
  93. NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
  94. ret = NV40TCL_TEX_WRAP_S_REPEAT;
  95. break;
  96. }
  97. return ret >> NV40TCL_TEX_WRAP_S_SHIFT;
  98. }
  99. static void *
  100. nv40_sampler_state_create(struct pipe_context *pipe,
  101. const struct pipe_sampler_state *cso)
  102. {
  103. struct nv40_sampler_state *ps;
  104. uint32_t filter = 0;
  105. ps = MALLOC(sizeof(struct nv40_sampler_state));
  106. ps->fmt = 0;
  107. if (!cso->normalized_coords)
  108. ps->fmt |= NV40TCL_TEX_FORMAT_RECT;
  109. ps->wrap = ((wrap_mode(cso->wrap_s) << NV40TCL_TEX_WRAP_S_SHIFT) |
  110. (wrap_mode(cso->wrap_t) << NV40TCL_TEX_WRAP_T_SHIFT) |
  111. (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT));
  112. ps->en = 0;
  113. if (cso->max_anisotropy >= 2) {
  114. /* no idea, binary driver sets it, works without it.. meh.. */
  115. ps->wrap |= (1 << 5);
  116. if (cso->max_anisotropy >= 16) {
  117. ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
  118. } else
  119. if (cso->max_anisotropy >= 12) {
  120. ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
  121. } else
  122. if (cso->max_anisotropy >= 10) {
  123. ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
  124. } else
  125. if (cso->max_anisotropy >= 8) {
  126. ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
  127. } else
  128. if (cso->max_anisotropy >= 6) {
  129. ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
  130. } else
  131. if (cso->max_anisotropy >= 4) {
  132. ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
  133. } else {
  134. ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
  135. }
  136. }
  137. switch (cso->mag_img_filter) {
  138. case PIPE_TEX_FILTER_LINEAR:
  139. filter |= NV40TCL_TEX_FILTER_MAG_LINEAR;
  140. break;
  141. case PIPE_TEX_FILTER_NEAREST:
  142. default:
  143. filter |= NV40TCL_TEX_FILTER_MAG_NEAREST;
  144. break;
  145. }
  146. switch (cso->min_img_filter) {
  147. case PIPE_TEX_FILTER_LINEAR:
  148. switch (cso->min_mip_filter) {
  149. case PIPE_TEX_MIPFILTER_NEAREST:
  150. filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST;
  151. break;
  152. case PIPE_TEX_MIPFILTER_LINEAR:
  153. filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR;
  154. break;
  155. case PIPE_TEX_MIPFILTER_NONE:
  156. default:
  157. filter |= NV40TCL_TEX_FILTER_MIN_LINEAR;
  158. break;
  159. }
  160. break;
  161. case PIPE_TEX_FILTER_NEAREST:
  162. default:
  163. switch (cso->min_mip_filter) {
  164. case PIPE_TEX_MIPFILTER_NEAREST:
  165. filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST;
  166. break;
  167. case PIPE_TEX_MIPFILTER_LINEAR:
  168. filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR;
  169. break;
  170. case PIPE_TEX_MIPFILTER_NONE:
  171. default:
  172. filter |= NV40TCL_TEX_FILTER_MIN_NEAREST;
  173. break;
  174. }
  175. break;
  176. }
  177. ps->filt = filter;
  178. {
  179. float limit;
  180. limit = CLAMP(cso->lod_bias, -16.0, 15.0);
  181. ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
  182. limit = CLAMP(cso->max_lod, 0.0, 15.0);
  183. ps->en |= (int)(limit * 256.0) << 7;
  184. limit = CLAMP(cso->min_lod, 0.0, 15.0);
  185. ps->en |= (int)(limit * 256.0) << 19;
  186. }
  187. if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
  188. switch (cso->compare_func) {
  189. case PIPE_FUNC_NEVER:
  190. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NEVER;
  191. break;
  192. case PIPE_FUNC_GREATER:
  193. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GREATER;
  194. break;
  195. case PIPE_FUNC_EQUAL:
  196. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_EQUAL;
  197. break;
  198. case PIPE_FUNC_GEQUAL:
  199. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GEQUAL;
  200. break;
  201. case PIPE_FUNC_LESS:
  202. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LESS;
  203. break;
  204. case PIPE_FUNC_NOTEQUAL:
  205. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NOTEQUAL;
  206. break;
  207. case PIPE_FUNC_LEQUAL:
  208. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LEQUAL;
  209. break;
  210. case PIPE_FUNC_ALWAYS:
  211. ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_ALWAYS;
  212. break;
  213. default:
  214. break;
  215. }
  216. }
  217. ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
  218. (float_to_ubyte(cso->border_color[0]) << 16) |
  219. (float_to_ubyte(cso->border_color[1]) << 8) |
  220. (float_to_ubyte(cso->border_color[2]) << 0));
  221. return (void *)ps;
  222. }
  223. static void
  224. nv40_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
  225. {
  226. struct nv40_context *nv40 = nv40_context(pipe);
  227. unsigned unit;
  228. for (unit = 0; unit < nr; unit++) {
  229. nv40->tex_sampler[unit] = sampler[unit];
  230. nv40->dirty_samplers |= (1 << unit);
  231. }
  232. for (unit = nr; unit < nv40->nr_samplers; unit++) {
  233. nv40->tex_sampler[unit] = NULL;
  234. nv40->dirty_samplers |= (1 << unit);
  235. }
  236. nv40->nr_samplers = nr;
  237. nv40->dirty |= NV40_NEW_SAMPLER;
  238. }
  239. static void
  240. nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
  241. {
  242. FREE(hwcso);
  243. }
  244. static void
  245. nv40_set_fragment_sampler_views(struct pipe_context *pipe,
  246. unsigned nr,
  247. struct pipe_sampler_view **views)
  248. {
  249. struct nv40_context *nv40 = nv40_context(pipe);
  250. unsigned unit;
  251. for (unit = 0; unit < nr; unit++) {
  252. pipe_sampler_view_reference(&nv40->fragment_sampler_views[unit], views[unit]);
  253. pipe_texture_reference((struct pipe_texture **)
  254. &nv40->tex_miptree[unit], views[unit]->texture);
  255. nv40->dirty_samplers |= (1 << unit);
  256. }
  257. for (unit = nr; unit < nv40->nr_textures; unit++) {
  258. pipe_sampler_view_reference(&nv40->fragment_sampler_views[unit], NULL);
  259. pipe_texture_reference((struct pipe_texture **)
  260. &nv40->tex_miptree[unit], NULL);
  261. nv40->dirty_samplers |= (1 << unit);
  262. }
  263. nv40->nr_textures = nr;
  264. nv40->dirty |= NV40_NEW_SAMPLER;
  265. }
  266. static struct pipe_sampler_view *
  267. nv40_create_sampler_view(struct pipe_context *pipe,
  268. struct pipe_texture *texture,
  269. const struct pipe_sampler_view *templ)
  270. {
  271. struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
  272. if (view) {
  273. *view = *templ;
  274. view->reference.count = 1;
  275. view->texture = NULL;
  276. pipe_texture_reference(&view->texture, texture);
  277. view->context = pipe;
  278. }
  279. return view;
  280. }
  281. static void
  282. nv40_sampler_view_destroy(struct pipe_context *pipe,
  283. struct pipe_sampler_view *view)
  284. {
  285. pipe_texture_reference(&view->texture, NULL);
  286. FREE(view);
  287. }
  288. static void *
  289. nv40_rasterizer_state_create(struct pipe_context *pipe,
  290. const struct pipe_rasterizer_state *cso)
  291. {
  292. struct nv40_context *nv40 = nv40_context(pipe);
  293. struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
  294. struct nouveau_stateobj *so = so_new(9, 19, 0);
  295. struct nouveau_grobj *curie = nv40->screen->curie;
  296. /*XXX: ignored:
  297. * light_twoside
  298. * point_smooth -nohw
  299. * multisample
  300. */
  301. so_method(so, curie, NV40TCL_SHADE_MODEL, 1);
  302. so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT :
  303. NV40TCL_SHADE_MODEL_SMOOTH);
  304. so_method(so, curie, NV40TCL_LINE_WIDTH, 2);
  305. so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
  306. so_data (so, cso->line_smooth ? 1 : 0);
  307. so_method(so, curie, NV40TCL_LINE_STIPPLE_ENABLE, 2);
  308. so_data (so, cso->line_stipple_enable ? 1 : 0);
  309. so_data (so, (cso->line_stipple_pattern << 16) |
  310. cso->line_stipple_factor);
  311. so_method(so, curie, NV40TCL_POINT_SIZE, 1);
  312. so_data (so, fui(cso->point_size));
  313. so_method(so, curie, NV40TCL_POLYGON_MODE_FRONT, 6);
  314. if (cso->front_winding == PIPE_WINDING_CCW) {
  315. so_data(so, nvgl_polygon_mode(cso->fill_ccw));
  316. so_data(so, nvgl_polygon_mode(cso->fill_cw));
  317. switch (cso->cull_mode) {
  318. case PIPE_WINDING_CCW:
  319. so_data(so, NV40TCL_CULL_FACE_FRONT);
  320. break;
  321. case PIPE_WINDING_CW:
  322. so_data(so, NV40TCL_CULL_FACE_BACK);
  323. break;
  324. case PIPE_WINDING_BOTH:
  325. so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK);
  326. break;
  327. default:
  328. so_data(so, NV40TCL_CULL_FACE_BACK);
  329. break;
  330. }
  331. so_data(so, NV40TCL_FRONT_FACE_CCW);
  332. } else {
  333. so_data(so, nvgl_polygon_mode(cso->fill_cw));
  334. so_data(so, nvgl_polygon_mode(cso->fill_ccw));
  335. switch (cso->cull_mode) {
  336. case PIPE_WINDING_CCW:
  337. so_data(so, NV40TCL_CULL_FACE_BACK);
  338. break;
  339. case PIPE_WINDING_CW:
  340. so_data(so, NV40TCL_CULL_FACE_FRONT);
  341. break;
  342. case PIPE_WINDING_BOTH:
  343. so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK);
  344. break;
  345. default:
  346. so_data(so, NV40TCL_CULL_FACE_BACK);
  347. break;
  348. }
  349. so_data(so, NV40TCL_FRONT_FACE_CW);
  350. }
  351. so_data(so, cso->poly_smooth ? 1 : 0);
  352. so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0);
  353. so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
  354. so_data (so, cso->poly_stipple_enable ? 1 : 0);
  355. so_method(so, curie, NV40TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
  356. if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
  357. (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
  358. so_data(so, 1);
  359. else
  360. so_data(so, 0);
  361. if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
  362. (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
  363. so_data(so, 1);
  364. else
  365. so_data(so, 0);
  366. if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
  367. (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
  368. so_data(so, 1);
  369. else
  370. so_data(so, 0);
  371. if (cso->offset_cw || cso->offset_ccw) {
  372. so_method(so, curie, NV40TCL_POLYGON_OFFSET_FACTOR, 2);
  373. so_data (so, fui(cso->offset_scale));
  374. so_data (so, fui(cso->offset_units * 2));
  375. }
  376. so_method(so, curie, NV40TCL_POINT_SPRITE, 1);
  377. if (cso->point_quad_rasterization) {
  378. unsigned psctl = (1 << 0), i;
  379. for (i = 0; i < 8; i++) {
  380. if ((cso->sprite_coord_enable >> i) & 1)
  381. psctl |= (1 << (8 + i));
  382. }
  383. so_data(so, psctl);
  384. } else {
  385. so_data(so, 0);
  386. }
  387. so_ref(so, &rsso->so);
  388. so_ref(NULL, &so);
  389. rsso->pipe = *cso;
  390. return (void *)rsso;
  391. }
  392. static void
  393. nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
  394. {
  395. struct nv40_context *nv40 = nv40_context(pipe);
  396. nv40->rasterizer = hwcso;
  397. nv40->dirty |= NV40_NEW_RAST;
  398. nv40->draw_dirty |= NV40_NEW_RAST;
  399. }
  400. static void
  401. nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
  402. {
  403. struct nv40_rasterizer_state *rsso = hwcso;
  404. so_ref(NULL, &rsso->so);
  405. FREE(rsso);
  406. }
  407. static void *
  408. nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
  409. const struct pipe_depth_stencil_alpha_state *cso)
  410. {
  411. struct nv40_context *nv40 = nv40_context(pipe);
  412. struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
  413. struct nouveau_stateobj *so = so_new(6, 20, 0);
  414. struct nouveau_grobj *curie = nv40->screen->curie;
  415. so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
  416. so_data (so, nvgl_comparison_op(cso->depth.func));
  417. so_data (so, cso->depth.writemask ? 1 : 0);
  418. so_data (so, cso->depth.enabled ? 1 : 0);
  419. so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
  420. so_data (so, cso->alpha.enabled ? 1 : 0);
  421. so_data (so, nvgl_comparison_op(cso->alpha.func));
  422. so_data (so, float_to_ubyte(cso->alpha.ref_value));
  423. if (cso->stencil[0].enabled) {
  424. so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 3);
  425. so_data (so, cso->stencil[0].enabled ? 1 : 0);
  426. so_data (so, cso->stencil[0].writemask);
  427. so_data (so, nvgl_comparison_op(cso->stencil[0].func));
  428. so_method(so, curie, NV40TCL_STENCIL_FRONT_FUNC_MASK, 4);
  429. so_data (so, cso->stencil[0].valuemask);
  430. so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
  431. so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
  432. so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
  433. } else {
  434. so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
  435. so_data (so, 0);
  436. }
  437. if (cso->stencil[1].enabled) {
  438. so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 3);
  439. so_data (so, cso->stencil[1].enabled ? 1 : 0);
  440. so_data (so, cso->stencil[1].writemask);
  441. so_data (so, nvgl_comparison_op(cso->stencil[1].func));
  442. so_method(so, curie, NV40TCL_STENCIL_BACK_FUNC_MASK, 4);
  443. so_data (so, cso->stencil[1].valuemask);
  444. so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
  445. so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
  446. so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
  447. } else {
  448. so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
  449. so_data (so, 0);
  450. }
  451. so_ref(so, &zsaso->so);
  452. so_ref(NULL, &so);
  453. zsaso->pipe = *cso;
  454. return (void *)zsaso;
  455. }
  456. static void
  457. nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
  458. {
  459. struct nv40_context *nv40 = nv40_context(pipe);
  460. nv40->zsa = hwcso;
  461. nv40->dirty |= NV40_NEW_ZSA;
  462. }
  463. static void
  464. nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
  465. {
  466. struct nv40_zsa_state *zsaso = hwcso;
  467. so_ref(NULL, &zsaso->so);
  468. FREE(zsaso);
  469. }
  470. static void *
  471. nv40_vp_state_create(struct pipe_context *pipe,
  472. const struct pipe_shader_state *cso)
  473. {
  474. struct nv40_context *nv40 = nv40_context(pipe);
  475. struct nv40_vertex_program *vp;
  476. vp = CALLOC(1, sizeof(struct nv40_vertex_program));
  477. vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
  478. vp->draw = draw_create_vertex_shader(nv40->draw, &vp->pipe);
  479. return (void *)vp;
  480. }
  481. static void
  482. nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso)
  483. {
  484. struct nv40_context *nv40 = nv40_context(pipe);
  485. nv40->vertprog = hwcso;
  486. nv40->dirty |= NV40_NEW_VERTPROG;
  487. nv40->draw_dirty |= NV40_NEW_VERTPROG;
  488. }
  489. static void
  490. nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso)
  491. {
  492. struct nv40_context *nv40 = nv40_context(pipe);
  493. struct nv40_vertex_program *vp = hwcso;
  494. draw_delete_vertex_shader(nv40->draw, vp->draw);
  495. nv40_vertprog_destroy(nv40, vp);
  496. FREE((void*)vp->pipe.tokens);
  497. FREE(vp);
  498. }
  499. static void *
  500. nv40_fp_state_create(struct pipe_context *pipe,
  501. const struct pipe_shader_state *cso)
  502. {
  503. struct nv40_fragment_program *fp;
  504. fp = CALLOC(1, sizeof(struct nv40_fragment_program));
  505. fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
  506. tgsi_scan_shader(fp->pipe.tokens, &fp->info);
  507. return (void *)fp;
  508. }
  509. static void
  510. nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso)
  511. {
  512. struct nv40_context *nv40 = nv40_context(pipe);
  513. nv40->fragprog = hwcso;
  514. nv40->dirty |= NV40_NEW_FRAGPROG;
  515. }
  516. static void
  517. nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso)
  518. {
  519. struct nv40_context *nv40 = nv40_context(pipe);
  520. struct nv40_fragment_program *fp = hwcso;
  521. nv40_fragprog_destroy(nv40, fp);
  522. FREE((void*)fp->pipe.tokens);
  523. FREE(fp);
  524. }
  525. static void
  526. nv40_set_blend_color(struct pipe_context *pipe,
  527. const struct pipe_blend_color *bcol)
  528. {
  529. struct nv40_context *nv40 = nv40_context(pipe);
  530. nv40->blend_colour = *bcol;
  531. nv40->dirty |= NV40_NEW_BCOL;
  532. }
  533. static void
  534. nv40_set_stencil_ref(struct pipe_context *pipe,
  535. const struct pipe_stencil_ref *sr)
  536. {
  537. struct nv40_context *nv40 = nv40_context(pipe);
  538. nv40->stencil_ref = *sr;
  539. nv40->dirty |= NV40_NEW_SR;
  540. }
  541. static void
  542. nv40_set_clip_state(struct pipe_context *pipe,
  543. const struct pipe_clip_state *clip)
  544. {
  545. struct nv40_context *nv40 = nv40_context(pipe);
  546. nv40->clip = *clip;
  547. nv40->dirty |= NV40_NEW_UCP;
  548. nv40->draw_dirty |= NV40_NEW_UCP;
  549. }
  550. static void
  551. nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
  552. struct pipe_buffer *buf )
  553. {
  554. struct nv40_context *nv40 = nv40_context(pipe);
  555. nv40->constbuf[shader] = buf;
  556. nv40->constbuf_nr[shader] = buf->size / (4 * sizeof(float));
  557. if (shader == PIPE_SHADER_VERTEX) {
  558. nv40->dirty |= NV40_NEW_VERTPROG;
  559. } else
  560. if (shader == PIPE_SHADER_FRAGMENT) {
  561. nv40->dirty |= NV40_NEW_FRAGPROG;
  562. }
  563. }
  564. static void
  565. nv40_set_framebuffer_state(struct pipe_context *pipe,
  566. const struct pipe_framebuffer_state *fb)
  567. {
  568. struct nv40_context *nv40 = nv40_context(pipe);
  569. nv40->framebuffer = *fb;
  570. nv40->dirty |= NV40_NEW_FB;
  571. }
  572. static void
  573. nv40_set_polygon_stipple(struct pipe_context *pipe,
  574. const struct pipe_poly_stipple *stipple)
  575. {
  576. struct nv40_context *nv40 = nv40_context(pipe);
  577. memcpy(nv40->stipple, stipple->stipple, 4 * 32);
  578. nv40->dirty |= NV40_NEW_STIPPLE;
  579. }
  580. static void
  581. nv40_set_scissor_state(struct pipe_context *pipe,
  582. const struct pipe_scissor_state *s)
  583. {
  584. struct nv40_context *nv40 = nv40_context(pipe);
  585. nv40->scissor = *s;
  586. nv40->dirty |= NV40_NEW_SCISSOR;
  587. }
  588. static void
  589. nv40_set_viewport_state(struct pipe_context *pipe,
  590. const struct pipe_viewport_state *vpt)
  591. {
  592. struct nv40_context *nv40 = nv40_context(pipe);
  593. nv40->viewport = *vpt;
  594. nv40->dirty |= NV40_NEW_VIEWPORT;
  595. nv40->draw_dirty |= NV40_NEW_VIEWPORT;
  596. }
  597. static void
  598. nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
  599. const struct pipe_vertex_buffer *vb)
  600. {
  601. struct nv40_context *nv40 = nv40_context(pipe);
  602. memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count);
  603. nv40->vtxbuf_nr = count;
  604. nv40->dirty |= NV40_NEW_ARRAYS;
  605. nv40->draw_dirty |= NV40_NEW_ARRAYS;
  606. }
  607. static void *
  608. nv40_vtxelts_state_create(struct pipe_context *pipe,
  609. unsigned num_elements,
  610. const struct pipe_vertex_element *elements)
  611. {
  612. struct nv40_vtxelt_state *cso = CALLOC_STRUCT(nv40_vtxelt_state);
  613. assert(num_elements < 16); /* not doing fallbacks yet */
  614. cso->num_elements = num_elements;
  615. memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
  616. /* nv40_vtxelt_construct(cso);*/
  617. return (void *)cso;
  618. }
  619. static void
  620. nv40_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
  621. {
  622. FREE(hwcso);
  623. }
  624. static void
  625. nv40_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
  626. {
  627. struct nv40_context *nv40 = nv40_context(pipe);
  628. nv40->vtxelt = hwcso;
  629. nv40->dirty |= NV40_NEW_ARRAYS;
  630. nv40->draw_dirty |= NV40_NEW_ARRAYS;
  631. }
  632. void
  633. nv40_init_state_functions(struct nv40_context *nv40)
  634. {
  635. nv40->pipe.create_blend_state = nv40_blend_state_create;
  636. nv40->pipe.bind_blend_state = nv40_blend_state_bind;
  637. nv40->pipe.delete_blend_state = nv40_blend_state_delete;
  638. nv40->pipe.create_sampler_state = nv40_sampler_state_create;
  639. nv40->pipe.bind_fragment_sampler_states = nv40_sampler_state_bind;
  640. nv40->pipe.delete_sampler_state = nv40_sampler_state_delete;
  641. nv40->pipe.set_fragment_sampler_views = nv40_set_fragment_sampler_views;
  642. nv40->pipe.create_sampler_view = nv40_create_sampler_view;
  643. nv40->pipe.sampler_view_destroy = nv40_sampler_view_destroy;
  644. nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create;
  645. nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind;
  646. nv40->pipe.delete_rasterizer_state = nv40_rasterizer_state_delete;
  647. nv40->pipe.create_depth_stencil_alpha_state =
  648. nv40_depth_stencil_alpha_state_create;
  649. nv40->pipe.bind_depth_stencil_alpha_state =
  650. nv40_depth_stencil_alpha_state_bind;
  651. nv40->pipe.delete_depth_stencil_alpha_state =
  652. nv40_depth_stencil_alpha_state_delete;
  653. nv40->pipe.create_vs_state = nv40_vp_state_create;
  654. nv40->pipe.bind_vs_state = nv40_vp_state_bind;
  655. nv40->pipe.delete_vs_state = nv40_vp_state_delete;
  656. nv40->pipe.create_fs_state = nv40_fp_state_create;
  657. nv40->pipe.bind_fs_state = nv40_fp_state_bind;
  658. nv40->pipe.delete_fs_state = nv40_fp_state_delete;
  659. nv40->pipe.set_blend_color = nv40_set_blend_color;
  660. nv40->pipe.set_stencil_ref = nv40_set_stencil_ref;
  661. nv40->pipe.set_clip_state = nv40_set_clip_state;
  662. nv40->pipe.set_constant_buffer = nv40_set_constant_buffer;
  663. nv40->pipe.set_framebuffer_state = nv40_set_framebuffer_state;
  664. nv40->pipe.set_polygon_stipple = nv40_set_polygon_stipple;
  665. nv40->pipe.set_scissor_state = nv40_set_scissor_state;
  666. nv40->pipe.set_viewport_state = nv40_set_viewport_state;
  667. nv40->pipe.create_vertex_elements_state = nv40_vtxelts_state_create;
  668. nv40->pipe.delete_vertex_elements_state = nv40_vtxelts_state_delete;
  669. nv40->pipe.bind_vertex_elements_state = nv40_vtxelts_state_bind;
  670. nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers;
  671. }