Clone of mesa.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

nv40_screen.c 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. #include "pipe/p_screen.h"
  2. #include "nv40_context.h"
  3. #include "nv40_screen.h"
  4. #define NV4X_GRCLASS4097_CHIPSETS 0x00000baf
  5. #define NV4X_GRCLASS4497_CHIPSETS 0x00005450
  6. #define NV6X_GRCLASS4497_CHIPSETS 0x00000088
  7. static int
  8. nv40_screen_get_param(struct pipe_screen *pscreen, int param)
  9. {
  10. struct nv40_screen *screen = nv40_screen(pscreen);
  11. switch (param) {
  12. case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
  13. return 16;
  14. case PIPE_CAP_NPOT_TEXTURES:
  15. return 1;
  16. case PIPE_CAP_TWO_SIDED_STENCIL:
  17. return 1;
  18. case PIPE_CAP_GLSL:
  19. return 0;
  20. case PIPE_CAP_ANISOTROPIC_FILTER:
  21. return 1;
  22. case PIPE_CAP_POINT_SPRITE:
  23. return 1;
  24. case PIPE_CAP_MAX_RENDER_TARGETS:
  25. return 4;
  26. case PIPE_CAP_OCCLUSION_QUERY:
  27. return 1;
  28. case PIPE_CAP_TEXTURE_SHADOW_MAP:
  29. return 1;
  30. case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
  31. return 13;
  32. case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
  33. return 10;
  34. case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
  35. return 13;
  36. case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
  37. case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
  38. return 1;
  39. case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
  40. return 0; /* We have 4 - but unsupported currently */
  41. case PIPE_CAP_TGSI_CONT_SUPPORTED:
  42. return 0;
  43. case PIPE_CAP_BLEND_EQUATION_SEPARATE:
  44. return 1;
  45. case NOUVEAU_CAP_HW_VTXBUF:
  46. return 1;
  47. case NOUVEAU_CAP_HW_IDXBUF:
  48. if (screen->curie->grclass == NV40TCL)
  49. return 1;
  50. return 0;
  51. default:
  52. NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
  53. return 0;
  54. }
  55. }
  56. static float
  57. nv40_screen_get_paramf(struct pipe_screen *pscreen, int param)
  58. {
  59. switch (param) {
  60. case PIPE_CAP_MAX_LINE_WIDTH:
  61. case PIPE_CAP_MAX_LINE_WIDTH_AA:
  62. return 10.0;
  63. case PIPE_CAP_MAX_POINT_WIDTH:
  64. case PIPE_CAP_MAX_POINT_WIDTH_AA:
  65. return 64.0;
  66. case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
  67. return 16.0;
  68. case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
  69. return 16.0;
  70. default:
  71. NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
  72. return 0.0;
  73. }
  74. }
  75. static boolean
  76. nv40_screen_surface_format_supported(struct pipe_screen *pscreen,
  77. enum pipe_format format,
  78. enum pipe_texture_target target,
  79. unsigned tex_usage, unsigned geom_flags)
  80. {
  81. if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
  82. switch (format) {
  83. case PIPE_FORMAT_A8R8G8B8_UNORM:
  84. case PIPE_FORMAT_R5G6B5_UNORM:
  85. return TRUE;
  86. default:
  87. break;
  88. }
  89. } else
  90. if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
  91. switch (format) {
  92. case PIPE_FORMAT_Z24S8_UNORM:
  93. case PIPE_FORMAT_Z24X8_UNORM:
  94. case PIPE_FORMAT_Z16_UNORM:
  95. return TRUE;
  96. default:
  97. break;
  98. }
  99. } else {
  100. switch (format) {
  101. case PIPE_FORMAT_A8R8G8B8_UNORM:
  102. case PIPE_FORMAT_A1R5G5B5_UNORM:
  103. case PIPE_FORMAT_A4R4G4B4_UNORM:
  104. case PIPE_FORMAT_R5G6B5_UNORM:
  105. case PIPE_FORMAT_R16_SNORM:
  106. case PIPE_FORMAT_L8_UNORM:
  107. case PIPE_FORMAT_A8_UNORM:
  108. case PIPE_FORMAT_I8_UNORM:
  109. case PIPE_FORMAT_A8L8_UNORM:
  110. case PIPE_FORMAT_Z16_UNORM:
  111. case PIPE_FORMAT_Z24S8_UNORM:
  112. case PIPE_FORMAT_DXT1_RGB:
  113. case PIPE_FORMAT_DXT1_RGBA:
  114. case PIPE_FORMAT_DXT3_RGBA:
  115. case PIPE_FORMAT_DXT5_RGBA:
  116. return TRUE;
  117. default:
  118. break;
  119. }
  120. }
  121. return FALSE;
  122. }
  123. static struct pipe_buffer *
  124. nv40_surface_buffer(struct pipe_surface *surf)
  125. {
  126. struct nv40_miptree *mt = (struct nv40_miptree *)surf->texture;
  127. return mt->buffer;
  128. }
  129. static void
  130. nv40_screen_destroy(struct pipe_screen *pscreen)
  131. {
  132. struct nv40_screen *screen = nv40_screen(pscreen);
  133. nouveau_resource_free(&screen->vp_exec_heap);
  134. nouveau_resource_free(&screen->vp_data_heap);
  135. nouveau_resource_free(&screen->query_heap);
  136. nouveau_notifier_free(&screen->query);
  137. nouveau_notifier_free(&screen->sync);
  138. nouveau_grobj_free(&screen->curie);
  139. nouveau_screen_fini(&screen->base);
  140. FREE(pscreen);
  141. }
  142. struct pipe_screen *
  143. nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
  144. {
  145. struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen);
  146. struct nouveau_channel *chan;
  147. struct pipe_screen *pscreen;
  148. struct nouveau_stateobj *so;
  149. unsigned curie_class = 0;
  150. int ret;
  151. if (!screen)
  152. return NULL;
  153. pscreen = &screen->base.base;
  154. ret = nouveau_screen_init(&screen->base, dev);
  155. if (ret) {
  156. nv40_screen_destroy(pscreen);
  157. return NULL;
  158. }
  159. chan = screen->base.channel;
  160. pscreen->winsys = ws;
  161. pscreen->destroy = nv40_screen_destroy;
  162. pscreen->get_param = nv40_screen_get_param;
  163. pscreen->get_paramf = nv40_screen_get_paramf;
  164. pscreen->is_format_supported = nv40_screen_surface_format_supported;
  165. nv40_screen_init_miptree_functions(pscreen);
  166. nv40_screen_init_transfer_functions(pscreen);
  167. /* 3D object */
  168. switch (dev->chipset & 0xf0) {
  169. case 0x40:
  170. if (NV4X_GRCLASS4097_CHIPSETS & (1 << (dev->chipset & 0x0f)))
  171. curie_class = NV40TCL;
  172. else
  173. if (NV4X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
  174. curie_class = NV44TCL;
  175. break;
  176. case 0x60:
  177. if (NV6X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
  178. curie_class = NV44TCL;
  179. break;
  180. }
  181. if (!curie_class) {
  182. NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", dev->chipset);
  183. return NULL;
  184. }
  185. ret = nouveau_grobj_alloc(chan, 0xbeef3097, curie_class, &screen->curie);
  186. if (ret) {
  187. NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
  188. return FALSE;
  189. }
  190. BIND_RING(chan, screen->curie, 7);
  191. /* 2D engine setup */
  192. screen->eng2d = nv04_surface_2d_init(&screen->base);
  193. screen->eng2d->buf = nv40_surface_buffer;
  194. /* Notifier for sync purposes */
  195. ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
  196. if (ret) {
  197. NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
  198. nv40_screen_destroy(pscreen);
  199. return NULL;
  200. }
  201. /* Query objects */
  202. ret = nouveau_notifier_alloc(chan, 0xbeef0302, 32, &screen->query);
  203. if (ret) {
  204. NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
  205. nv40_screen_destroy(pscreen);
  206. return NULL;
  207. }
  208. nouveau_resource_init(&screen->query_heap, 0, 32);
  209. if (ret) {
  210. NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
  211. nv40_screen_destroy(pscreen);
  212. return NULL;
  213. }
  214. /* Vtxprog resources */
  215. if (nouveau_resource_init(&screen->vp_exec_heap, 0, 512) ||
  216. nouveau_resource_init(&screen->vp_data_heap, 0, 256)) {
  217. nv40_screen_destroy(pscreen);
  218. return NULL;
  219. }
  220. /* Static curie initialisation */
  221. so = so_new(128, 0);
  222. so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1);
  223. so_data (so, screen->sync->handle);
  224. so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2);
  225. so_data (so, chan->vram->handle);
  226. so_data (so, chan->gart->handle);
  227. so_method(so, screen->curie, NV40TCL_DMA_COLOR1, 1);
  228. so_data (so, chan->vram->handle);
  229. so_method(so, screen->curie, NV40TCL_DMA_COLOR0, 2);
  230. so_data (so, chan->vram->handle);
  231. so_data (so, chan->vram->handle);
  232. so_method(so, screen->curie, NV40TCL_DMA_VTXBUF0, 2);
  233. so_data (so, chan->vram->handle);
  234. so_data (so, chan->gart->handle);
  235. so_method(so, screen->curie, NV40TCL_DMA_FENCE, 2);
  236. so_data (so, 0);
  237. so_data (so, screen->query->handle);
  238. so_method(so, screen->curie, NV40TCL_DMA_UNK01AC, 2);
  239. so_data (so, chan->vram->handle);
  240. so_data (so, chan->vram->handle);
  241. so_method(so, screen->curie, NV40TCL_DMA_COLOR2, 2);
  242. so_data (so, chan->vram->handle);
  243. so_data (so, chan->vram->handle);
  244. so_method(so, screen->curie, 0x1ea4, 3);
  245. so_data (so, 0x00000010);
  246. so_data (so, 0x01000100);
  247. so_data (so, 0xff800006);
  248. /* vtxprog output routing */
  249. so_method(so, screen->curie, 0x1fc4, 1);
  250. so_data (so, 0x06144321);
  251. so_method(so, screen->curie, 0x1fc8, 2);
  252. so_data (so, 0xedcba987);
  253. so_data (so, 0x00000021);
  254. so_method(so, screen->curie, 0x1fd0, 1);
  255. so_data (so, 0x00171615);
  256. so_method(so, screen->curie, 0x1fd4, 1);
  257. so_data (so, 0x001b1a19);
  258. so_method(so, screen->curie, 0x1ef8, 1);
  259. so_data (so, 0x0020ffff);
  260. so_method(so, screen->curie, 0x1d64, 1);
  261. so_data (so, 0x00d30000);
  262. so_method(so, screen->curie, 0x1e94, 1);
  263. so_data (so, 0x00000001);
  264. so_emit(chan, so);
  265. so_ref(NULL, &so);
  266. nouveau_pushbuf_flush(chan, 0);
  267. return pscreen;
  268. }