gallium: add PIPE_SHADER_CAP_GLSL_16BIT_TEMPS for LowerPrecisionTemporaries
[mesa.git] / src / gallium / drivers / svga / svga_tgsi_emit.h
index 2557824293ee042f5055dfacc070890a7b656900..357d772e7a6c7a4402229ecbb0e169bfc803617b 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "tgsi/tgsi_scan.h"
 #include "svga_hw_reg.h"
+#include "svga_shader.h"
 #include "svga_tgsi.h"
 #include "svga3d_shaderdefs.h"
 
@@ -38,33 +39,34 @@ struct src_register
 };
 
 
-struct svga_arl_consts {
+struct svga_arl_consts
+{
    int number;
    int idx;
    int swizzle;
    int arl_num;
 };
 
-/* Internal functions:
- */
 
+/**
+ * This is the context/state used during TGSI->SVGA shader translation.
+ */
 struct svga_shader_emitter
 {
-   boolean use_sm30;
-   
    unsigned size;
    char *buf;
    char *ptr;
 
-   union svga_compile_key key;
+   struct svga_compile_key key;
    struct tgsi_shader_info info;
    int unit;
 
    int imm_start;
 
-   int nr_hw_const;
+   int nr_hw_float_const;
+   int nr_hw_int_const;
    int nr_hw_temp;
-   
+
    int insn_offset;
 
    int internal_temp_count;
@@ -78,30 +80,53 @@ struct svga_shader_emitter
    int internal_frontface_idx;
 
    int ps30_input_count;
+   int vs30_output_count;
+
+   int dynamic_branching_level;
+
+   unsigned num_output_writes;
+   boolean constant_color_output;
 
    boolean in_main_func;
 
-   boolean created_zero_immediate;
-   int zero_immediate_idx;
+   boolean created_common_immediate;
+   int common_immediate_idx[2];
 
    boolean created_loop_const;
    int loop_const_idx;
 
-   boolean created_sincos_consts;
-   int sincos_consts_idx;
+   unsigned inverted_texcoords;  /**< bitmask of which texcoords are flipped */
+   struct src_register ps_true_texcoord[PIPE_MAX_ATTRIBS];
+   struct src_register ps_inverted_texcoord[PIPE_MAX_ATTRIBS];
+   unsigned ps_inverted_texcoord_input[PIPE_MAX_ATTRIBS];
 
    unsigned label[32];
    unsigned nr_labels;
 
+   /** input/output register mappings, indexed by register number */
    struct src_register input_map[PIPE_MAX_ATTRIBS];
    SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];
 
+   boolean ps_reads_pos;
+   boolean emitted_depth_fog;
+   struct src_register ps_true_pos;
+   struct src_register ps_depth_pos;
+   SVGA3dShaderDestToken ps_temp_pos;
+
+   /* shared input for depth and fog */
+   struct src_register ps_depth_fog;
+
    struct src_register imm_0055;
    SVGA3dShaderDestToken temp_pos;
    SVGA3dShaderDestToken true_pos;
+   SVGA3dShaderDestToken depth_pos;
 
-   SVGA3dShaderDestToken temp_col[PIPE_MAX_COLOR_BUFS];
-   SVGA3dShaderDestToken true_col[PIPE_MAX_COLOR_BUFS];
+   /* shared output for depth and fog */
+   SVGA3dShaderDestToken vs_depth_fog;
+
+   /* PS output colors (indexed by color semantic index) */
+   SVGA3dShaderDestToken temp_color_output[PIPE_MAX_COLOR_BUFS];
+   SVGA3dShaderDestToken true_color_output[PIPE_MAX_COLOR_BUFS];
 
    SVGA3dShaderDestToken temp_psiz;
    SVGA3dShaderDestToken true_psiz;
@@ -109,94 +134,35 @@ struct svga_shader_emitter
    struct svga_arl_consts arl_consts[12];
    int num_arl_consts;
    int current_arl;
-};
 
+   unsigned pstipple_sampler_unit;
 
-boolean svga_shader_emit_dword( struct svga_shader_emitter *emit,
-                                unsigned dword );
-
-boolean svga_shader_emit_dwords( struct svga_shader_emitter *emit,
-                                 const unsigned *dwords,
-                                 unsigned nr );
-
-boolean svga_shader_emit_opcode( struct svga_shader_emitter *emit,
-                                 unsigned opcode );
-
-boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
-                                       const struct tgsi_token *tokens );
-
-boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
-                               const struct tgsi_full_declaration *decl );
-
-boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
-                               const struct tgsi_full_declaration *decl );
-
-
-static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
-                         SVGA3dShaderDestToken dest )
-{
-   assert(dest.reserved0);
-   return svga_shader_emit_dword( emit, dest.value );
-}
+   int num_samplers;
+   uint8_t sampler_target[PIPE_MAX_SAMPLERS];
+};
 
