Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
  2.  
  3. /*
  4.  * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23.  * SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Rob Clark <robclark@freedesktop.org>
  27.  */
  28.  
  29. #include "pipe/p_state.h"
  30. #include "util/u_string.h"
  31. #include "util/u_memory.h"
  32. #include "util/u_inlines.h"
  33. #include "util/u_format.h"
  34. #include "tgsi/tgsi_dump.h"
  35. #include "tgsi/tgsi_parse.h"
  36.  
  37. #include "freedreno_program.h"
  38.  
  39. #include "fd2_program.h"
  40. #include "fd2_compiler.h"
  41. #include "fd2_texture.h"
  42. #include "fd2_util.h"
  43.  
  44. static struct fd2_shader_stateobj *
  45. create_shader(enum shader_t type)
  46. {
  47.         struct fd2_shader_stateobj *so = CALLOC_STRUCT(fd2_shader_stateobj);
  48.         if (!so)
  49.                 return NULL;
  50.         so->type = type;
  51.         return so;
  52. }
  53.  
  54. static void
  55. delete_shader(struct fd2_shader_stateobj *so)
  56. {
  57.         ir2_shader_destroy(so->ir);
  58.         free(so->tokens);
  59.         free(so->bin);
  60.         free(so);
  61. }
  62.  
  63. static struct fd2_shader_stateobj *
  64. assemble(struct fd2_shader_stateobj *so)
  65. {
  66.         free(so->bin);
  67.         so->bin = ir2_shader_assemble(so->ir, &so->info);
  68.         if (!so->bin)
  69.                 goto fail;
  70.  
  71.         if (fd_mesa_debug & FD_DBG_DISASM) {
  72.                 DBG("disassemble: type=%d", so->type);
  73.                 disasm_a2xx(so->bin, so->info.sizedwords, 0, so->type);
  74.         }
  75.  
  76.         return so;
  77.  
  78. fail:
  79.         debug_error("assemble failed!");
  80.         delete_shader(so);
  81.         return NULL;
  82. }
  83.  
  84. static struct fd2_shader_stateobj *
  85. compile(struct fd_program_stateobj *prog, struct fd2_shader_stateobj *so)
  86. {
  87.         int ret;
  88.  
  89.         if (fd_mesa_debug & FD_DBG_DISASM) {
  90.                 DBG("dump tgsi: type=%d", so->type);
  91.                 tgsi_dump(so->tokens, 0);
  92.         }
  93.  
  94.         ret = fd2_compile_shader(prog, so);
  95.         if (ret)
  96.                 goto fail;
  97.  
  98.         /* NOTE: we don't assemble yet because for VS we don't know the
  99.          * type information for vertex fetch yet.. so those need to be
  100.          * patched up later before assembling.
  101.          */
  102.  
  103.         so->info.sizedwords = 0;
  104.  
  105.         return so;
  106.  
  107. fail:
  108.         debug_error("compile failed!");
  109.         delete_shader(so);
  110.         return NULL;
  111. }
  112.  
  113. static void
  114. emit(struct fd_ringbuffer *ring, struct fd2_shader_stateobj *so)
  115. {
  116.         unsigned i;
  117.  
  118.         if (so->info.sizedwords == 0)
  119.                 assemble(so);
  120.  
  121.         OUT_PKT3(ring, CP_IM_LOAD_IMMEDIATE, 2 + so->info.sizedwords);
  122.         OUT_RING(ring, (so->type == SHADER_VERTEX) ? 0 : 1);
  123.         OUT_RING(ring, so->info.sizedwords);
  124.         for (i = 0; i < so->info.sizedwords; i++)
  125.                 OUT_RING(ring, so->bin[i]);
  126. }
  127.  
  128. static void *
  129. fd2_fp_state_create(struct pipe_context *pctx,
  130.                 const struct pipe_shader_state *cso)
  131. {
  132.         struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
  133.         if (!so)
  134.                 return NULL;
  135.         so->tokens = tgsi_dup_tokens(cso->tokens);
  136.         return so;
  137. }
  138.  
  139. static void
  140. fd2_fp_state_delete(struct pipe_context *pctx, void *hwcso)
  141. {
  142.         struct fd2_shader_stateobj *so = hwcso;
  143.         delete_shader(so);
  144. }
  145.  
  146. static void *
  147. fd2_vp_state_create(struct pipe_context *pctx,
  148.                 const struct pipe_shader_state *cso)
  149. {
  150.         struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
  151.         if (!so)
  152.                 return NULL;
  153.         so->tokens = tgsi_dup_tokens(cso->tokens);
  154.         return so;
  155. }
  156.  
  157. static void
  158. fd2_vp_state_delete(struct pipe_context *pctx, void *hwcso)
  159. {
  160.         struct fd2_shader_stateobj *so = hwcso;
  161.         delete_shader(so);
  162. }
  163.  
  164. static void
  165. patch_vtx_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so,
  166.                 struct fd_vertex_stateobj *vtx)
  167. {
  168.         unsigned i;
  169.  
  170.         assert(so->num_vfetch_instrs == vtx->num_elements);
  171.  
  172.         /* update vtx fetch instructions: */
  173.         for (i = 0; i < so->num_vfetch_instrs; i++) {
  174.                 struct ir2_instruction *instr = so->vfetch_instrs[i];
  175.                 struct pipe_vertex_element *elem = &vtx->pipe[i];
  176.                 struct pipe_vertex_buffer *vb =
  177.                                 &ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index];
  178.                 enum pipe_format format = elem->src_format;
  179.                 const struct util_format_description *desc =
  180.                                 util_format_description(format);
  181.                 unsigned j;
  182.  
  183.                 /* Find the first non-VOID channel. */
  184.                 for (j = 0; j < 4; j++)
  185.                         if (desc->channel[j].type != UTIL_FORMAT_TYPE_VOID)
  186.                                 break;
  187.  
  188.                 /* CI/CIS can probably be set in compiler instead: */
  189.                 instr->fetch.const_idx = 20 + (i / 3);
  190.                 instr->fetch.const_idx_sel = i % 3;
  191.  
  192.                 instr->fetch.fmt = fd2_pipe2surface(format);
  193.                 instr->fetch.is_normalized = desc->channel[j].normalized;
  194.                 instr->fetch.is_signed =
  195.                                 desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED;
  196.                 instr->fetch.stride = vb->stride ? : 1;
  197.                 instr->fetch.offset = elem->src_offset;
  198.  
  199.                 for (j = 0; j < 4; j++)
  200.                         instr->regs[0]->swizzle[j] = "xyzw01__"[desc->swizzle[j]];
  201.  
  202.                 assert(instr->fetch.fmt != ~0);
  203.  
  204.                 DBG("vtx[%d]: %s (%d), ci=%d, cis=%d, id=%d, swizzle=%s, "
  205.                                 "stride=%d, offset=%d",
  206.                                 i, util_format_name(format),
  207.                                 instr->fetch.fmt,
  208.                                 instr->fetch.const_idx,
  209.                                 instr->fetch.const_idx_sel,
  210.                                 elem->instance_divisor,
  211.                                 instr->regs[0]->swizzle,
  212.                                 instr->fetch.stride,
  213.                                 instr->fetch.offset);
  214.         }
  215.  
  216.         /* trigger re-assemble: */
  217.         so->info.sizedwords = 0;
  218. }
  219.  
  220. static void
  221. patch_tex_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so,
  222.                 struct fd_texture_stateobj *tex)
  223. {
  224.         unsigned i;
  225.  
  226.         /* update tex fetch instructions: */
  227.         for (i = 0; i < so->num_tfetch_instrs; i++) {
  228.                 struct ir2_instruction *instr = so->tfetch_instrs[i].instr;
  229.                 unsigned samp_id = so->tfetch_instrs[i].samp_id;
  230.                 unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id);
  231.  
  232.                 if (const_idx != instr->fetch.const_idx) {
  233.                         instr->fetch.const_idx = const_idx;
  234.                         /* trigger re-assemble: */
  235.                         so->info.sizedwords = 0;
  236.                 }
  237.         }
  238. }
  239.  
  240. void
  241. fd2_program_validate(struct fd_context *ctx)
  242. {
  243.         struct fd_program_stateobj *prog = &ctx->prog;
  244.  
  245.         /* if vertex or frag shader is dirty, we may need to recompile. Compile
  246.          * frag shader first, as that assigns the register slots for exports
  247.          * from the vertex shader.  And therefore if frag shader has changed we
  248.          * need to recompile both vert and frag shader.
  249.          */
  250.         if (prog->dirty & FD_SHADER_DIRTY_FP)
  251.                 compile(prog, prog->fp);
  252.  
  253.         if (prog->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP))
  254.                 compile(prog, prog->vp);
  255.  
  256.         if (prog->dirty)
  257.                 ctx->dirty |= FD_DIRTY_PROG;
  258.  
  259.         /* if necessary, fix up vertex fetch instructions: */
  260.         if (ctx->dirty & (FD_DIRTY_VTXSTATE | FD_DIRTY_PROG))
  261.                 patch_vtx_fetches(ctx, prog->vp, ctx->vtx.vtx);
  262.  
  263.         /* if necessary, fix up texture fetch instructions: */
  264.         if (ctx->dirty & (FD_DIRTY_TEXSTATE | FD_DIRTY_PROG)) {
  265.                 patch_tex_fetches(ctx, prog->vp, &ctx->verttex);
  266.                 patch_tex_fetches(ctx, prog->fp, &ctx->fragtex);
  267.         }
  268. }
  269.  
  270. void
  271. fd2_program_emit(struct fd_ringbuffer *ring,
  272.                 struct fd_program_stateobj *prog)
  273. {
  274.         struct ir2_shader_info *vsi =
  275.                 &((struct fd2_shader_stateobj *)prog->vp)->info;
  276.         struct ir2_shader_info *fsi =
  277.                 &((struct fd2_shader_stateobj *)prog->fp)->info;
  278.         uint8_t vs_gprs, fs_gprs, vs_export;
  279.  
  280.         emit(ring, prog->vp);
  281.         emit(ring, prog->fp);
  282.  
  283.         vs_gprs = (vsi->max_reg < 0) ? 0x80 : vsi->max_reg;
  284.         fs_gprs = (fsi->max_reg < 0) ? 0x80 : fsi->max_reg;
  285.         vs_export = MAX2(1, prog->num_exports) - 1;
  286.  
  287.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  288.         OUT_RING(ring, CP_REG(REG_A2XX_SQ_PROGRAM_CNTL));
  289.         OUT_RING(ring, A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(POSITION_2_VECTORS_SPRITE) |
  290.                         A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE |
  291.                         A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE |
  292.                         A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(vs_export) |
  293.                         A2XX_SQ_PROGRAM_CNTL_PS_REGS(fs_gprs) |
  294.                         A2XX_SQ_PROGRAM_CNTL_VS_REGS(vs_gprs));
  295.  
  296.         prog->dirty = 0;
  297. }
  298.  
  299. /* Creates shader:
  300.  *    EXEC ADDR(0x2) CNT(0x1)
  301.  *       (S)FETCH:      SAMPLE  R0.xyzw = R0.xyx CONST(0) LOCATION(CENTER)
  302.  *    ALLOC PARAM/PIXEL SIZE(0x0)
  303.  *    EXEC_END ADDR(0x3) CNT(0x1)
  304.  *          ALU:        MAXv    export0 = R0, R0        ; gl_FragColor
  305.  *    NOP
  306.  */
  307. static struct fd2_shader_stateobj *
  308. create_blit_fp(void)
  309. {
  310.         struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
  311.         struct ir2_cf *cf;
  312.         struct ir2_instruction *instr;
  313.  
  314.         if (!so)
  315.                 return NULL;
  316.  
  317.         so->ir = ir2_shader_create();
  318.  
  319.         cf = ir2_cf_create(so->ir, EXEC);
  320.  
  321.         instr = ir2_instr_create_tex_fetch(cf, 0);
  322.         ir2_reg_create(instr, 0, "xyzw", 0);
  323.         ir2_reg_create(instr, 0, "xyx", 0);
  324.         instr->sync = true;
  325.  
  326.         cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
  327.         cf = ir2_cf_create(so->ir, EXEC_END);
  328.  
  329.         instr = ir2_instr_create_alu(cf, MAXv, ~0);
  330.         ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
  331.         ir2_reg_create(instr, 0, NULL, 0);
  332.         ir2_reg_create(instr, 0, NULL, 0);
  333.  
  334.         return assemble(so);
  335. }
  336.  
  337. /* Creates shader:
  338. *     EXEC ADDR(0x3) CNT(0x2)
  339. *           FETCH:      VERTEX  R1.xy01 = R0.x FMT_32_32_FLOAT UNSIGNED STRIDE(8) CONST(26, 1)
  340. *           FETCH:      VERTEX  R2.xyz1 = R0.x FMT_32_32_32_FLOAT UNSIGNED STRIDE(12) CONST(26, 0)
  341. *     ALLOC POSITION SIZE(0x0)
  342. *     EXEC ADDR(0x5) CNT(0x1)
  343. *           ALU:        MAXv    export62 = R2, R2       ; gl_Position
  344. *     ALLOC PARAM/PIXEL SIZE(0x0)
  345. *     EXEC_END ADDR(0x6) CNT(0x1)
  346. *           ALU:        MAXv    export0 = R1, R1
  347. *     NOP
  348.  */
  349. static struct fd2_shader_stateobj *
  350. create_blit_vp(void)
  351. {
  352.         struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
  353.         struct ir2_cf *cf;
  354.         struct ir2_instruction *instr;
  355.  
  356.         if (!so)
  357.                 return NULL;
  358.  
  359.         so->ir = ir2_shader_create();
  360.  
  361.         cf = ir2_cf_create(so->ir, EXEC);
  362.  
  363.         instr = ir2_instr_create_vtx_fetch(cf, 26, 1, FMT_32_32_FLOAT, false, 8);
  364.         instr->fetch.is_normalized = true;
  365.         ir2_reg_create(instr, 1, "xy01", 0);
  366.         ir2_reg_create(instr, 0, "x", 0);
  367.  
  368.         instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
  369.         instr->fetch.is_normalized = true;
  370.         ir2_reg_create(instr, 2, "xyz1", 0);
  371.         ir2_reg_create(instr, 0, "x", 0);
  372.  
  373.         cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
  374.         cf = ir2_cf_create(so->ir, EXEC);
  375.  
  376.         instr = ir2_instr_create_alu(cf, MAXv, ~0);
  377.         ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
  378.         ir2_reg_create(instr, 2, NULL, 0);
  379.         ir2_reg_create(instr, 2, NULL, 0);
  380.  
  381.         cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
  382.         cf = ir2_cf_create(so->ir, EXEC_END);
  383.  
  384.         instr = ir2_instr_create_alu(cf, MAXv, ~0);
  385.         ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
  386.         ir2_reg_create(instr, 1, NULL, 0);
  387.         ir2_reg_create(instr, 1, NULL, 0);
  388.  
  389.         return assemble(so);
  390. }
  391.  
  392. /* Creates shader:
  393.  *    ALLOC PARAM/PIXEL SIZE(0x0)
  394.  *    EXEC_END ADDR(0x1) CNT(0x1)
  395.  *          ALU:        MAXv    export0 = C0, C0        ; gl_FragColor
  396.  */
  397. static struct fd2_shader_stateobj *
  398. create_solid_fp(void)
  399. {
  400.         struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
  401.         struct ir2_cf *cf;
  402.         struct ir2_instruction *instr;
  403.  
  404.         if (!so)
  405.                 return NULL;
  406.  
  407.         so->ir = ir2_shader_create();
  408.  
  409.         cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
  410.         cf = ir2_cf_create(so->ir, EXEC_END);
  411.  
  412.         instr = ir2_instr_create_alu(cf, MAXv, ~0);
  413.         ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
  414.         ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
  415.         ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
  416.  
  417.         return assemble(so);
  418. }
  419.  
  420. /* Creates shader:
  421.  *    EXEC ADDR(0x3) CNT(0x1)
  422.  *       (S)FETCH:      VERTEX  R1.xyz1 = R0.x FMT_32_32_32_FLOAT
  423.  *                           UNSIGNED STRIDE(12) CONST(26, 0)
  424.  *    ALLOC POSITION SIZE(0x0)
  425.  *    EXEC ADDR(0x4) CNT(0x1)
  426.  *          ALU:        MAXv    export62 = R1, R1       ; gl_Position
  427.  *    ALLOC PARAM/PIXEL SIZE(0x0)
  428.  *    EXEC_END ADDR(0x5) CNT(0x0)
  429.  */
  430. static struct fd2_shader_stateobj *
  431. create_solid_vp(void)
  432. {
  433.         struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
  434.         struct ir2_cf *cf;
  435.         struct ir2_instruction *instr;
  436.  
  437.         if (!so)
  438.                 return NULL;
  439.  
  440.         so->ir = ir2_shader_create();
  441.  
  442.         cf = ir2_cf_create(so->ir, EXEC);
  443.  
  444.         instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
  445.         ir2_reg_create(instr, 1, "xyz1", 0);
  446.         ir2_reg_create(instr, 0, "x", 0);
  447.  
  448.         cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
  449.         cf = ir2_cf_create(so->ir, EXEC);
  450.  
  451.         instr = ir2_instr_create_alu(cf, MAXv, ~0);
  452.         ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
  453.         ir2_reg_create(instr, 1, NULL, 0);
  454.         ir2_reg_create(instr, 1, NULL, 0);
  455.  
  456.         cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
  457.         cf = ir2_cf_create(so->ir, EXEC_END);
  458.  
  459.         return assemble(so);
  460. }
  461.  
  462. void
  463. fd2_prog_init(struct pipe_context *pctx)
  464. {
  465.         struct fd_context *ctx = fd_context(pctx);
  466.  
  467.         pctx->create_fs_state = fd2_fp_state_create;
  468.         pctx->delete_fs_state = fd2_fp_state_delete;
  469.  
  470.         pctx->create_vs_state = fd2_vp_state_create;
  471.         pctx->delete_vs_state = fd2_vp_state_delete;
  472.  
  473.         fd_prog_init(pctx);
  474.  
  475.         ctx->solid_prog.fp = create_solid_fp();
  476.         ctx->solid_prog.vp = create_solid_vp();
  477.         ctx->blit_prog[0].fp = create_blit_fp();
  478.         ctx->blit_prog[0].vp = create_blit_vp();
  479. }
  480.