Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #ifndef TGSI_TRANSFORM_H
  29. #define TGSI_TRANSFORM_H
  30.  
  31.  
  32. #include "pipe/p_shader_tokens.h"
  33. #include "tgsi/tgsi_parse.h"
  34. #include "tgsi/tgsi_build.h"
  35.  
  36.  
  37.  
  38. /**
  39.  * Subclass this to add caller-specific data
  40.  */
  41. struct tgsi_transform_context
  42. {
  43. /**** PUBLIC ***/
  44.  
  45.    /**
  46.     * User-defined callbacks invoked per instruction.
  47.     */
  48.    void (*transform_instruction)(struct tgsi_transform_context *ctx,
  49.                                  struct tgsi_full_instruction *inst);
  50.  
  51.    void (*transform_declaration)(struct tgsi_transform_context *ctx,
  52.                                  struct tgsi_full_declaration *decl);
  53.  
  54.    void (*transform_immediate)(struct tgsi_transform_context *ctx,
  55.                                struct tgsi_full_immediate *imm);
  56.    void (*transform_property)(struct tgsi_transform_context *ctx,
  57.                               struct tgsi_full_property *prop);
  58.  
  59.    /**
  60.     * Called after last declaration, before first instruction.  This is
  61.     * where the user might insert new declarations and/or instructions.
  62.     */
  63.    void (*prolog)(struct tgsi_transform_context *ctx);
  64.  
  65.    /**
  66.     * Called at end of input program to allow caller to append extra
  67.     * instructions.  Return number of tokens emitted.
  68.     */
  69.    void (*epilog)(struct tgsi_transform_context *ctx);
  70.  
  71.  
  72. /*** PRIVATE ***/
  73.  
  74.    /**
  75.     * These are setup by tgsi_transform_shader() and cannot be overridden.
  76.     * Meant to be called from in the above user callback functions.
  77.     */
  78.    void (*emit_instruction)(struct tgsi_transform_context *ctx,
  79.                             const struct tgsi_full_instruction *inst);
  80.    void (*emit_declaration)(struct tgsi_transform_context *ctx,
  81.                             const struct tgsi_full_declaration *decl);
  82.    void (*emit_immediate)(struct tgsi_transform_context *ctx,
  83.                           const struct tgsi_full_immediate *imm);
  84.    void (*emit_property)(struct tgsi_transform_context *ctx,
  85.                          const struct tgsi_full_property *prop);
  86.  
  87.    struct tgsi_header *header;
  88.    uint max_tokens_out;
  89.    struct tgsi_token *tokens_out;
  90.    uint ti;
  91. };
  92.  
  93.  
  94. /**
  95.  * Helper for emitting temporary register declarations.
  96.  */
  97. static INLINE void
  98. tgsi_transform_temp_decl(struct tgsi_transform_context *ctx,
  99.                          unsigned index)
  100. {
  101.    struct tgsi_full_declaration decl;
  102.  
  103.    decl = tgsi_default_full_declaration();
  104.    decl.Declaration.File = TGSI_FILE_TEMPORARY;
  105.    decl.Range.First =
  106.    decl.Range.Last = index;
  107.    ctx->emit_declaration(ctx, &decl);
  108. }
  109.  
  110.  
  111. static INLINE void
  112. tgsi_transform_input_decl(struct tgsi_transform_context *ctx,
  113.                           unsigned index,
  114.                           unsigned sem_name, unsigned sem_index,
  115.                           unsigned interp)
  116. {
  117.    struct tgsi_full_declaration decl;
  118.  
  119.    decl = tgsi_default_full_declaration();
  120.    decl.Declaration.File = TGSI_FILE_INPUT;
  121.    decl.Declaration.Interpolate = 1;
  122.    decl.Declaration.Semantic = 1;
  123.    decl.Semantic.Name = sem_name;
  124.    decl.Semantic.Index = sem_index;
  125.    decl.Range.First =
  126.    decl.Range.Last = index;
  127.    decl.Interp.Interpolate = interp;
  128.  
  129.    ctx->emit_declaration(ctx, &decl);
  130. }
  131.  
  132.  
  133. static INLINE void
  134. tgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
  135.                             unsigned index)
  136. {
  137.    struct tgsi_full_declaration decl;
  138.  
  139.    decl = tgsi_default_full_declaration();
  140.    decl.Declaration.File = TGSI_FILE_SAMPLER;
  141.    decl.Range.First =
  142.    decl.Range.Last = index;
  143.    ctx->emit_declaration(ctx, &decl);
  144. }
  145.  
  146.  
  147. static INLINE void
  148. tgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
  149.                               float x, float y, float z, float w)
  150. {
  151.    struct tgsi_full_immediate immed;
  152.    unsigned size = 4;
  153.  
  154.    immed = tgsi_default_full_immediate();
  155.    immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
  156.    immed.u[0].Float = x;
  157.    immed.u[1].Float = y;
  158.    immed.u[2].Float = z;
  159.    immed.u[3].Float = w;
  160.  
  161.    ctx->emit_immediate(ctx, &immed);
  162. }
  163.  
  164.  
  165. /**
  166.  * Helper for emitting 1-operand instructions.
  167.  */
  168. static INLINE void
  169. tgsi_transform_op1_inst(struct tgsi_transform_context *ctx,
  170.                         unsigned opcode,
  171.                         unsigned dst_file,
  172.                         unsigned dst_index,
  173.                         unsigned dst_writemask,
  174.                         unsigned src0_file,
  175.                         unsigned src0_index)
  176. {
  177.    struct tgsi_full_instruction inst;
  178.  
  179.    inst = tgsi_default_full_instruction();
  180.    inst.Instruction.Opcode = opcode;
  181.    inst.Instruction.NumDstRegs = 1;
  182.    inst.Dst[0].Register.File = dst_file,
  183.    inst.Dst[0].Register.Index = dst_index;
  184.    inst.Dst[0].Register.WriteMask = dst_writemask;
  185.    inst.Instruction.NumSrcRegs = 1;
  186.    inst.Src[0].Register.File = src0_file;
  187.    inst.Src[0].Register.Index = src0_index;
  188.  
  189.    ctx->emit_instruction(ctx, &inst);
  190. }
  191.  
  192.  
  193. static INLINE void
  194. tgsi_transform_op2_inst(struct tgsi_transform_context *ctx,
  195.                         unsigned opcode,
  196.                         unsigned dst_file,
  197.                         unsigned dst_index,
  198.                         unsigned dst_writemask,
  199.                         unsigned src0_file,
  200.                         unsigned src0_index,
  201.                         unsigned src1_file,
  202.                         unsigned src1_index)
  203. {
  204.    struct tgsi_full_instruction inst;
  205.  
  206.    inst = tgsi_default_full_instruction();
  207.    inst.Instruction.Opcode = opcode;
  208.    inst.Instruction.NumDstRegs = 1;
  209.    inst.Dst[0].Register.File = dst_file,
  210.    inst.Dst[0].Register.Index = dst_index;
  211.    inst.Dst[0].Register.WriteMask = dst_writemask;
  212.    inst.Instruction.NumSrcRegs = 2;
  213.    inst.Src[0].Register.File = src0_file;
  214.    inst.Src[0].Register.Index = src0_index;
  215.    inst.Src[1].Register.File = src1_file;
  216.    inst.Src[1].Register.Index = src1_index;
  217.  
  218.    ctx->emit_instruction(ctx, &inst);
  219. }
  220.  
  221.  
  222. static INLINE void
  223. tgsi_transform_op1_swz_inst(struct tgsi_transform_context *ctx,
  224.                             unsigned opcode,
  225.                             unsigned dst_file,
  226.                             unsigned dst_index,
  227.                             unsigned dst_writemask,
  228.                             unsigned src0_file,
  229.                             unsigned src0_index,
  230.                             unsigned src0_swizzle)
  231. {
  232.    struct tgsi_full_instruction inst;
  233.  
  234.    inst = tgsi_default_full_instruction();
  235.    inst.Instruction.Opcode = opcode;
  236.    inst.Instruction.NumDstRegs = 1;
  237.    inst.Dst[0].Register.File = dst_file,
  238.    inst.Dst[0].Register.Index = dst_index;
  239.    inst.Dst[0].Register.WriteMask = dst_writemask;
  240.    inst.Instruction.NumSrcRegs = 1;
  241.    inst.Src[0].Register.File = src0_file;
  242.    inst.Src[0].Register.Index = src0_index;
  243.    switch (dst_writemask) {
  244.    case TGSI_WRITEMASK_X:
  245.       inst.Src[0].Register.SwizzleX = src0_swizzle;
  246.       break;
  247.    case TGSI_WRITEMASK_Y:
  248.       inst.Src[0].Register.SwizzleY = src0_swizzle;
  249.       break;
  250.    case TGSI_WRITEMASK_Z:
  251.       inst.Src[0].Register.SwizzleZ = src0_swizzle;
  252.       break;
  253.    case TGSI_WRITEMASK_W:
  254.       inst.Src[0].Register.SwizzleW = src0_swizzle;
  255.       break;
  256.    default:
  257.       ; /* nothing */
  258.    }
  259.  
  260.    ctx->emit_instruction(ctx, &inst);
  261. }
  262.  
  263.  
  264. static INLINE void
  265. tgsi_transform_op2_swz_inst(struct tgsi_transform_context *ctx,
  266.                             unsigned opcode,
  267.                             unsigned dst_file,
  268.                             unsigned dst_index,
  269.                             unsigned dst_writemask,
  270.                             unsigned src0_file,
  271.                             unsigned src0_index,
  272.                             unsigned src0_swizzle,
  273.                             unsigned src1_file,
  274.                             unsigned src1_index,
  275.                             unsigned src1_swizzle)
  276. {
  277.    struct tgsi_full_instruction inst;
  278.  
  279.    inst = tgsi_default_full_instruction();
  280.    inst.Instruction.Opcode = opcode;
  281.    inst.Instruction.NumDstRegs = 1;
  282.    inst.Dst[0].Register.File = dst_file,
  283.    inst.Dst[0].Register.Index = dst_index;
  284.    inst.Dst[0].Register.WriteMask = dst_writemask;
  285.    inst.Instruction.NumSrcRegs = 2;
  286.    inst.Src[0].Register.File = src0_file;
  287.    inst.Src[0].Register.Index = src0_index;
  288.    inst.Src[1].Register.File = src1_file;
  289.    inst.Src[1].Register.Index = src1_index;
  290.    switch (dst_writemask) {
  291.    case TGSI_WRITEMASK_X:
  292.       inst.Src[0].Register.SwizzleX = src0_swizzle;
  293.       inst.Src[1].Register.SwizzleX = src1_swizzle;
  294.       break;
  295.    case TGSI_WRITEMASK_Y:
  296.       inst.Src[0].Register.SwizzleY = src0_swizzle;
  297.       inst.Src[1].Register.SwizzleY = src1_swizzle;
  298.       break;
  299.    case TGSI_WRITEMASK_Z:
  300.       inst.Src[0].Register.SwizzleZ = src0_swizzle;
  301.       inst.Src[1].Register.SwizzleZ = src1_swizzle;
  302.       break;
  303.    case TGSI_WRITEMASK_W:
  304.       inst.Src[0].Register.SwizzleW = src0_swizzle;
  305.       inst.Src[1].Register.SwizzleW = src1_swizzle;
  306.       break;
  307.    default:
  308.       ; /* nothing */
  309.    }
  310.  
  311.    ctx->emit_instruction(ctx, &inst);
  312. }
  313.  
  314.  
  315. static INLINE void
  316. tgsi_transform_op3_swz_inst(struct tgsi_transform_context *ctx,
  317.                             unsigned opcode,
  318.                             unsigned dst_file,
  319.                             unsigned dst_index,
  320.                             unsigned dst_writemask,
  321.                             unsigned src0_file,
  322.                             unsigned src0_index,
  323.                             unsigned src0_swizzle,
  324.                             unsigned src0_negate,
  325.                             unsigned src1_file,
  326.                             unsigned src1_index,
  327.                             unsigned src1_swizzle,
  328.                             unsigned src2_file,
  329.                             unsigned src2_index,
  330.                             unsigned src2_swizzle)
  331. {
  332.    struct tgsi_full_instruction inst;
  333.  
  334.    inst = tgsi_default_full_instruction();
  335.    inst.Instruction.Opcode = opcode;
  336.    inst.Instruction.NumDstRegs = 1;
  337.    inst.Dst[0].Register.File = dst_file,
  338.    inst.Dst[0].Register.Index = dst_index;
  339.    inst.Dst[0].Register.WriteMask = dst_writemask;
  340.    inst.Instruction.NumSrcRegs = 3;
  341.    inst.Src[0].Register.File = src0_file;
  342.    inst.Src[0].Register.Index = src0_index;
  343.    inst.Src[0].Register.Negate = src0_negate;
  344.    inst.Src[1].Register.File = src1_file;
  345.    inst.Src[1].Register.Index = src1_index;
  346.    inst.Src[2].Register.File = src2_file;
  347.    inst.Src[2].Register.Index = src2_index;
  348.    switch (dst_writemask) {
  349.    case TGSI_WRITEMASK_X:
  350.       inst.Src[0].Register.SwizzleX = src0_swizzle;
  351.       inst.Src[1].Register.SwizzleX = src1_swizzle;
  352.       inst.Src[2].Register.SwizzleX = src2_swizzle;
  353.       break;
  354.    case TGSI_WRITEMASK_Y:
  355.       inst.Src[0].Register.SwizzleY = src0_swizzle;
  356.       inst.Src[1].Register.SwizzleY = src1_swizzle;
  357.       inst.Src[2].Register.SwizzleY = src2_swizzle;
  358.       break;
  359.    case TGSI_WRITEMASK_Z:
  360.       inst.Src[0].Register.SwizzleZ = src0_swizzle;
  361.       inst.Src[1].Register.SwizzleZ = src1_swizzle;
  362.       inst.Src[2].Register.SwizzleZ = src2_swizzle;
  363.       break;
  364.    case TGSI_WRITEMASK_W:
  365.       inst.Src[0].Register.SwizzleW = src0_swizzle;
  366.       inst.Src[1].Register.SwizzleW = src1_swizzle;
  367.       inst.Src[2].Register.SwizzleW = src2_swizzle;
  368.       break;
  369.    default:
  370.       ; /* nothing */
  371.    }
  372.  
  373.    ctx->emit_instruction(ctx, &inst);
  374. }
  375.  
  376.  
  377. static INLINE void
  378. tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
  379.                          unsigned src_file,
  380.                          unsigned src_index,
  381.                          unsigned src_swizzle)
  382. {
  383.    struct tgsi_full_instruction inst;
  384.  
  385.    inst = tgsi_default_full_instruction();
  386.    inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
  387.    inst.Instruction.NumDstRegs = 0;
  388.    inst.Instruction.NumSrcRegs = 1;
  389.    inst.Src[0].Register.File = src_file;
  390.    inst.Src[0].Register.Index = src_index;
  391.    inst.Src[0].Register.SwizzleX =
  392.    inst.Src[0].Register.SwizzleY =
  393.    inst.Src[0].Register.SwizzleZ =
  394.    inst.Src[0].Register.SwizzleW = src_swizzle;
  395.    inst.Src[0].Register.Negate = 1;
  396.  
  397.    ctx->emit_instruction(ctx, &inst);
  398. }
  399.  
  400.  
  401. static INLINE void
  402. tgsi_transform_tex_2d_inst(struct tgsi_transform_context *ctx,
  403.                            unsigned dst_file,
  404.                            unsigned dst_index,
  405.                            unsigned src_file,
  406.                            unsigned src_index,
  407.                            unsigned sampler_index)
  408. {
  409.    struct tgsi_full_instruction inst;
  410.  
  411.    inst = tgsi_default_full_instruction();
  412.    inst.Instruction.Opcode = TGSI_OPCODE_TEX;
  413.    inst.Instruction.NumDstRegs = 1;
  414.    inst.Dst[0].Register.File = dst_file;
  415.    inst.Dst[0].Register.Index = dst_index;
  416.    inst.Instruction.NumSrcRegs = 2;
  417.    inst.Instruction.Texture = TRUE;
  418.    inst.Texture.Texture = TGSI_TEXTURE_2D;
  419.    inst.Src[0].Register.File = src_file;
  420.    inst.Src[0].Register.Index = src_index;
  421.    inst.Src[1].Register.File = TGSI_FILE_SAMPLER;
  422.    inst.Src[1].Register.Index = sampler_index;
  423.  
  424.    ctx->emit_instruction(ctx, &inst);
  425. }
  426.  
  427.  
  428. extern int
  429. tgsi_transform_shader(const struct tgsi_token *tokens_in,
  430.                       struct tgsi_token *tokens_out,
  431.                       uint max_tokens_out,
  432.                       struct tgsi_transform_context *ctx);
  433.  
  434.  
  435. #endif /* TGSI_TRANSFORM_H */
  436.