-static INLINE boolean emit_src( struct svga_shader_emitter *emit,
-                         const struct src_register src )
-{
-   if (src.base.relAddr) {
-      assert(src.base.reserved0);
-      assert(src.indirect.reserved0);
-      return (svga_shader_emit_dword( emit, src.base.value ) &&
-              svga_shader_emit_dword( emit, src.indirect.value ));
-   }
-   else {
-      assert(src.base.reserved0);
-      return svga_shader_emit_dword( emit, src.base.value );
-   }
-}
 
+boolean
+svga_shader_emit_dword(struct svga_shader_emitter *emit, unsigned dword);
 
-static INLINE boolean emit_instruction( struct svga_shader_emitter *emit,
-                                 SVGA3dShaderInstToken opcode )
-{
-   return svga_shader_emit_opcode( emit, opcode.value );
-}
+boolean
+svga_shader_emit_dwords(struct svga_shader_emitter *emit,
+                        const unsigned *dwords, unsigned nr);
 
+boolean
+svga_shader_emit_opcode(struct svga_shader_emitter *emit,
+                        unsigned opcode);
 
-static INLINE boolean emit_op1( struct svga_shader_emitter *emit,
-                         SVGA3dShaderInstToken inst,
-                         SVGA3dShaderDestToken dest,
-                         struct src_register src0 )
-{
-   return (emit_instruction( emit, inst ) &&
-           emit_dst( emit, dest ) &&
-           emit_src( emit, src0 ));
-}
+boolean
+svga_shader_emit_instructions(struct svga_shader_emitter *emit,
+                              const struct tgsi_token *tokens);
 
-static INLINE boolean emit_op2( struct svga_shader_emitter *emit,
-                     SVGA3dShaderInstToken inst,
-                     SVGA3dShaderDestToken dest,
-                     struct src_register src0,
-                     struct src_register src1 )
-{
-   return (emit_instruction( emit, inst ) &&
-           emit_dst( emit, dest ) &&
-           emit_src( emit, src0 ) &&
-           emit_src( emit, src1 ));
-}
+boolean
+svga_shader_emit_samplers_decl(struct svga_shader_emitter *emit);
 
-static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
-                         SVGA3dShaderInstToken inst,
-                         SVGA3dShaderDestToken dest,
-                         struct src_register src0,
-                         struct src_register src1,
-                         struct src_register src2 )
-{
-   return (emit_instruction( emit, inst ) &&
-           emit_dst( emit, dest ) &&
-           emit_src( emit, src0 ) &&
-           emit_src( emit, src1 ) &&
-           emit_src( emit, src2 ));
-}
+boolean
+svga_translate_decl_sm30(struct svga_shader_emitter *emit,
+                         const struct tgsi_full_declaration *decl);
 
 
 #define TRANSLATE_SWIZZLE(x,y,z,w)  ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
@@ -212,9 +178,18 @@ static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W)
 
 
+/** Emit the given SVGA3dShaderInstToken opcode */
+static inline boolean
+emit_instruction(struct svga_shader_emitter *emit,
+                 SVGA3dShaderInstToken opcode)
+{
+   return svga_shader_emit_opcode(emit, opcode.value);
+}
 
-static INLINE SVGA3dShaderInstToken
-inst_token( unsigned opcode )
+
+/** Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode */
+static inline SVGA3dShaderInstToken
+inst_token(SVGA3dShaderOpCodeType opcode)
 {
    SVGA3dShaderInstToken inst;
 
@@ -224,12 +199,55 @@ inst_token( unsigned opcode )
    return inst;
 }
 
