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.

nouveau_stateobj.h 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #ifndef __NOUVEAU_STATEOBJ_H__
  2. #define __NOUVEAU_STATEOBJ_H__
  3. #include "util/u_debug.h"
  4. struct nouveau_stateobj_reloc {
  5. struct nouveau_bo *bo;
  6. unsigned offset;
  7. unsigned packet;
  8. unsigned data;
  9. unsigned flags;
  10. unsigned vor;
  11. unsigned tor;
  12. };
  13. struct nouveau_stateobj {
  14. struct pipe_reference reference;
  15. unsigned *push;
  16. struct nouveau_stateobj_reloc *reloc;
  17. unsigned *cur;
  18. unsigned cur_packet;
  19. unsigned cur_reloc;
  20. };
  21. static INLINE struct nouveau_stateobj *
  22. so_new(unsigned push, unsigned reloc)
  23. {
  24. struct nouveau_stateobj *so;
  25. so = MALLOC(sizeof(struct nouveau_stateobj));
  26. pipe_reference_init(&so->reference, 1);
  27. so->push = MALLOC(sizeof(unsigned) * push);
  28. so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc);
  29. so->cur = so->push;
  30. so->cur_reloc = so->cur_packet = 0;
  31. return so;
  32. }
  33. static INLINE void
  34. so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso)
  35. {
  36. struct nouveau_stateobj *so = *pso;
  37. int i;
  38. if (pipe_reference((struct pipe_reference**)pso, &ref->reference)) {
  39. free(so->push);
  40. for (i = 0; i < so->cur_reloc; i++)
  41. nouveau_bo_ref(NULL, &so->reloc[i].bo);
  42. free(so->reloc);
  43. free(so);
  44. }
  45. }
  46. static INLINE void
  47. so_data(struct nouveau_stateobj *so, unsigned data)
  48. {
  49. (*so->cur++) = (data);
  50. so->cur_packet += 4;
  51. }
  52. static INLINE void
  53. so_datap(struct nouveau_stateobj *so, unsigned *data, unsigned size)
  54. {
  55. so->cur_packet += (4 * size);
  56. while (size--)
  57. (*so->cur++) = (*data++);
  58. }
  59. static INLINE void
  60. so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr,
  61. unsigned mthd, unsigned size)
  62. {
  63. so->cur_packet = (gr->subc << 13) | (1 << 18) | (mthd - 4);
  64. so_data(so, (gr->subc << 13) | (size << 18) | mthd);
  65. }
  66. static INLINE void
  67. so_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo,
  68. unsigned data, unsigned flags, unsigned vor, unsigned tor)
  69. {
  70. struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++];
  71. r->bo = NULL;
  72. nouveau_bo_ref(bo, &r->bo);
  73. r->offset = so->cur - so->push;
  74. r->packet = so->cur_packet;
  75. r->data = data;
  76. r->flags = flags;
  77. r->vor = vor;
  78. r->tor = tor;
  79. so_data(so, data);
  80. }
  81. static INLINE void
  82. so_dump(struct nouveau_stateobj *so)
  83. {
  84. unsigned i, nr = so->cur - so->push;
  85. for (i = 0; i < nr; i++)
  86. debug_printf("+0x%04x: 0x%08x\n", i, so->push[i]);
  87. }
  88. static INLINE void
  89. so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so)
  90. {
  91. struct nouveau_pushbuf *pb = chan->pushbuf;
  92. unsigned nr, i;
  93. nr = so->cur - so->push;
  94. if (pb->remaining < nr)
  95. nouveau_pushbuf_flush(chan, nr);
  96. pb->remaining -= nr;
  97. memcpy(pb->cur, so->push, nr * 4);
  98. for (i = 0; i < so->cur_reloc; i++) {
  99. struct nouveau_stateobj_reloc *r = &so->reloc[i];
  100. nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset,
  101. r->bo, r->data, 0, r->flags,
  102. r->vor, r->tor);
  103. }
  104. pb->cur += nr;
  105. }
  106. static INLINE void
  107. so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so)
  108. {
  109. struct nouveau_pushbuf *pb = chan->pushbuf;
  110. unsigned i;
  111. if (!so)
  112. return;
  113. i = so->cur_reloc << 1;
  114. if (pb->remaining < i)
  115. nouveau_pushbuf_flush(chan, i);
  116. pb->remaining -= i;
  117. for (i = 0; i < so->cur_reloc; i++) {
  118. struct nouveau_stateobj_reloc *r = &so->reloc[i];
  119. nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0,
  120. (r->flags & (NOUVEAU_BO_VRAM |
  121. NOUVEAU_BO_GART |
  122. NOUVEAU_BO_RDWR)) |
  123. NOUVEAU_BO_DUMMY, 0, 0);
  124. nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0,
  125. r->flags | NOUVEAU_BO_DUMMY,
  126. r->vor, r->tor);
  127. }
  128. }
  129. #endif