PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/limare/lib/gp.c

https://gitlab.com/lima-ncc1988/lima-ncc1988
C | 859 lines | 645 code | 167 blank | 47 comment | 101 complexity | f0c7db34defb9a8c421d3cb362b74218 MD5 | raw file
  1. /*
  2. * Copyright (c) 2011-2013 Luc Verhaegen <libv@skynet.be>
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sub license,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the
  12. * next paragraph) shall be included in all copies or substantial portions
  13. * of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21. * DEALINGS IN THE SOFTWARE.
  22. */
  23. /*
  24. *
  25. * Code to help deal with setting up command streams for GP vs/plbu.
  26. *
  27. */
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <errno.h>
  32. #include <sys/ioctl.h>
  33. #include <GLES2/gl2.h>
  34. #include "ioctl_registers.h"
  35. #include "limare.h"
  36. #include "compiler.h"
  37. #include "plb.h"
  38. #include "symbols.h"
  39. #include "gp.h"
  40. #include "jobs.h"
  41. #include "vs.h"
  42. #include "plbu.h"
  43. #include "render_state.h"
  44. #include "hfloat.h"
  45. #include "from_float.h"
  46. #include "texture.h"
  47. #include "program.h"
  48. int
  49. vs_command_queue_create(struct limare_frame *frame, int size)
  50. {
  51. size = ALIGN(size, 0x40);
  52. if ((frame->mem_size - frame->mem_used) < size) {
  53. printf("%s: no space for vs queue\n", __func__);
  54. return -1;
  55. }
  56. frame->vs_commands = frame->mem_address + frame->mem_used;
  57. frame->vs_commands_physical = frame->mem_physical + frame->mem_used;
  58. frame->vs_commands_count = 0;
  59. frame->vs_commands_size = size / 8;
  60. frame->mem_used += size;
  61. return 0;
  62. }
  63. void
  64. plbu_viewport_set(struct limare_frame *frame,
  65. float x, float y, float w, float h)
  66. {
  67. struct lima_cmd *cmds = frame->plbu_commands;
  68. int i = frame->plbu_commands_count;
  69. cmds[i].val = from_float(x);
  70. cmds[i].cmd = LIMA_PLBU_CMD_VIEWPORT_X;
  71. i++;
  72. cmds[i].val = from_float(x + w);
  73. cmds[i].cmd = LIMA_PLBU_CMD_VIEWPORT_W;
  74. i++;
  75. cmds[i].val = from_float(y);
  76. cmds[i].cmd = LIMA_PLBU_CMD_VIEWPORT_Y;
  77. i++;
  78. cmds[i].val = from_float(y + h);
  79. cmds[i].cmd = LIMA_PLBU_CMD_VIEWPORT_H;
  80. i++;
  81. frame->plbu_commands_count = i;
  82. }
  83. void
  84. plbu_scissor(struct limare_state *state, struct limare_frame *frame)
  85. {
  86. struct lima_cmd *cmds = frame->plbu_commands;
  87. int i = frame->plbu_commands_count;
  88. int x, y, w, h;
  89. if (state->scissor) {
  90. x = state->scissor_x;
  91. y = state->scissor_y;
  92. w = state->scissor_w;
  93. h = state->scissor_h;
  94. } else {
  95. x = state->viewport_x;
  96. y = state->viewport_y;
  97. w = state->viewport_w;
  98. h = state->viewport_h;
  99. }
  100. cmds[i].val = (x << 30) | (y + h - 1) << 15 | y;
  101. cmds[i].cmd = LIMA_PLBU_CMD_SCISSORS |
  102. (x + w -1) << 13 | (x >> 2);
  103. frame->plbu_commands_count++;
  104. }
  105. int
  106. plbu_command_queue_create(struct limare_state *state,
  107. struct limare_frame *frame, int size, int heap_size)
  108. {
  109. struct plb_info *plb = state->plb;
  110. struct lima_cmd *cmds;
  111. int i = 0;
  112. size = ALIGN(size, 0x40);
  113. heap_size = ALIGN(heap_size, 0x40);
  114. if ((frame->mem_size - frame->mem_used) < (size + heap_size)) {
  115. printf("%s: no space for plbu queue and tile heap\n", __func__);
  116. return -1;
  117. }
  118. frame->tile_heap_offset = frame->mem_used;
  119. frame->tile_heap_size = heap_size;
  120. frame->mem_used += heap_size;
  121. frame->plbu_commands = frame->mem_address + frame->mem_used;
  122. frame->plbu_commands_physical = frame->mem_physical + frame->mem_used;
  123. frame->plbu_commands_count = 0;
  124. frame->plbu_commands_size = size / 8;
  125. frame->mem_used += size;
  126. cmds = frame->plbu_commands;
  127. cmds[i].val = 0x0000200;
  128. cmds[i].cmd = LIMA_PLBU_CMD_PRIMITIVE_SETUP;
  129. i++;
  130. cmds[i].val = plb->shift_w | (plb->shift_h << 16);
  131. if (state->type == LIMARE_TYPE_M400)
  132. cmds[i].val |= plb->shift_max << 28;
  133. cmds[i].cmd = LIMA_PLBU_CMD_BLOCK_STEP;
  134. i++;
  135. cmds[i].val = ((plb->tiled_w - 1) << 24) | ((plb->tiled_h - 1) << 8);
  136. cmds[i].cmd = LIMA_PLBU_CMD_TILED_DIMENSIONS;
  137. i++;
  138. cmds[i].val = plb->block_w;
  139. cmds[i].cmd = LIMA_PLBU_CMD_PLBU_BLOCK_STRIDE;
  140. i++;
  141. cmds[i].val = frame->mem_physical + frame->plb_plbu_offset;
  142. if (state->type == LIMARE_TYPE_M200)
  143. cmds[i].cmd = LIMA_M200_PLBU_CMD_PLBU_ARRAY_ADDRESS;
  144. else if (state->type == LIMARE_TYPE_M400) {
  145. cmds[i].cmd = LIMA_M400_PLBU_CMD_PLBU_ARRAY_ADDRESS;
  146. cmds[i].cmd |= plb->block_w * plb->block_h - 1;
  147. }
  148. i++;
  149. frame->plbu_commands_count = i;
  150. plbu_viewport_set(frame, 0.0, 0.0, state->width, state->height);
  151. i = frame->plbu_commands_count;
  152. cmds[i].val = frame->mem_physical + frame->tile_heap_offset;
  153. cmds[i].cmd = LIMA_PLBU_CMD_TILE_HEAP_START;
  154. i++;
  155. cmds[i].val = frame->mem_physical + frame->tile_heap_offset +
  156. frame->tile_heap_size;
  157. cmds[i].cmd = LIMA_PLBU_CMD_TILE_HEAP_END;
  158. i++;
  159. frame->plbu_commands_count = i;
  160. return 0;
  161. }
  162. int
  163. vs_info_setup(struct limare_state *state, struct limare_frame *frame,
  164. struct draw_info *draw)
  165. {
  166. struct vs_info *info = draw->vs;
  167. int i;
  168. if (state->type == LIMARE_TYPE_M200) {
  169. if ((frame->mem_size - frame->mem_used) <
  170. sizeof(struct gp_common)) {
  171. printf("%s: no space for vs common\n", __func__);
  172. return -1;
  173. }
  174. /* lima200 has a common area for attributes and varyings. */
  175. info->common = frame->mem_address + frame->mem_used;
  176. info->common_offset = frame->mem_used;
  177. info->common_size = sizeof(struct gp_common);
  178. frame->mem_used += ALIGN(info->common_size, 0x40);
  179. /* initialize common */
  180. for (i = 0; i < 0x10; i++) {
  181. info->common->attributes[i].physical = 0;
  182. info->common->attributes[i].size = 0x3F;
  183. }
  184. for (i = 0; i < 0x10; i++) {
  185. info->common->varyings[i].physical = 0;
  186. info->common->varyings[i].size = 0x3F;
  187. }
  188. } else if (state->type == LIMARE_TYPE_M400) {
  189. if ((frame->mem_size - frame->mem_used) <
  190. (0x20 * sizeof(struct gp_common_entry))) {
  191. printf("%s: no space for vs attribute/varying area\n",
  192. __func__);
  193. return -1;
  194. }
  195. info->attribute_area = frame->mem_address + frame->mem_used;
  196. info->attribute_area_size = 0x10 * sizeof(struct gp_common_entry);
  197. info->attribute_area_offset = frame->mem_used;
  198. frame->mem_used += ALIGN(info->attribute_area_size, 0x40);
  199. info->varying_area = frame->mem_address + frame->mem_used;
  200. info->varying_area_size = 0x10 * sizeof(struct gp_common_entry);
  201. info->varying_area_offset = frame->mem_used;
  202. frame->mem_used += ALIGN(info->varying_area_size, 0x40);
  203. }
  204. return 0;
  205. }
  206. int
  207. vs_info_attach_uniforms(struct limare_frame *frame, struct draw_info *draw,
  208. struct symbol **uniforms, int count, int size)
  209. {
  210. struct vs_info *info = draw->vs;
  211. void *address;
  212. int i;
  213. if ((frame->mem_size - frame->mem_used) <
  214. ALIGN(4 * size, 0x40)) {
  215. printf("%s: no space for uniforms\n", __func__);
  216. return -1;
  217. }
  218. info->uniform_offset = frame->mem_used;
  219. info->uniform_size = size;
  220. frame->mem_used += ALIGN(4 * size, 0x40);
  221. address = frame->mem_address + info->uniform_offset;
  222. for (i = 0; i < count; i++) {
  223. struct symbol *symbol = uniforms[i];
  224. if (symbol->src_stride == symbol->dst_stride)
  225. memcpy(address + symbol->component_size * symbol->offset,
  226. symbol->data, symbol->size);
  227. else {
  228. void *symbol_address = address +
  229. symbol->component_size * symbol->offset;
  230. int j;
  231. for (j = 0; (j * symbol->src_stride) < symbol->size; j++)
  232. memcpy(symbol_address + (j * symbol->dst_stride),
  233. symbol->data + (j * symbol->src_stride),
  234. symbol->src_stride);
  235. }
  236. }
  237. return 0;
  238. }
  239. int
  240. vs_info_attach_attribute(struct limare_frame *frame, struct draw_info *draw,
  241. struct symbol *attribute)
  242. {
  243. struct vs_info *info = draw->vs;
  244. if (info->attribute_count == 0x10) {
  245. printf("%s: No more attributes\n", __func__);
  246. return -1;
  247. }
  248. info->attributes[attribute->offset / 4] = attribute;
  249. info->attribute_count++;
  250. return 0;
  251. }
  252. int
  253. vs_info_attach_varyings(struct limare_program *program,
  254. struct limare_frame *frame, struct draw_info *draw)
  255. {
  256. struct vs_info *info = draw->vs;
  257. info->varying_size = ALIGN(program->varying_map_size *
  258. draw->attributes_vertex_count, 0x40);
  259. if (info->varying_size > (frame->mem_size - frame->mem_used)) {
  260. printf("%s: No more space\n", __func__);
  261. return -2;
  262. }
  263. info->varying_offset = frame->mem_used;
  264. frame->mem_used += info->varying_size;
  265. info->gl_Position_size =
  266. ALIGN(16 * draw->attributes_vertex_count, 0x40);
  267. if (info->gl_Position_size > (frame->mem_size - frame->mem_used)) {
  268. printf("%s: No more space\n", __func__);
  269. return -2;
  270. }
  271. info->gl_Position_offset = frame->mem_used;
  272. frame->mem_used += info->gl_Position_size;
  273. return 0;
  274. }
  275. void
  276. vs_commands_draw_add(struct limare_state *state, struct limare_frame *frame,
  277. struct limare_program *program, struct draw_info *draw)
  278. {
  279. struct vs_info *vs = draw->vs;
  280. struct plbu_info *plbu = draw->plbu;
  281. struct lima_cmd *cmds = frame->vs_commands;
  282. int i = frame->vs_commands_count;
  283. if (!plbu->indices_mem_physical) {
  284. cmds[i].val = LIMA_VS_CMD_ARRAYS_SEMAPHORE_BEGIN_1;
  285. cmds[i].cmd = LIMA_VS_CMD_ARRAYS_SEMAPHORE;
  286. i++;
  287. cmds[i].val = LIMA_VS_CMD_ARRAYS_SEMAPHORE_BEGIN_2;
  288. cmds[i].cmd = LIMA_VS_CMD_ARRAYS_SEMAPHORE;
  289. i++;
  290. }
  291. cmds[i].val = program->mem_physical + program->vertex_mem_offset;
  292. cmds[i].cmd = LIMA_VS_CMD_SHADER_ADDRESS |
  293. ((program->vertex_shader_size / 16) << 16);
  294. i++;
  295. cmds[i].val = (program->vertex_attribute_prefetch - 1) << 20;
  296. cmds[i].val |= ((ALIGN(program->vertex_shader_size, 16) / 16) - 1)
  297. << 10;
  298. cmds[i].cmd = LIMA_VS_CMD_SHADER_INFO;
  299. i++;
  300. cmds[i].val = (program->varying_map_count << 8) |
  301. ((vs->attribute_count - 1) << 24);
  302. cmds[i].cmd = LIMA_VS_CMD_VARYING_ATTRIBUTE_COUNT;
  303. i++;
  304. cmds[i].val = frame->mem_physical + vs->uniform_offset;
  305. cmds[i].cmd = LIMA_VS_CMD_UNIFORMS_ADDRESS |
  306. (ALIGN(vs->uniform_size, 4) << 14);
  307. i++;
  308. if (state->type == LIMARE_TYPE_M200) {
  309. cmds[i].val = frame->mem_physical + vs->common_offset;
  310. cmds[i].cmd = LIMA_VS_CMD_COMMON_ADDRESS |
  311. (vs->common_size << 14);
  312. i++;
  313. } else if (state->type == LIMARE_TYPE_M400) {
  314. cmds[i].val = frame->mem_physical + vs->attribute_area_offset;
  315. cmds[i].cmd = LIMA_VS_CMD_ATTRIBUTES_ADDRESS |
  316. (vs->attribute_count << 17);
  317. i++;
  318. cmds[i].val = frame->mem_physical + vs->varying_area_offset;
  319. cmds[i].cmd = LIMA_VS_CMD_VARYINGS_ADDRESS |
  320. ((program->varying_map_count + 1) << 17);
  321. i++;
  322. }
  323. cmds[i].val = 0x00000003; /* always 3 */
  324. cmds[i].cmd = 0x10000041;
  325. i++;
  326. cmds[i].val = draw->attributes_vertex_count << 24;
  327. if (plbu->indices_mem_physical)
  328. cmds[i].val |= 0x01;
  329. cmds[i].cmd = LIMA_VS_CMD_DRAW | draw->attributes_vertex_count >> 8;
  330. i++;
  331. cmds[i].val = 0x00000000;
  332. cmds[i].cmd = 0x60000000;
  333. i++;
  334. if (plbu->indices_mem_physical)
  335. cmds[i].val = LIMA_VS_CMD_ARRAYS_SEMAPHORE_NEXT;
  336. else
  337. cmds[i].val = LIMA_VS_CMD_ARRAYS_SEMAPHORE_END;
  338. cmds[i].cmd = LIMA_VS_CMD_ARRAYS_SEMAPHORE;
  339. i++;
  340. /* update our size so we can set the gp job properly */
  341. frame->vs_commands_count = i;
  342. }
  343. void
  344. vs_info_finalize(struct limare_state *state, struct limare_frame *frame,
  345. struct limare_program *program,
  346. struct draw_info *draw, struct vs_info *info)
  347. {
  348. int i;
  349. if (state->type == LIMARE_TYPE_M200) {
  350. for (i = 0; i < info->attribute_count; i++) {
  351. struct symbol *symbol = info->attributes[i];
  352. info->common->attributes[i].physical =
  353. symbol->mem_physical;
  354. info->common->attributes[i].size =
  355. (symbol->entry_stride << 11) |
  356. (symbol->component_type << 2) |
  357. (symbol->component_count - 1);
  358. }
  359. for (i = 0; i < program->varying_map_count; i++) {
  360. info->common->varyings[i].physical =
  361. frame->mem_physical +
  362. info->varying_offset +
  363. program->varying_map[i].offset;
  364. info->common->varyings[i].size =
  365. (program->varying_map_size << 11) |
  366. (program->varying_map[i].entries - 1);
  367. if (program->varying_map[i].entry_size == 2)
  368. info->common->varyings[i].size |= 0x0C;
  369. }
  370. if (program->gl_Position) {
  371. info->common->varyings[i].physical =
  372. frame->mem_physical + info->gl_Position_offset;
  373. info->common->varyings[i].size = 0x8020;
  374. }
  375. } else if (state->type == LIMARE_TYPE_M400) {
  376. for (i = 0; i < info->attribute_count; i++) {
  377. struct symbol *symbol = info->attributes[i];
  378. info->attribute_area[i].physical =
  379. symbol->mem_physical +
  380. (symbol->entry_stride * draw->vertex_start);
  381. info->attribute_area[i].size =
  382. (symbol->entry_stride << 11) |
  383. (symbol->component_type << 2) |
  384. (symbol->component_count - 1);
  385. }
  386. for (i = 0; i < program->varying_map_count; i++) {
  387. info->varying_area[i].physical =
  388. frame->mem_physical +
  389. info->varying_offset +
  390. program->varying_map[i].offset;
  391. info->varying_area[i].size =
  392. (program->varying_map_size << 11) |
  393. (program->varying_map[i].entries - 1);
  394. if (program->varying_map[i].entry_size == 2)
  395. info->varying_area[i].size |= 0x0C;
  396. }
  397. if (program->gl_Position) {
  398. info->varying_area[i].physical =
  399. frame->mem_physical + info->gl_Position_offset;
  400. info->varying_area[i].size = 0x8020;
  401. }
  402. }
  403. }
  404. void
  405. plbu_commands_draw_add(struct limare_state *state, struct limare_frame *frame,
  406. struct draw_info *draw)
  407. {
  408. struct plbu_info *plbu = draw->plbu;
  409. struct vs_info *vs = draw->vs;
  410. struct lima_cmd *cmds = frame->plbu_commands;
  411. int i = frame->plbu_commands_count;
  412. /*
  413. *
  414. */
  415. if (!plbu->indices_mem_physical) {
  416. cmds[i].val = LIMA_PLBU_CMD_ARRAYS_SEMAPHORE_BEGIN;
  417. cmds[i].cmd = LIMA_PLBU_CMD_ARRAYS_SEMAPHORE;
  418. i++;
  419. }
  420. cmds[i].val = LIMA_PLBU_CMD_PRIMITIVE_GLES2 | 0x0000200;
  421. if (plbu->indices_mem_physical) {
  422. if (plbu->indices_type == GL_UNSIGNED_SHORT)
  423. cmds[i].val |= LIMA_PLBU_CMD_PRIMITIVE_INDEX_SHORT;
  424. else
  425. cmds[i].val |= LIMA_PLBU_CMD_PRIMITIVE_INDEX_BYTE;
  426. }
  427. if (state->culling) {
  428. if (state->cull_front_cw) {
  429. if (state->cull_front)
  430. cmds[i].val |= LIMA_PLBU_CMD_PRIMITIVE_CULL_CW;
  431. if (state->cull_back)
  432. cmds[i].val |= LIMA_PLBU_CMD_PRIMITIVE_CULL_CCW;
  433. } else {
  434. if (state->cull_front)
  435. cmds[i].val |= LIMA_PLBU_CMD_PRIMITIVE_CULL_CCW;
  436. if (state->cull_back)
  437. cmds[i].val |= LIMA_PLBU_CMD_PRIMITIVE_CULL_CW;
  438. }
  439. }
  440. cmds[i].cmd = LIMA_PLBU_CMD_PRIMITIVE_SETUP;
  441. i++;
  442. cmds[i].val = frame->mem_physical + plbu->render_state_offset;
  443. cmds[i].cmd = LIMA_PLBU_CMD_RSW_VERTEX_ARRAY;
  444. cmds[i].cmd |= (frame->mem_physical + vs->gl_Position_offset) >> 4;
  445. i++;
  446. frame->plbu_commands_count = i;
  447. /* original mali driver also flushes depth in this case. */
  448. if (state->viewport_dirty && state->scissor_dirty)
  449. state->depth_dirty = 1;
  450. if (state->viewport_dirty) {
  451. plbu_viewport_set(frame, state->viewport_x, state->viewport_y,
  452. state->viewport_w, state->viewport_h);
  453. state->viewport_dirty = 0;
  454. }
  455. if (state->scissor_dirty) {
  456. plbu_scissor(state, frame);
  457. state->scissor_dirty = 0;
  458. }
  459. i = frame->plbu_commands_count;
  460. if (state->depth_dirty) {
  461. cmds[i].val = 0x00000000;
  462. cmds[i].cmd = 0x1000010a;
  463. i++;
  464. cmds[i].val = from_float(state->depth_near);
  465. cmds[i].cmd = LIMA_PLBU_CMD_DEPTH_RANGE_NEAR;
  466. i++;
  467. cmds[i].val = from_float(state->depth_far);
  468. cmds[i].cmd = LIMA_PLBU_CMD_DEPTH_RANGE_FAR;
  469. i++;
  470. state->depth_dirty = 0;
  471. }
  472. if (plbu->indices_mem_physical) {
  473. cmds[i].val = frame->mem_physical + vs->gl_Position_offset;
  474. cmds[i].cmd = LIMA_PLBU_CMD_INDEXED_DEST;
  475. i++;
  476. cmds[i].val = plbu->indices_mem_physical;
  477. cmds[i].cmd = LIMA_PLBU_CMD_INDICES;
  478. i++;
  479. } else {
  480. cmds[i].val = (draw->vertex_count << 24) | draw->vertex_start;
  481. cmds[i].cmd = LIMA_PLBU_CMD_DRAW | LIMA_PLBU_CMD_DRAW_ARRAYS |
  482. ((draw->draw_mode & 0x1F) << 16) |
  483. (draw->vertex_count >> 8);
  484. i++;
  485. }
  486. cmds[i].val = LIMA_PLBU_CMD_ARRAYS_SEMAPHORE_END;
  487. cmds[i].cmd = LIMA_PLBU_CMD_ARRAYS_SEMAPHORE;
  488. i++;
  489. if (plbu->indices_mem_physical) {
  490. cmds[i].val = (draw->vertex_count << 24) | draw->vertex_start;
  491. cmds[i].cmd = LIMA_PLBU_CMD_DRAW | LIMA_PLBU_CMD_DRAW_ELEMENTS |
  492. ((draw->draw_mode & 0x1F) << 16) | (draw->vertex_count >> 8);
  493. i++;
  494. }
  495. /* update our size so we can set the gp job properly */
  496. frame->plbu_commands_count = i;
  497. }
  498. void
  499. plbu_commands_depth_buffer_clear_draw_add(struct limare_state *state,
  500. struct limare_frame *frame,
  501. struct draw_info *draw, unsigned int
  502. varying_vertices_physical)
  503. {
  504. struct plbu_info *plbu = draw->plbu;
  505. struct lima_cmd *cmds = frame->plbu_commands;
  506. int i;
  507. plbu_viewport_set(frame, 0.0, 0.0, 4096.0, 4096.0);
  508. state->viewport_dirty = 1;
  509. if (state->scissor_dirty) {
  510. plbu_scissor(state, frame);
  511. state->scissor_dirty = 0;
  512. }
  513. i = frame->plbu_commands_count;
  514. cmds[i].val = frame->mem_physical + plbu->render_state_offset;
  515. cmds[i].cmd = LIMA_PLBU_CMD_RSW_VERTEX_ARRAY;
  516. cmds[i].cmd |= varying_vertices_physical >> 4;
  517. i++;
  518. cmds[i].val = 0x00000200;
  519. cmds[i].cmd = LIMA_PLBU_CMD_PRIMITIVE_SETUP;
  520. i++;
  521. cmds[i].val = from_float(state->depth_near);
  522. cmds[i].cmd = LIMA_PLBU_CMD_DEPTH_RANGE_NEAR;
  523. i++;
  524. cmds[i].val = from_float(state->depth_far);
  525. cmds[i].cmd = LIMA_PLBU_CMD_DEPTH_RANGE_FAR;
  526. i++;
  527. cmds[i].val = 0x00000000;
  528. cmds[i].cmd = 0x1000010a;
  529. i++;
  530. state->depth_dirty = 1;
  531. cmds[i].val = plbu->indices_mem_physical;
  532. cmds[i].cmd = LIMA_PLBU_CMD_INDICES;
  533. i++;
  534. cmds[i].val = varying_vertices_physical;
  535. cmds[i].cmd = LIMA_PLBU_CMD_INDEXED_DEST;
  536. i++;
  537. cmds[i].val = (draw->vertex_count << 24) | draw->vertex_start;
  538. cmds[i].cmd = LIMA_PLBU_CMD_DRAW | LIMA_PLBU_CMD_DRAW_ELEMENTS |
  539. ((draw->draw_mode & 0x1F) << 16) | (draw->vertex_count >> 8);
  540. i++;
  541. /* update our size so we can set the gp job properly */
  542. frame->plbu_commands_count = i;
  543. }
  544. void
  545. plbu_commands_finish(struct limare_frame *frame)
  546. {
  547. struct lima_cmd *cmds = frame->plbu_commands;
  548. int i = frame->plbu_commands_count;
  549. #if 0
  550. cmds[i].val = 0x00000000;
  551. cmds[i].cmd = 0xd0000000;
  552. i++;
  553. cmds[i].val = 0x00000000;
  554. cmds[i].cmd = 0xd0000000;
  555. i++;
  556. #endif
  557. cmds[i].val = 0;
  558. cmds[i].cmd = LIMA_PLBU_CMD_END;
  559. i++;
  560. /* update our size so we can set the gp job properly */
  561. frame->plbu_commands_count = i;
  562. }
  563. int
  564. plbu_info_attach_uniforms(struct limare_frame *frame, struct draw_info *draw,
  565. struct symbol **uniforms, int count, int size)
  566. {
  567. struct plbu_info *info = draw->plbu;
  568. void *address;
  569. unsigned int *array;
  570. int i;
  571. if (!count)
  572. return 0;
  573. /* if we have only samplers, we can shortcut this. */
  574. for (i = 0; i < count; i++) {
  575. struct symbol *symbol = uniforms[i];
  576. if (symbol->value_type != SYMBOL_SAMPLER)
  577. break;
  578. }
  579. if (i == count)
  580. return 0;
  581. if ((frame->mem_size - frame->mem_used) < (0x40 + ALIGN(size, 0x40))) {
  582. printf("%s: no space for plbu uniforms\n", __func__);
  583. return -1;
  584. }
  585. info->uniform_array_offset = frame->mem_used;
  586. info->uniform_array_size = 4;
  587. frame->mem_used += 0x40;
  588. array = frame->mem_address + info->uniform_array_offset;
  589. info->uniform_offset = frame->mem_used;
  590. info->uniform_size = size;
  591. frame->mem_used += ALIGN(4 * size, 0x40);
  592. address = frame->mem_address + info->uniform_offset;
  593. array[0] = frame->mem_physical + info->uniform_offset;
  594. for (i = 0; i < count; i++) {
  595. struct symbol *symbol = uniforms[i];
  596. /*
  597. * For samplers, there is place reserved, but the actual
  598. * uniform never is written, and the value is actually plainly
  599. * ignored.
  600. */
  601. if (symbol->value_type == SYMBOL_SAMPLER)
  602. continue;
  603. memcpy(address +
  604. symbol->component_size * symbol->offset,
  605. symbol->data, symbol->size);
  606. }
  607. return 0;
  608. }
  609. void
  610. plbu_info_attach_indices(struct draw_info *draw, int indices_type,
  611. unsigned int mem_physical)
  612. {
  613. struct plbu_info *plbu = draw->plbu;
  614. plbu->indices_type = indices_type;
  615. plbu->indices_mem_physical = mem_physical;
  616. }
  617. int
  618. plbu_info_attach_textures(struct limare_state *state,
  619. struct limare_frame *frame,
  620. struct draw_info *draw)
  621. {
  622. struct limare_program *program = state->program_current;
  623. unsigned int *list;
  624. int i;
  625. /* first a quick pass to see whether we need any textures */
  626. for (i = 0; i < program->fragment_uniform_count; i++) {
  627. struct symbol *symbol = program->fragment_uniforms[i];
  628. if (symbol->value_type == SYMBOL_SAMPLER)
  629. break;
  630. }
  631. if (i == program->fragment_uniform_count)
  632. return 0;
  633. /* create descriptor list */
  634. draw->texture_descriptor_list_offset = frame->mem_used;
  635. list = frame->mem_address + frame->mem_used;
  636. frame->mem_used += 0x40;
  637. for (i = 0; i < program->fragment_uniform_count; i++) {
  638. struct symbol *symbol = program->fragment_uniforms[i];
  639. struct limare_texture *texture;
  640. int handle, j;
  641. if (symbol->value_type != SYMBOL_SAMPLER)
  642. continue;
  643. handle = symbol->data_handle;
  644. /* first, check sanity of the offset */
  645. if (symbol->offset >= LIMARE_DRAW_TEXTURE_COUNT) {
  646. printf("%s: Error: sampler %s has wrong offset %d.\n",
  647. __func__, symbol->name, symbol->offset);
  648. return -1;
  649. }
  650. /* find the matching texture */
  651. for (j = 0; j < LIMARE_TEXTURE_COUNT; j++) {
  652. if (!state->textures[j])
  653. continue;
  654. texture = state->textures[j];
  655. if (handle == texture->handle)
  656. break;
  657. }
  658. if (j == LIMARE_TEXTURE_COUNT) {
  659. printf("%s: Error: symbol %s texture handle not "
  660. "found\n", __func__, symbol->name);
  661. return -1;
  662. }
  663. draw->texture_handles[symbol->offset] = handle;
  664. list[symbol->offset] = texture->descriptor_physical;
  665. if ((symbol->offset + 1) > draw->texture_descriptor_count)
  666. draw->texture_descriptor_count = symbol->offset + 1;
  667. }
  668. return 0;
  669. }
  670. struct draw_info *
  671. draw_create_new(struct limare_state *state, struct limare_frame *frame,
  672. int draw_mode, int attributes_vertex_count, int vertex_start,
  673. int vertex_count)
  674. {
  675. struct draw_info *draw = calloc(1, sizeof(struct draw_info));
  676. if (!draw)
  677. return NULL;
  678. draw->draw_mode = draw_mode;
  679. draw->attributes_vertex_count = attributes_vertex_count;
  680. draw->vertex_start = vertex_start;
  681. draw->vertex_count = vertex_count;
  682. if (vs_info_setup(state, frame, draw)) {
  683. free(draw);
  684. return NULL;
  685. }
  686. return draw;
  687. }
  688. void
  689. draw_info_destroy(struct draw_info *draw)
  690. {
  691. free(draw);
  692. }