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.

nv50_state_validate.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #include "nv50_context.h"
  2. #include "os/os_time.h"
  3. static void
  4. nv50_validate_fb(struct nv50_context *nv50)
  5. {
  6. struct nouveau_channel *chan = nv50->screen->base.channel;
  7. struct pipe_framebuffer_state *fb = &nv50->framebuffer;
  8. unsigned i;
  9. unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
  10. boolean serialize = FALSE;
  11. nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
  12. BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
  13. OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs);
  14. BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
  15. OUT_RING (chan, fb->width << 16);
  16. OUT_RING (chan, fb->height << 16);
  17. MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
  18. for (i = 0; i < fb->nr_cbufs; ++i) {
  19. struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
  20. struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
  21. struct nouveau_bo *bo = mt->base.bo;
  22. uint32_t offset = sf->offset;
  23. BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5);
  24. OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  25. OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  26. OUT_RING (chan, nv50_format_table[sf->base.format].rt);
  27. OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
  28. OUT_RING (chan, mt->layer_stride >> 2);
  29. BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
  30. OUT_RING (chan, sf->width);
  31. OUT_RING (chan, sf->height);
  32. BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
  33. OUT_RING (chan, sf->depth);
  34. ms_mode = mt->ms_mode;
  35. if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
  36. serialize = TRUE;
  37. mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
  38. mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
  39. /* only register for writing, otherwise we'd always serialize here */
  40. nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
  41. NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
  42. }
  43. if (fb->zsbuf) {
  44. struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
  45. struct nv50_surface *sf = nv50_surface(fb->zsbuf);
  46. struct nouveau_bo *bo = mt->base.bo;
  47. int unk = mt->base.base.target == PIPE_TEXTURE_2D;
  48. uint32_t offset = sf->offset;
  49. MARK_RING (chan, 12, 2);
  50. BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
  51. OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  52. OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  53. OUT_RING (chan, nv50_format_table[fb->zsbuf->format].rt);
  54. OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
  55. OUT_RING (chan, mt->layer_stride >> 2);
  56. BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
  57. OUT_RING (chan, 1);
  58. BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
  59. OUT_RING (chan, sf->width);
  60. OUT_RING (chan, sf->height);
  61. OUT_RING (chan, (unk << 16) | sf->depth);
  62. ms_mode = mt->ms_mode;
  63. if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
  64. serialize = TRUE;
  65. mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
  66. mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
  67. nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
  68. NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
  69. } else {
  70. BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
  71. OUT_RING (chan, 0);
  72. }
  73. BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
  74. OUT_RING (chan, ms_mode);
  75. BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
  76. OUT_RING (chan, fb->width << 16);
  77. OUT_RING (chan, fb->height << 16);
  78. if (serialize) {
  79. BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
  80. OUT_RING (chan, 0);
  81. }
  82. }
  83. static void
  84. nv50_validate_blend_colour(struct nv50_context *nv50)
  85. {
  86. struct nouveau_channel *chan = nv50->screen->base.channel;
  87. BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
  88. OUT_RINGf (chan, nv50->blend_colour.color[0]);
  89. OUT_RINGf (chan, nv50->blend_colour.color[1]);
  90. OUT_RINGf (chan, nv50->blend_colour.color[2]);
  91. OUT_RINGf (chan, nv50->blend_colour.color[3]);
  92. }
  93. static void
  94. nv50_validate_stencil_ref(struct nv50_context *nv50)
  95. {
  96. struct nouveau_channel *chan = nv50->screen->base.channel;
  97. BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1);
  98. OUT_RING (chan, nv50->stencil_ref.ref_value[0]);
  99. BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1);
  100. OUT_RING (chan, nv50->stencil_ref.ref_value[1]);
  101. }
  102. static void
  103. nv50_validate_stipple(struct nv50_context *nv50)
  104. {
  105. struct nouveau_channel *chan = nv50->screen->base.channel;
  106. unsigned i;
  107. BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
  108. for (i = 0; i < 32; ++i)
  109. OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i]));
  110. }
  111. static void
  112. nv50_validate_scissor(struct nv50_context *nv50)
  113. {
  114. struct nouveau_channel *chan = nv50->screen->base.channel;
  115. struct pipe_scissor_state *s = &nv50->scissor;
  116. #ifdef NV50_SCISSORS_CLIPPING
  117. struct pipe_viewport_state *vp = &nv50->viewport;
  118. int minx, maxx, miny, maxy;
  119. if (!(nv50->dirty &
  120. (NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | NV50_NEW_FRAMEBUFFER)) &&
  121. nv50->state.scissor == nv50->rast->pipe.scissor)
  122. return;
  123. nv50->state.scissor = nv50->rast->pipe.scissor;
  124. if (nv50->state.scissor) {
  125. minx = s->minx;
  126. maxx = s->maxx;
  127. miny = s->miny;
  128. maxy = s->maxy;
  129. } else {
  130. minx = 0;
  131. maxx = nv50->framebuffer.width;
  132. miny = 0;
  133. maxy = nv50->framebuffer.height;
  134. }
  135. minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0])));
  136. maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0])));
  137. miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
  138. maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
  139. BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
  140. OUT_RING (chan, (maxx << 16) | minx);
  141. OUT_RING (chan, (maxy << 16) | miny);
  142. #else
  143. BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
  144. OUT_RING (chan, (s->maxx << 16) | s->minx);
  145. OUT_RING (chan, (s->maxy << 16) | s->miny);
  146. #endif
  147. }
  148. static void
  149. nv50_validate_viewport(struct nv50_context *nv50)
  150. {
  151. struct nouveau_channel *chan = nv50->screen->base.channel;
  152. float zmin, zmax;
  153. BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
  154. OUT_RINGf (chan, nv50->viewport.translate[0]);
  155. OUT_RINGf (chan, nv50->viewport.translate[1]);
  156. OUT_RINGf (chan, nv50->viewport.translate[2]);
  157. BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
  158. OUT_RINGf (chan, nv50->viewport.scale[0]);
  159. OUT_RINGf (chan, nv50->viewport.scale[1]);
  160. OUT_RINGf (chan, nv50->viewport.scale[2]);
  161. zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]);
  162. zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
  163. #ifdef NV50_SCISSORS_CLIPPING
  164. BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
  165. OUT_RINGf (chan, zmin);
  166. OUT_RINGf (chan, zmax);
  167. #endif
  168. }
  169. static void
  170. nv50_validate_clip(struct nv50_context *nv50)
  171. {
  172. struct nouveau_channel *chan = nv50->screen->base.channel;
  173. uint32_t clip;
  174. if (nv50->clip.depth_clamp) {
  175. clip =
  176. NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR |
  177. NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR |
  178. NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
  179. } else {
  180. clip = 0;
  181. }
  182. #ifndef NV50_SCISSORS_CLIPPING
  183. clip |=
  184. NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 |
  185. NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
  186. #endif
  187. BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
  188. OUT_RING (chan, clip);
  189. if (nv50->clip.nr) {
  190. BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
  191. OUT_RING (chan, (0 << 8) | NV50_CB_AUX);
  192. BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nv50->clip.nr * 4);
  193. OUT_RINGp (chan, &nv50->clip.ucp[0][0], nv50->clip.nr * 4);
  194. }
  195. BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
  196. OUT_RING (chan, (1 << nv50->clip.nr) - 1);
  197. if (nv50->vertprog && nv50->clip.nr > nv50->vertprog->vp.clpd_nr)
  198. nv50->dirty |= NV50_NEW_VERTPROG;
  199. }
  200. static void
  201. nv50_validate_blend(struct nv50_context *nv50)
  202. {
  203. struct nouveau_channel *chan = nv50->screen->base.channel;
  204. WAIT_RING(chan, nv50->blend->size);
  205. OUT_RINGp(chan, nv50->blend->state, nv50->blend->size);
  206. }
  207. static void
  208. nv50_validate_zsa(struct nv50_context *nv50)
  209. {
  210. struct nouveau_channel *chan = nv50->screen->base.channel;
  211. WAIT_RING(chan, nv50->zsa->size);
  212. OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size);
  213. }
  214. static void
  215. nv50_validate_rasterizer(struct nv50_context *nv50)
  216. {
  217. struct nouveau_channel *chan = nv50->screen->base.channel;
  218. WAIT_RING(chan, nv50->rast->size);
  219. OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
  220. }
  221. static void
  222. nv50_validate_sample_mask(struct nv50_context *nv50)
  223. {
  224. struct nouveau_channel *chan = nv50->screen->base.channel;
  225. unsigned mask[4] =
  226. {
  227. nv50->sample_mask & 0xffff,
  228. nv50->sample_mask & 0xffff,
  229. nv50->sample_mask & 0xffff,
  230. nv50->sample_mask & 0xffff
  231. };
  232. BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
  233. OUT_RING (chan, mask[0]);
  234. OUT_RING (chan, mask[1]);
  235. OUT_RING (chan, mask[2]);
  236. OUT_RING (chan, mask[3]);
  237. }
  238. static void
  239. nv50_switch_pipe_context(struct nv50_context *ctx_to)
  240. {
  241. struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
  242. if (ctx_from)
  243. ctx_to->state = ctx_from->state;
  244. ctx_to->dirty = ~0;
  245. if (!ctx_to->vertex)
  246. ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS);
  247. if (!ctx_to->vertprog)
  248. ctx_to->dirty &= ~NV50_NEW_VERTPROG;
  249. if (!ctx_to->fragprog)
  250. ctx_to->dirty &= ~NV50_NEW_FRAGPROG;
  251. if (!ctx_to->blend)
  252. ctx_to->dirty &= ~NV50_NEW_BLEND;
  253. if (!ctx_to->rast)
  254. #ifdef NV50_SCISSORS_CLIPPING
  255. ctx_to->dirty &= ~(NV50_NEW_RASTERIZER | NV50_NEW_SCISSOR);
  256. #else
  257. ctx_to->dirty &= ~NV50_NEW_RASTERIZER;
  258. #endif
  259. if (!ctx_to->zsa)
  260. ctx_to->dirty &= ~NV50_NEW_ZSA;
  261. ctx_to->screen->cur_ctx = ctx_to;
  262. }
  263. static struct state_validate {
  264. void (*func)(struct nv50_context *);
  265. uint32_t states;
  266. } validate_list[] = {
  267. { nv50_validate_fb, NV50_NEW_FRAMEBUFFER },
  268. { nv50_validate_blend, NV50_NEW_BLEND },
  269. { nv50_validate_zsa, NV50_NEW_ZSA },
  270. { nv50_validate_sample_mask, NV50_NEW_SAMPLE_MASK },
  271. { nv50_validate_rasterizer, NV50_NEW_RASTERIZER },
  272. { nv50_validate_blend_colour, NV50_NEW_BLEND_COLOUR },
  273. { nv50_validate_stencil_ref, NV50_NEW_STENCIL_REF },
  274. { nv50_validate_stipple, NV50_NEW_STIPPLE },
  275. #ifdef NV50_SCISSORS_CLIPPING
  276. { nv50_validate_scissor, NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT |
  277. NV50_NEW_RASTERIZER |
  278. NV50_NEW_FRAMEBUFFER },
  279. #else
  280. { nv50_validate_scissor, NV50_NEW_SCISSOR },
  281. #endif
  282. { nv50_validate_viewport, NV50_NEW_VIEWPORT },
  283. { nv50_validate_clip, NV50_NEW_CLIP },
  284. { nv50_vertprog_validate, NV50_NEW_VERTPROG },
  285. { nv50_gmtyprog_validate, NV50_NEW_GMTYPROG },
  286. { nv50_fragprog_validate, NV50_NEW_FRAGPROG },
  287. { nv50_fp_linkage_validate, NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
  288. NV50_NEW_GMTYPROG },
  289. { nv50_gp_linkage_validate, NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG },
  290. { nv50_validate_derived_rs, NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER |
  291. NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
  292. { nv50_constbufs_validate, NV50_NEW_CONSTBUF },
  293. { nv50_validate_textures, NV50_NEW_TEXTURES },
  294. { nv50_validate_samplers, NV50_NEW_SAMPLERS },
  295. { nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS }
  296. };
  297. #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
  298. boolean
  299. nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
  300. {
  301. uint32_t state_mask;
  302. unsigned i;
  303. if (nv50->screen->cur_ctx != nv50)
  304. nv50_switch_pipe_context(nv50);
  305. state_mask = nv50->dirty & mask;
  306. if (state_mask) {
  307. for (i = 0; i < validate_list_len; ++i) {
  308. struct state_validate *validate = &validate_list[i];
  309. if (state_mask & validate->states)
  310. validate->func(nv50);
  311. }
  312. nv50->dirty &= ~state_mask;
  313. }
  314. MARK_RING(nv50->screen->base.channel, words, 0);
  315. nv50_bufctx_emit_relocs(nv50);
  316. return TRUE;
  317. }