-static INLINE SVGA3dShaderDestToken 
-dst_register( unsigned file,
-              int number )
+
+/**
+ * Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode
+ * with the predication flag set.
+ */
+static inline SVGA3dShaderInstToken
+inst_token_predicated(SVGA3dShaderOpCodeType opcode)
+{
+   SVGA3dShaderInstToken inst;
+
+   inst.value = 0;
+   inst.op = opcode;
+   inst.predicated = 1;
+
+   return inst;
+}
+
+
+/**
+ * Generate a SVGA3dShaderInstToken for a SETP instruction (set predicate)
+ * using the given comparison operator (one of SVGA3DOPCOMP_xx).
+ */
+static inline SVGA3dShaderInstToken
+inst_token_setp(SVGA3dShaderOpCodeCompFnType operator)
+{
+   SVGA3dShaderInstToken inst;
+
+   inst.value = 0;
+   inst.op = SVGA3DOP_SETP;
+   inst.control = operator;
+
+   return inst;
+}
+
+
+/**
+ * Create an instance of a SVGA3dShaderDestToken.
+ * Note that this function is used to create tokens for output registers,
+ * temp registers AND constants (see emit_def_const()).
+ */
+static inline SVGA3dShaderDestToken
+dst_register(SVGA3dShaderRegType file, int number)
 {
    SVGA3dShaderDestToken dest;
 
+   /* check values against bitfield sizes */
+   assert(number < (1 << 11));
+   assert(file <= SVGA3DREG_PREDICATE);
+
    dest.value = 0;
    dest.num = number;
    dest.type_upper = file >> 3;
@@ -240,24 +258,34 @@ dst_register( unsigned file,
    dest.shfScale = 0;
    dest.type_lower = file & 0x7;
    dest.reserved0 = 1;          /* is_reg */
-   
+
    return dest;
 }
 
-static INLINE SVGA3dShaderDestToken
-writemask( SVGA3dShaderDestToken dest,
-           unsigned mask )
+
+/**
+ * Apply a writemask to the given SVGA3dShaderDestToken, returning a
+ * new SVGA3dShaderDestToken.
+ */
+static inline SVGA3dShaderDestToken
+writemask(SVGA3dShaderDestToken dest, unsigned mask)
 {
+   assert(dest.mask & mask);
    dest.mask &= mask;
    return dest;
 }
 
 
-static INLINE SVGA3dShaderSrcToken 
-src_token( unsigned file, int number )
+/** Create a SVGA3dShaderSrcToken given a register file and number */
+static inline SVGA3dShaderSrcToken
+src_token(SVGA3dShaderRegType file, int number)
 {
    SVGA3dShaderSrcToken src;
 
+   /* check values against bitfield sizes */
+   assert(number < (1 << 11));
+   assert(file <= SVGA3DREG_PREDICATE);
+
    src.value = 0;
    src.num = number;
    src.type_upper = file >> 3;
@@ -272,74 +300,31 @@ src_token( unsigned file, int number )
 }
 
 
-static INLINE struct src_register 
-absolute( struct src_register src )
-{
-   src.base.srcMod = SVGA3DSRCMOD_ABS;
-
-   return src;
-}
-
-
-static INLINE struct src_register 
-negate( struct src_register src )
-{
-   switch (src.base.srcMod) {
-   case SVGA3DSRCMOD_ABS:
-      src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
-      break;
-   case SVGA3DSRCMOD_ABSNEG:
-      src.base.srcMod = SVGA3DSRCMOD_ABS;
-      break;
-   case SVGA3DSRCMOD_NEG:
-      src.base.srcMod = SVGA3DSRCMOD_NONE;
-      break;
-   case SVGA3DSRCMOD_NONE:
-      src.base.srcMod = SVGA3DSRCMOD_NEG;
-      break;
-   }
-   return src;
-}
-
-
-static INLINE struct src_register 
-src_register( unsigned file, int number )
+/** Create a src_register given a register file and register number */
+static inline struct src_register
+src_register(SVGA3dShaderRegType file, int number)
 {
    struct src_register src;
-   
-   src.base = src_token( file, number );
+
+   src.base = src_token(file, number);
    src.indirect.value = 0;
 
    return src;
 }
 
-static INLINE SVGA3dShaderDestToken dst( struct src_register src )
+/** Translate src_register into SVGA3dShaderDestToken */
+static inline SVGA3dShaderDestToken
+dst(struct src_register src)
 {
-   return dst_register( SVGA3dShaderGetRegType( src.base.value ),
-                        src.base.num );
+   return dst_register(SVGA3dShaderGetRegType(src.base.value), src.base.num);
 }
 
-static INLINE struct src_register src( SVGA3dShaderDestToken dst )
-{
-   return src_register( SVGA3dShaderGetRegType( dst.value ),
-                        dst.num );
-}
 
-static INLINE ubyte svga_tgsi_sampler_type( struct svga_shader_emitter *emit,
-                                            int idx )
+/** Translate SVGA3dShaderDestToken to a src_register */
+static inline struct src_register
+src(SVGA3dShaderDestToken dst)
 {
-   switch (emit->key.fkey.tex[idx].texture_target) {
-   case PIPE_TEXTURE_1D:
-      return SVGA3DSAMP_2D;
-   case PIPE_TEXTURE_2D:
-      return SVGA3DSAMP_2D;
-   case PIPE_TEXTURE_3D:
-      return SVGA3DSAMP_VOLUME;
-   case PIPE_TEXTURE_CUBE:
-      return SVGA3DSAMP_CUBE;
-   }
-
-   return SVGA3DSAMP_UNKNOWN;
+   return src_register(SVGA3dShaderGetRegType(dst.value), dst.num);
 }
 
 #endif