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. #ifndef IR3_SHADER_H_
  30. #define IR3_SHADER_H_
  31.  
  32. #include "ir3.h"
  33. #include "disasm.h"
  34.  
  35. typedef uint16_t ir3_semantic;  /* semantic name + index */
  36. static inline ir3_semantic
  37. ir3_semantic_name(uint8_t name, uint16_t index)
  38. {
  39.         return (name << 8) | (index & 0xff);
  40. }
  41.  
  42. static inline uint8_t sem2name(ir3_semantic sem)
  43. {
  44.         return sem >> 8;
  45. }
  46.  
  47. static inline uint16_t sem2idx(ir3_semantic sem)
  48. {
  49.         return sem & 0xff;
  50. }
  51.  
  52. /* Configuration key used to identify a shader variant.. different
  53.  * shader variants can be used to implement features not supported
  54.  * in hw (two sided color), binning-pass vertex shader, etc.
  55.  */
  56. struct ir3_shader_key {
  57.         union {
  58.                 struct {
  59.                         /* do we need to check {v,f}saturate_{s,t,r}? */
  60.                         unsigned has_per_samp : 1;
  61.  
  62.                         /*
  63.                          * Vertex shader variant parameters:
  64.                          */
  65.                         unsigned binning_pass : 1;
  66.  
  67.                         /*
  68.                          * Fragment shader variant parameters:
  69.                          */
  70.                         unsigned color_two_side : 1;
  71.                         unsigned half_precision : 1;
  72.                         /* used when shader needs to handle flat varyings (a4xx),
  73.                          * for TGSI_INTERPOLATE_COLOR:
  74.                          */
  75.                         unsigned rasterflat : 1;
  76.                 };
  77.                 uint32_t global;
  78.         };
  79.  
  80.         /* bitmask of sampler which needs coords clamped for vertex
  81.          * shader:
  82.          */
  83.         uint16_t vsaturate_s, vsaturate_t, vsaturate_r;
  84.  
  85.         /* bitmask of sampler which needs coords clamped for frag
  86.          * shader:
  87.          */
  88.         uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
  89.  
  90.         /* bitmask of sampler which produces integer outputs:
  91.          */
  92.         uint16_t vinteger_s, finteger_s;
  93. };
  94.  
  95. static inline bool
  96. ir3_shader_key_equal(struct ir3_shader_key *a, struct ir3_shader_key *b)
  97. {
  98.         /* slow-path if we need to check {v,f}saturate_{s,t,r} */
  99.         if (a->has_per_samp || b->has_per_samp)
  100.                 return memcmp(a, b, sizeof(struct ir3_shader_key)) == 0;
  101.         return a->global == b->global;
  102. }
  103.  
  104. struct ir3_shader_variant {
  105.         struct fd_bo *bo;
  106.  
  107.         struct ir3_shader_key key;
  108.  
  109.         struct ir3_info info;
  110.         struct ir3 *ir;
  111.  
  112.         /* the instructions length is in units of instruction groups
  113.          * (4 instructions for a3xx, 16 instructions for a4xx.. each
  114.          * instruction is 2 dwords):
  115.          */
  116.         unsigned instrlen;
  117.  
  118.         /* the constants length is in units of vec4's, and is the sum of
  119.          * the uniforms and the built-in compiler constants
  120.          */
  121.         unsigned constlen;
  122.  
  123.         /* About Linkage:
  124.          *   + Let the frag shader determine the position/compmask for the
  125.          *     varyings, since it is the place where we know if the varying
  126.          *     is actually used, and if so, which components are used.  So
  127.          *     what the hw calls "outloc" is taken from the "inloc" of the
  128.          *     frag shader.
  129.          *   + From the vert shader, we only need the output regid
  130.          */
  131.  
  132.         /* for frag shader, pos_regid holds the frag_pos, ie. what is passed
  133.          * to bary.f instructions
  134.          */
  135.         uint8_t pos_regid;
  136.         bool frag_coord, frag_face, color0_mrt;
  137.  
  138.         /* varyings/outputs: */
  139.         unsigned outputs_count;
  140.         struct {
  141.                 ir3_semantic semantic;
  142.                 uint8_t regid;
  143.         } outputs[16 + 2];  /* +POSITION +PSIZE */
  144.         bool writes_pos, writes_psize;
  145.  
  146.         /* vertices/inputs: */
  147.         unsigned inputs_count;
  148.         struct {
  149.                 ir3_semantic semantic;
  150.                 uint8_t regid;
  151.                 uint8_t compmask;
  152.                 uint8_t ncomp;
  153.                 /* In theory inloc of fs should match outloc of vs.  Or
  154.                  * rather the outloc of the vs is 8 plus the offset passed
  155.                  * to bary.f.  Presumably that +8 is to account for
  156.                  * gl_Position/gl_PointSize?
  157.                  *
  158.                  * NOTE inloc is currently aligned to 4 (we don't try
  159.                  * to pack varyings).  Changing this would likely break
  160.                  * assumptions in few places (like setting up of flat
  161.                  * shading in fd3_program) so be sure to check all the
  162.                  * spots where inloc is used.
  163.                  */
  164.                 uint8_t inloc;
  165.                 uint8_t bary;
  166.                 uint8_t interpolate;
  167.         } inputs[16 + 2];  /* +POSITION +FACE */
  168.  
  169.         unsigned total_in;       /* sum of inputs (scalar) */
  170.  
  171.         /* do we have one or more texture sample instructions: */
  172.         bool has_samp;
  173.  
  174.         /* do we have kill instructions: */
  175.         bool has_kill;
  176.  
  177.         /* const reg # of first immediate, ie. 1 == c1
  178.          * (not regid, because TGSI thinks in terms of vec4 registers,
  179.          * not scalar registers)
  180.          */
  181.         unsigned first_driver_param;
  182.         unsigned first_immediate;
  183.         unsigned immediates_count;
  184.         struct {
  185.                 uint32_t val[4];
  186.         } immediates[64];
  187.  
  188.         /* shader variants form a linked list: */
  189.         struct ir3_shader_variant *next;
  190.  
  191.         /* replicated here to avoid passing extra ptrs everywhere: */
  192.         enum shader_t type;
  193.         struct ir3_shader *shader;
  194. };
  195.  
  196. struct ir3_shader {
  197.         enum shader_t type;
  198.  
  199.         struct pipe_context *pctx;
  200.         const struct tgsi_token *tokens;
  201.  
  202.         struct ir3_shader_variant *variants;
  203.  
  204.         /* so far, only used for blit_prog shader.. values for
  205.          * VPC_VARYING_PS_REPL[i].MODE
  206.          */
  207.         uint32_t vpsrepl[8];
  208. };
  209.  
  210. void * ir3_shader_assemble(struct ir3_shader_variant *v, uint32_t gpu_id);
  211.  
  212. struct ir3_shader * ir3_shader_create(struct pipe_context *pctx,
  213.                 const struct tgsi_token *tokens, enum shader_t type);
  214. void ir3_shader_destroy(struct ir3_shader *shader);
  215. uint32_t ir3_shader_gpuid(struct ir3_shader *shader);
  216. struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
  217.                 struct ir3_shader_key key);
  218.  
  219. /*
  220.  * Helper/util:
  221.  */
  222.  
  223. static inline int
  224. ir3_find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
  225. {
  226.         int j;
  227.  
  228.         for (j = 0; j < so->outputs_count; j++)
  229.                 if (so->outputs[j].semantic == semantic)
  230.                         return j;
  231.  
  232.         /* it seems optional to have a OUT.BCOLOR[n] for each OUT.COLOR[n]
  233.          * in the vertex shader.. but the fragment shader doesn't know this
  234.          * so  it will always have both IN.COLOR[n] and IN.BCOLOR[n].  So
  235.          * at link time if there is no matching OUT.BCOLOR[n], we must map
  236.          * OUT.COLOR[n] to IN.BCOLOR[n].  And visa versa if there is only
  237.          * a OUT.BCOLOR[n] but no matching OUT.COLOR[n]
  238.          */
  239.         if (sem2name(semantic) == TGSI_SEMANTIC_BCOLOR) {
  240.                 unsigned idx = sem2idx(semantic);
  241.                 semantic = ir3_semantic_name(TGSI_SEMANTIC_COLOR, idx);
  242.         } else if (sem2name(semantic) == TGSI_SEMANTIC_COLOR) {
  243.                 unsigned idx = sem2idx(semantic);
  244.                 semantic = ir3_semantic_name(TGSI_SEMANTIC_BCOLOR, idx);
  245.         } else {
  246.                 return 0;
  247.         }
  248.  
  249.         for (j = 0; j < so->outputs_count; j++)
  250.                 if (so->outputs[j].semantic == semantic)
  251.                         return j;
  252.  
  253.         debug_assert(0);
  254.  
  255.         return 0;
  256. }
  257.  
  258. static inline int
  259. ir3_next_varying(const struct ir3_shader_variant *so, int i)
  260. {
  261.         while (++i < so->inputs_count)
  262.                 if (so->inputs[i].compmask && so->inputs[i].bary)
  263.                         break;
  264.         return i;
  265. }
  266.  
  267. static inline uint32_t
  268. ir3_find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
  269. {
  270.         int j;
  271.         for (j = 0; j < so->outputs_count; j++)
  272.                 if (so->outputs[j].semantic == semantic)
  273.                         return so->outputs[j].regid;
  274.         return regid(63, 0);
  275. }
  276.  
  277. #endif /* IR3_SHADER_H_ */
  278.