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) 2014 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 "fd4_program.h"
  40. #include "fd4_emit.h"
  41. #include "fd4_texture.h"
  42. #include "fd4_format.h"
  43.  
  44. static void
  45. delete_shader_stateobj(struct fd4_shader_stateobj *so)
  46. {
  47.         ir3_shader_destroy(so->shader);
  48.         free(so);
  49. }
  50.  
  51. static struct fd4_shader_stateobj *
  52. create_shader_stateobj(struct pipe_context *pctx, const struct pipe_shader_state *cso,
  53.                 enum shader_t type)
  54. {
  55.         struct fd4_shader_stateobj *so = CALLOC_STRUCT(fd4_shader_stateobj);
  56.         so->shader = ir3_shader_create(pctx, cso->tokens, type);
  57.         return so;
  58. }
  59.  
  60. static void *
  61. fd4_fp_state_create(struct pipe_context *pctx,
  62.                 const struct pipe_shader_state *cso)
  63. {
  64.         return create_shader_stateobj(pctx, cso, SHADER_FRAGMENT);
  65. }
  66.  
  67. static void
  68. fd4_fp_state_delete(struct pipe_context *pctx, void *hwcso)
  69. {
  70.         struct fd4_shader_stateobj *so = hwcso;
  71.         delete_shader_stateobj(so);
  72. }
  73.  
  74. static void *
  75. fd4_vp_state_create(struct pipe_context *pctx,
  76.                 const struct pipe_shader_state *cso)
  77. {
  78.         return create_shader_stateobj(pctx, cso, SHADER_VERTEX);
  79. }
  80.  
  81. static void
  82. fd4_vp_state_delete(struct pipe_context *pctx, void *hwcso)
  83. {
  84.         struct fd4_shader_stateobj *so = hwcso;
  85.         delete_shader_stateobj(so);
  86. }
  87.  
  88. static void
  89. emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so)
  90. {
  91.         const struct ir3_info *si = &so->info;
  92.         enum adreno_state_block sb;
  93.         enum adreno_state_src src;
  94.         uint32_t i, sz, *bin;
  95.  
  96.         if (so->type == SHADER_VERTEX) {
  97.                 sb = SB_VERT_SHADER;
  98.         } else {
  99.                 sb = SB_FRAG_SHADER;
  100.         }
  101.  
  102.         if (fd_mesa_debug & FD_DBG_DIRECT) {
  103.                 sz = si->sizedwords;
  104.                 src = SS_DIRECT;
  105.                 bin = fd_bo_map(so->bo);
  106.         } else {
  107.                 sz = 0;
  108.                 src = 2;  // enums different on a4xx..
  109.                 bin = NULL;
  110.         }
  111.  
  112.         OUT_PKT3(ring, CP_LOAD_STATE, 2 + sz);
  113.         OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(0) |
  114.                         CP_LOAD_STATE_0_STATE_SRC(src) |
  115.                         CP_LOAD_STATE_0_STATE_BLOCK(sb) |
  116.                         CP_LOAD_STATE_0_NUM_UNIT(so->instrlen));
  117.         if (bin) {
  118.                 OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) |
  119.                                 CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER));
  120.         } else {
  121.                 OUT_RELOC(ring, so->bo, 0,
  122.                                 CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER), 0);
  123.         }
  124.         for (i = 0; i < sz; i++) {
  125.                 OUT_RING(ring, bin[i]);
  126.         }
  127. }
  128.  
  129. struct stage {
  130.         const struct ir3_shader_variant *v;
  131.         const struct ir3_info *i;
  132.         /* const sizes are in units of 4 * vec4 */
  133.         uint8_t constoff;
  134.         uint8_t constlen;
  135.         /* instr sizes are in units of 16 instructions */
  136.         uint8_t instroff;
  137.         uint8_t instrlen;
  138. };
  139.  
  140. enum {
  141.         VS = 0,
  142.         FS = 1,
  143.         HS = 2,
  144.         DS = 3,
  145.         GS = 4,
  146.         MAX_STAGES
  147. };
  148.  
  149. static void
  150. setup_stages(struct fd4_emit *emit, struct stage *s)
  151. {
  152.         unsigned i;
  153.  
  154.         s[VS].v = fd4_emit_get_vp(emit);
  155.  
  156.         if (emit->key.binning_pass) {
  157.                 /* use dummy stateobj to simplify binning vs non-binning: */
  158.                 static const struct ir3_shader_variant binning_fp = {};
  159.                 s[FS].v = &binning_fp;
  160.         } else {
  161.                 s[FS].v = fd4_emit_get_fp(emit);
  162.         }
  163.  
  164.         s[HS].v = s[DS].v = s[GS].v = NULL;  /* for now */
  165.  
  166.         for (i = 0; i < MAX_STAGES; i++) {
  167.                 if (s[i].v) {
  168.                         s[i].i = &s[i].v->info;
  169.                         /* constlen is in units of 4 * vec4: */
  170.                         s[i].constlen = align(s[i].v->constlen, 4) / 4;
  171.                         /* instrlen is already in units of 16 instr.. although
  172.                          * probably we should ditch that and not make the compiler
  173.                          * care about instruction group size of a3xx vs a4xx
  174.                          */
  175.                         s[i].instrlen = s[i].v->instrlen;
  176.                 } else {
  177.                         s[i].i = NULL;
  178.                         s[i].constlen = 0;
  179.                         s[i].instrlen = 0;
  180.                 }
  181.         }
  182.  
  183.         /* NOTE: at least for gles2, blob partitions VS at bottom of const
  184.          * space and FS taking entire remaining space.  We probably don't
  185.          * need to do that the same way, but for now mimic what the blob
  186.          * does to make it easier to diff against register values from blob
  187.          *
  188.          * NOTE: if VS.instrlen + FS.instrlen > 64, then one or both shaders
  189.          * is run from external memory.
  190.          */
  191.         if ((s[VS].instrlen + s[FS].instrlen) > 64) {
  192.                 /* prioritize FS for internal memory: */
  193.                 if (s[FS].instrlen < 64) {
  194.                         /* if FS can fit, kick VS out to external memory: */
  195.                         s[VS].instrlen = 0;
  196.                 } else if (s[VS].instrlen < 64) {
  197.                         /* otherwise if VS can fit, kick out FS: */
  198.                         s[FS].instrlen = 0;
  199.                 } else {
  200.                         /* neither can fit, run both from external memory: */
  201.                         s[VS].instrlen = 0;
  202.                         s[FS].instrlen = 0;
  203.                 }
  204.         }
  205.         s[VS].constlen = 66;
  206.         s[FS].constlen = 128 - s[VS].constlen;
  207.         s[VS].instroff = 0;
  208.         s[VS].constoff = 0;
  209.         s[FS].instroff = 64 - s[FS].instrlen;
  210.         s[FS].constoff = s[VS].constlen;
  211.         s[HS].instroff = s[DS].instroff = s[GS].instroff = s[FS].instroff;
  212.         s[HS].constoff = s[DS].constoff = s[GS].constoff = s[FS].constoff;
  213. }
  214.  
  215. void
  216. fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit)
  217. {
  218.         struct stage s[MAX_STAGES];
  219.         uint32_t pos_regid, posz_regid, psize_regid, color_regid;
  220.         uint32_t face_regid, coord_regid, zwcoord_regid;
  221.         int constmode;
  222.         int i, j, k;
  223.  
  224.         setup_stages(emit, s);
  225.  
  226.         /* blob seems to always use constmode currently: */
  227.         constmode = 1;
  228.  
  229.         pos_regid = ir3_find_output_regid(s[VS].v,
  230.                 ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
  231.         posz_regid = ir3_find_output_regid(s[FS].v,
  232.                 ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
  233.         psize_regid = ir3_find_output_regid(s[VS].v,
  234.                 ir3_semantic_name(TGSI_SEMANTIC_PSIZE, 0));
  235.         color_regid = ir3_find_output_regid(s[FS].v,
  236.                 ir3_semantic_name(TGSI_SEMANTIC_COLOR, 0));
  237.  
  238.         if (util_format_is_alpha(emit->pformat))
  239.                 color_regid += 3;
  240.  
  241.         /* TODO get these dynamically: */
  242.         face_regid = s[FS].v->frag_face ? regid(0,0) : regid(63,0);
  243.         coord_regid = s[FS].v->frag_coord ? regid(0,0) : regid(63,0);
  244.         zwcoord_regid = s[FS].v->frag_coord ? regid(0,2) : regid(63,0);
  245.  
  246.         /* we could probably divide this up into things that need to be
  247.          * emitted if frag-prog is dirty vs if vert-prog is dirty..
  248.          */
  249.  
  250.         OUT_PKT0(ring, REG_A4XX_HLSQ_UPDATE_CONTROL, 1);
  251.         OUT_RING(ring, 0x00000003);
  252.  
  253.         OUT_PKT0(ring, REG_A4XX_HLSQ_CONTROL_0_REG, 5);
  254.         OUT_RING(ring, A4XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(FOUR_QUADS) |
  255.                         A4XX_HLSQ_CONTROL_0_REG_CONSTMODE(constmode) |
  256.                         A4XX_HLSQ_CONTROL_0_REG_FSSUPERTHREADENABLE |
  257.                         /* NOTE:  I guess SHADERRESTART and CONSTFULLUPDATE maybe
  258.                          * flush some caches? I think we only need to set those
  259.                          * bits if we have updated const or shader..
  260.                          */
  261.                         A4XX_HLSQ_CONTROL_0_REG_SPSHADERRESTART |
  262.                         A4XX_HLSQ_CONTROL_0_REG_SPCONSTFULLUPDATE);
  263.         OUT_RING(ring, A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(TWO_QUADS) |
  264.                         A4XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE |
  265.                         A4XX_HLSQ_CONTROL_1_REG_COORDREGID(coord_regid) |
  266.                         A4XX_HLSQ_CONTROL_1_REG_ZWCOORDREGID(zwcoord_regid));
  267.         OUT_RING(ring, A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(63) |
  268.                         0x3f3f000 |           /* XXX */
  269.                         A4XX_HLSQ_CONTROL_2_REG_FACEREGID(face_regid));
  270.         OUT_RING(ring, A4XX_HLSQ_CONTROL_3_REG_REGID(s[FS].v->pos_regid) |
  271.                         0xfcfcfc00);
  272.         OUT_RING(ring, 0x00fcfcfc);   /* XXX HLSQ_CONTROL_4 */
  273.  
  274.         OUT_PKT0(ring, REG_A4XX_HLSQ_VS_CONTROL_REG, 5);
  275.         OUT_RING(ring, A4XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH(s[VS].constlen) |
  276.                         A4XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET(s[VS].constoff) |
  277.                         A4XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH(s[VS].instrlen) |
  278.                         A4XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET(s[VS].instroff));
  279.         OUT_RING(ring, A4XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH(s[FS].constlen) |
  280.                         A4XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET(s[FS].constoff) |
  281.                         A4XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH(s[FS].instrlen) |
  282.                         A4XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET(s[FS].instroff));
  283.         OUT_RING(ring, A4XX_HLSQ_HS_CONTROL_REG_CONSTLENGTH(s[HS].constlen) |
  284.                         A4XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET(s[HS].constoff) |
  285.                         A4XX_HLSQ_HS_CONTROL_REG_INSTRLENGTH(s[HS].instrlen) |
  286.                         A4XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET(s[HS].instroff));
  287.         OUT_RING(ring, A4XX_HLSQ_DS_CONTROL_REG_CONSTLENGTH(s[DS].constlen) |
  288.                         A4XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET(s[DS].constoff) |
  289.                         A4XX_HLSQ_DS_CONTROL_REG_INSTRLENGTH(s[DS].instrlen) |
  290.                         A4XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET(s[DS].instroff));
  291.         OUT_RING(ring, A4XX_HLSQ_GS_CONTROL_REG_CONSTLENGTH(s[GS].constlen) |
  292.                         A4XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET(s[GS].constoff) |
  293.                         A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH(s[GS].instrlen) |
  294.                         A4XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET(s[GS].instroff));
  295.  
  296.         OUT_PKT0(ring, REG_A4XX_SP_SP_CTRL_REG, 1);
  297.         OUT_RING(ring, 0x140010 | /* XXX */
  298.                         COND(emit->key.binning_pass, A4XX_SP_SP_CTRL_REG_BINNING_PASS));
  299.  
  300.         OUT_PKT0(ring, REG_A4XX_SP_INSTR_CACHE_CTRL, 1);
  301.         OUT_RING(ring, 0x7f | /* XXX */
  302.                         COND(s[VS].instrlen, A4XX_SP_INSTR_CACHE_CTRL_VS_BUFFER) |
  303.                         COND(s[FS].instrlen, A4XX_SP_INSTR_CACHE_CTRL_FS_BUFFER) |
  304.                         COND(s[VS].instrlen && s[FS].instrlen,
  305.                                         A4XX_SP_INSTR_CACHE_CTRL_INSTR_BUFFER));
  306.  
  307.         OUT_PKT0(ring, REG_A4XX_SP_VS_LENGTH_REG, 1);
  308.         OUT_RING(ring, s[VS].v->instrlen);      /* SP_VS_LENGTH_REG */
  309.  
  310.         OUT_PKT0(ring, REG_A4XX_SP_VS_CTRL_REG0, 3);
  311.         OUT_RING(ring, A4XX_SP_VS_CTRL_REG0_THREADMODE(MULTI) |
  312.                         A4XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT(s[VS].i->max_half_reg + 1) |
  313.                         A4XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT(s[VS].i->max_reg + 1) |
  314.                         A4XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP(0) |
  315.                         A4XX_SP_VS_CTRL_REG0_THREADSIZE(TWO_QUADS) |
  316.                         A4XX_SP_VS_CTRL_REG0_SUPERTHREADMODE |
  317.                         COND(s[VS].v->has_samp, A4XX_SP_VS_CTRL_REG0_PIXLODENABLE));
  318.         OUT_RING(ring, A4XX_SP_VS_CTRL_REG1_CONSTLENGTH(s[VS].constlen) |
  319.                         A4XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING(s[VS].v->total_in));
  320.         OUT_RING(ring, A4XX_SP_VS_PARAM_REG_POSREGID(pos_regid) |
  321.                         A4XX_SP_VS_PARAM_REG_PSIZEREGID(psize_regid) |
  322.                         A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(align(s[FS].v->total_in, 4) / 4));
  323.  
  324.         for (i = 0, j = -1; (i < 16) && (j < (int)s[FS].v->inputs_count); i++) {
  325.                 uint32_t reg = 0;
  326.  
  327.                 OUT_PKT0(ring, REG_A4XX_SP_VS_OUT_REG(i), 1);
  328.  
  329.                 j = ir3_next_varying(s[FS].v, j);
  330.                 if (j < s[FS].v->inputs_count) {
  331.                         k = ir3_find_output(s[VS].v, s[FS].v->inputs[j].semantic);
  332.                         reg |= A4XX_SP_VS_OUT_REG_A_REGID(s[VS].v->outputs[k].regid);
  333.                         reg |= A4XX_SP_VS_OUT_REG_A_COMPMASK(s[FS].v->inputs[j].compmask);
  334.                 }
  335.  
  336.                 j = ir3_next_varying(s[FS].v, j);
  337.                 if (j < s[FS].v->inputs_count) {
  338.                         k = ir3_find_output(s[VS].v, s[FS].v->inputs[j].semantic);
  339.                         reg |= A4XX_SP_VS_OUT_REG_B_REGID(s[VS].v->outputs[k].regid);
  340.                         reg |= A4XX_SP_VS_OUT_REG_B_COMPMASK(s[FS].v->inputs[j].compmask);
  341.                 }
  342.  
  343.                 OUT_RING(ring, reg);
  344.         }
  345.  
  346.         for (i = 0, j = -1; (i < 8) && (j < (int)s[FS].v->inputs_count); i++) {
  347.                 uint32_t reg = 0;
  348.  
  349.                 OUT_PKT0(ring, REG_A4XX_SP_VS_VPC_DST_REG(i), 1);
  350.  
  351.                 j = ir3_next_varying(s[FS].v, j);
  352.                 if (j < s[FS].v->inputs_count)
  353.                         reg |= A4XX_SP_VS_VPC_DST_REG_OUTLOC0(s[FS].v->inputs[j].inloc);
  354.                 j = ir3_next_varying(s[FS].v, j);
  355.                 if (j < s[FS].v->inputs_count)
  356.                         reg |= A4XX_SP_VS_VPC_DST_REG_OUTLOC1(s[FS].v->inputs[j].inloc);
  357.                 j = ir3_next_varying(s[FS].v, j);
  358.                 if (j < s[FS].v->inputs_count)
  359.                         reg |= A4XX_SP_VS_VPC_DST_REG_OUTLOC2(s[FS].v->inputs[j].inloc);
  360.                 j = ir3_next_varying(s[FS].v, j);
  361.                 if (j < s[FS].v->inputs_count)
  362.                         reg |= A4XX_SP_VS_VPC_DST_REG_OUTLOC3(s[FS].v->inputs[j].inloc);
  363.  
  364.                 OUT_RING(ring, reg);
  365.         }
  366.  
  367.         OUT_PKT0(ring, REG_A4XX_SP_VS_OBJ_OFFSET_REG, 2);
  368.         OUT_RING(ring, A4XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(s[VS].constoff) |
  369.                         A4XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(s[VS].instroff));
  370.         OUT_RELOC(ring, s[VS].v->bo, 0, 0, 0);  /* SP_VS_OBJ_START_REG */
  371.  
  372.         OUT_PKT0(ring, REG_A4XX_SP_FS_LENGTH_REG, 1);
  373.         OUT_RING(ring, s[FS].v->instrlen);  /* SP_FS_LENGTH_REG */
  374.  
  375.         OUT_PKT0(ring, REG_A4XX_SP_FS_CTRL_REG0, 2);
  376.         OUT_RING(ring, A4XX_SP_FS_CTRL_REG0_THREADMODE(MULTI) |
  377.                         COND(s[FS].v->total_in > 0, A4XX_SP_FS_CTRL_REG0_VARYING) |
  378.                         A4XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT(s[FS].i->max_half_reg + 1) |
  379.                         A4XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT(s[FS].i->max_reg + 1) |
  380.                         A4XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP(1) |
  381.                         A4XX_SP_FS_CTRL_REG0_THREADSIZE(FOUR_QUADS) |
  382.                         A4XX_SP_FS_CTRL_REG0_SUPERTHREADMODE |
  383.                         COND(s[FS].v->has_samp, A4XX_SP_FS_CTRL_REG0_PIXLODENABLE));
  384.         OUT_RING(ring, A4XX_SP_FS_CTRL_REG1_CONSTLENGTH(s[FS].constlen) |
  385.                         0x80000000 |      /* XXX */
  386.                         COND(s[FS].v->frag_face, A4XX_SP_FS_CTRL_REG1_FACENESS) |
  387.                         COND(s[FS].v->total_in > 0, A4XX_SP_FS_CTRL_REG1_VARYING) |
  388.                         COND(s[FS].v->frag_coord, A4XX_SP_FS_CTRL_REG1_FRAGCOORD));
  389.  
  390.         OUT_PKT0(ring, REG_A4XX_SP_FS_OBJ_OFFSET_REG, 2);
  391.         OUT_RING(ring, A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(s[FS].constoff) |
  392.                         A4XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(s[FS].instroff));
  393.         if (emit->key.binning_pass)
  394.                 OUT_RING(ring, 0x00000000);
  395.         else
  396.                 OUT_RELOC(ring, s[FS].v->bo, 0, 0, 0);  /* SP_FS_OBJ_START_REG */
  397.  
  398.         OUT_PKT0(ring, REG_A4XX_SP_HS_OBJ_OFFSET_REG, 1);
  399.         OUT_RING(ring, A4XX_SP_HS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(s[HS].constoff) |
  400.                         A4XX_SP_HS_OBJ_OFFSET_REG_SHADEROBJOFFSET(s[HS].instroff));
  401.  
  402.         OUT_PKT0(ring, REG_A4XX_SP_DS_OBJ_OFFSET_REG, 1);
  403.         OUT_RING(ring, A4XX_SP_DS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(s[DS].constoff) |
  404.                         A4XX_SP_DS_OBJ_OFFSET_REG_SHADEROBJOFFSET(s[DS].instroff));
  405.  
  406.         OUT_PKT0(ring, REG_A4XX_SP_GS_OBJ_OFFSET_REG, 1);
  407.         OUT_RING(ring, A4XX_SP_GS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(s[GS].constoff) |
  408.                         A4XX_SP_GS_OBJ_OFFSET_REG_SHADEROBJOFFSET(s[GS].instroff));
  409.  
  410.         OUT_PKT0(ring, REG_A4XX_RB_RENDER_CONTROL2, 1);
  411.         OUT_RING(ring, A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES(0) |
  412.                         COND(s[FS].v->total_in > 0, A4XX_RB_RENDER_CONTROL2_VARYING) |
  413.                         COND(s[FS].v->frag_face, A4XX_RB_RENDER_CONTROL2_FACENESS) |
  414.                         COND(s[FS].v->frag_coord, A4XX_RB_RENDER_CONTROL2_XCOORD |
  415.                                         A4XX_RB_RENDER_CONTROL2_YCOORD |
  416. // TODO enabling gl_FragCoord.z is causing lockups on 0ad (but seems
  417. // to work everywhere else).
  418. //                                      A4XX_RB_RENDER_CONTROL2_ZCOORD |
  419.                                         A4XX_RB_RENDER_CONTROL2_WCOORD));
  420.  
  421.         OUT_PKT0(ring, REG_A4XX_RB_FS_OUTPUT_REG, 1);
  422.         OUT_RING(ring, A4XX_RB_FS_OUTPUT_REG_MRT(1) |
  423.                         COND(s[FS].v->writes_pos, A4XX_RB_FS_OUTPUT_REG_FRAG_WRITES_Z));
  424.  
  425.         OUT_PKT0(ring, REG_A4XX_SP_FS_OUTPUT_REG, 1);
  426.         if (s[FS].v->writes_pos) {
  427.                 OUT_RING(ring, 0x00000001 |
  428.                                 A4XX_SP_FS_OUTPUT_REG_DEPTH_ENABLE |
  429.                                 A4XX_SP_FS_OUTPUT_REG_DEPTH_REGID(posz_regid));
  430.         } else {
  431.                 OUT_RING(ring, 0x00000001);
  432.         }
  433.  
  434.         OUT_PKT0(ring, REG_A4XX_SP_FS_MRT_REG(0), 8);
  435.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(color_regid) |
  436.                         A4XX_SP_FS_MRT_REG_MRTFORMAT(emit->format) |
  437.                         COND(emit->key.half_precision, A4XX_SP_FS_MRT_REG_HALF_PRECISION));
  438.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(0));
  439.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(0));
  440.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(0));
  441.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(0));
  442.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(0));
  443.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(0));
  444.         OUT_RING(ring, A4XX_SP_FS_MRT_REG_REGID(0));
  445.  
  446.         if (emit->key.binning_pass) {
  447.                 OUT_PKT0(ring, REG_A4XX_VPC_ATTR, 2);
  448.                 OUT_RING(ring, A4XX_VPC_ATTR_THRDASSIGN(1) |
  449.                                 0x40000000 |      /* XXX */
  450.                                 COND(s[VS].v->writes_psize, A4XX_VPC_ATTR_PSIZE));
  451.                 OUT_RING(ring, 0x00000000);
  452.         } else {
  453.                 uint32_t vinterp[8], flatshade[2];
  454.  
  455.                 memset(vinterp, 0, sizeof(vinterp));
  456.                 memset(flatshade, 0, sizeof(flatshade));
  457.  
  458.                 /* looks like we need to do int varyings in the frag
  459.                  * shader on a4xx (no flatshad reg?  or a420.0 bug?):
  460.                  *
  461.                  *    (sy)(ss)nop
  462.                  *    (sy)ldlv.u32 r0.x,l[r0.x], 1
  463.                  *    ldlv.u32 r0.y,l[r0.x+1], 1
  464.                  *    (ss)bary.f (ei)r63.x, 0, r0.x
  465.                  *    (ss)(rpt1)cov.s32f16 hr0.x, (r)r0.x
  466.                  *    (rpt5)nop
  467.                  *    sam (f16)(xyzw)hr0.x, hr0.x, s#0, t#0
  468.                  *
  469.                  * Possibly on later a4xx variants we'll be able to use
  470.                  * something like the code below instead of workaround
  471.                  * in the shader:
  472.                  */
  473. #if 0
  474.                 /* figure out VARYING_INTERP / FLAT_SHAD register values: */
  475.                 for (j = -1; (j = ir3_next_varying(s[FS].v, j)) < (int)s[FS].v->inputs_count; ) {
  476.                         uint32_t interp = s[FS].v->inputs[j].interpolate;
  477.                         if ((interp == TGSI_INTERPOLATE_CONSTANT) ||
  478.                                         ((interp == TGSI_INTERPOLATE_COLOR) && emit->rasterflat)) {
  479.                                 /* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG
  480.                                  * instead.. rather than -8 everywhere else..
  481.                                  */
  482.                                 uint32_t loc = s[FS].v->inputs[j].inloc - 8;
  483.  
  484.                                 /* currently assuming varyings aligned to 4 (not
  485.                                  * packed):
  486.                                  */
  487.                                 debug_assert((loc % 4) == 0);
  488.  
  489.                                 for (i = 0; i < 4; i++, loc++) {
  490.                                         vinterp[loc / 16] |= 1 << ((loc % 16) * 2);
  491.                                         flatshade[loc / 32] |= 1 << (loc % 32);
  492.                                 }
  493.                         }
  494.                 }
  495. #endif
  496.  
  497.                 OUT_PKT0(ring, REG_A4XX_VPC_ATTR, 2);
  498.                 OUT_RING(ring, A4XX_VPC_ATTR_TOTALATTR(s[FS].v->total_in) |
  499.                                 A4XX_VPC_ATTR_THRDASSIGN(1) |
  500.                                 COND(s[FS].v->total_in > 0, A4XX_VPC_ATTR_ENABLE) |
  501.                                 0x40000000 |      /* XXX */
  502.                                 COND(s[VS].v->writes_psize, A4XX_VPC_ATTR_PSIZE));
  503.                 OUT_RING(ring, A4XX_VPC_PACK_NUMFPNONPOSVAR(s[FS].v->total_in) |
  504.                                 A4XX_VPC_PACK_NUMNONPOSVSVAR(s[FS].v->total_in));
  505.  
  506.                 OUT_PKT0(ring, REG_A4XX_VPC_VARYING_INTERP_MODE(0), 8);
  507.                 for (i = 0; i < 8; i++)
  508.                         OUT_RING(ring, vinterp[i]);     /* VPC_VARYING_INTERP[i].MODE */
  509.  
  510.                 OUT_PKT0(ring, REG_A4XX_VPC_VARYING_PS_REPL_MODE(0), 8);
  511.                 for (i = 0; i < 8; i++)
  512.                         OUT_RING(ring, s[FS].v->shader->vpsrepl[i]);   /* VPC_VARYING_PS_REPL[i] */
  513.         }
  514.  
  515.         if (s[VS].instrlen)
  516.                 emit_shader(ring, s[VS].v);
  517.  
  518.         if (!emit->key.binning_pass)
  519.                 if (s[FS].instrlen)
  520.                         emit_shader(ring, s[FS].v);
  521. }
  522.  
  523. /* hack.. until we figure out how to deal w/ vpsrepl properly.. */
  524. static void
  525. fix_blit_fp(struct pipe_context *pctx)
  526. {
  527.         struct fd_context *ctx = fd_context(pctx);
  528.         struct fd4_shader_stateobj *so = ctx->blit_prog[0].fp;
  529.  
  530.         so->shader->vpsrepl[0] = 0x99999999;
  531.         so->shader->vpsrepl[1] = 0x99999999;
  532.         so->shader->vpsrepl[2] = 0x99999999;
  533.         so->shader->vpsrepl[3] = 0x99999999;
  534. }
  535.  
  536. void
  537. fd4_prog_init(struct pipe_context *pctx)
  538. {
  539.         pctx->create_fs_state = fd4_fp_state_create;
  540.         pctx->delete_fs_state = fd4_fp_state_delete;
  541.  
  542.         pctx->create_vs_state = fd4_vp_state_create;
  543.         pctx->delete_vs_state = fd4_vp_state_delete;
  544.  
  545.         fd_prog_init(pctx);
  546.  
  547.         fix_blit_fp(pctx);
  548. }
  549.