Merge branch '7.8'
[mesa.git] / src / mesa / drivers / dri / r300 / compiler / radeon_program.h
index 561958608cab4170741ec65201306996cf3ef3d3..e31886769655a048a6003bc441dc97adec080164 100644 (file)
 #ifndef __RADEON_PROGRAM_H_
 #define __RADEON_PROGRAM_H_
 
-#include "main/glheader.h"
-#include "main/macros.h"
-#include "main/enums.h"
-#include "shader/program.h"
-#include "shader/prog_instruction.h"
+#include <stdint.h>
+#include <string.h>
+
+#include "radeon_opcodes.h"
+#include "radeon_code.h"
+#include "radeon_program_constants.h"
+#include "radeon_program_pair.h"
 
 struct radeon_compiler;
-struct rc_instruction;
-struct rc_program;
 
-enum {
-       PROGRAM_BUILTIN = PROGRAM_FILE_MAX /**< not a real register, but a special swizzle constant */
+struct rc_src_register {
+       unsigned int File:3;
+
+       /** Negative values may be used for relative addressing. */
+       signed int Index:(RC_REGISTER_INDEX_BITS+1);
+       unsigned int RelAddr:1;
+
+       unsigned int Swizzle:12;
+
+       /** Take the component-wise absolute value */
+       unsigned int Abs:1;
+
+       /** Post-Abs negation. */
+       unsigned int Negate:4;
+};
+
+struct rc_dst_register {
+       unsigned int File:3;
+
+       /** Negative values may be used for relative addressing. */
+       signed int Index:(RC_REGISTER_INDEX_BITS+1);
+       unsigned int RelAddr:1;
+
+       unsigned int WriteMask:4;
+};
+
+/**
+ * Instructions are maintained by the compiler in a doubly linked list
+ * of these structures.
+ *
+ * This instruction format is intended to be expanded for hardware-specific
+ * trickery. At different stages of compilation, a different set of
+ * instruction types may be valid.
+ */
+struct rc_sub_instruction {
+       struct rc_src_register SrcReg[3];
+       struct rc_dst_register DstReg;
+
+       /**
+        * Opcode of this instruction, according to \ref rc_opcode enums.
+        */
+       unsigned int Opcode:8;
+
+       /**
+        * Saturate each value of the result to the range [0,1] or [-1,1],
+        * according to \ref rc_saturate_mode enums.
+        */
+       unsigned int SaturateMode:2;
+
+       /**
+        * Writing to the special register RC_SPECIAL_ALU_RESULT
+        */
+       /*@{*/
+       unsigned int WriteALUResult:2;
+       unsigned int ALUResultCompare:3;
+       /*@}*/
+
+       /**
+        * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
+        */
+       /*@{*/
+       /** Source texture unit. */
+       unsigned int TexSrcUnit:5;
+
+       /** Source texture target, one of the \ref rc_texture_target enums */
+       unsigned int TexSrcTarget:3;
+
+       /** True if tex instruction should do shadow comparison */
+       unsigned int TexShadow:1;
+       /*@}*/
+};
+
+typedef enum {
+       RC_INSTRUCTION_NORMAL = 0,
+       RC_INSTRUCTION_PAIR
+} rc_instruction_type;
+
+struct rc_instruction {
+       struct rc_instruction * Prev;
+       struct rc_instruction * Next;
+
+       rc_instruction_type Type;
+       union {
+               struct rc_sub_instruction I;
+               struct rc_pair_instruction P;
+       } U;
+
+       /**
+        * Warning: IPs are not stable. If you want to use them,
+        * you need to recompute them at the beginning of each pass
+        * using \ref rc_recompute_ips
+        */
+       unsigned int IP;
+};
+
+struct rc_program {
+       /**
+        * Instructions.Next points to the first instruction,
+        * Instructions.Prev points to the last instruction.
+        */
+       struct rc_instruction Instructions;
+
+       /* Long term, we should probably remove InputsRead & OutputsWritten,
+        * since updating dependent state can be fragile, and they aren't
+        * actually used very often. */
+       uint32_t InputsRead;
+       uint32_t OutputsWritten;
+       uint32_t ShadowSamplers; /**< Texture units used for shadow sampling. */
+
+       struct rc_constant_list Constants;
 };
 
 enum {
-       OPCODE_REPL_ALPHA = MAX_OPCODE /**< used in paired instructions */
+       OPCODE_REPL_ALPHA = MAX_RC_OPCODE /**< used in paired instructions */
 };
 
-#define SWIZZLE_0000 MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO)
-#define SWIZZLE_1111 MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE)
 
-static inline GLuint get_swz(GLuint swz, GLuint idx)
+static inline rc_swizzle get_swz(unsigned int swz, rc_swizzle idx)
 {
        if (idx & 0x4)
                return idx;
        return GET_SWZ(swz, idx);
 }
 
-static inline GLuint combine_swizzles4(GLuint src, GLuint swz_x, GLuint swz_y, GLuint swz_z, GLuint swz_w)
+static inline unsigned int combine_swizzles4(unsigned int src,
+               rc_swizzle swz_x, rc_swizzle swz_y, rc_swizzle swz_z, rc_swizzle swz_w)
 {
-       GLuint ret = 0;
+       unsigned int ret = 0;
 
        ret |= get_swz(src, swz_x);
        ret |= get_swz(src, swz_y) << 3;
@@ -68,22 +175,24 @@ static inline GLuint combine_swizzles4(GLuint src, GLuint swz_x, GLuint swz_y, G
        return ret;
 }
 
-static inline GLuint combine_swizzles(GLuint src, GLuint swz)
+static inline unsigned int combine_swizzles(unsigned int src, unsigned int swz)
 {
-       GLuint ret = 0;
+       unsigned int ret = 0;
 
-       ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_X));
-       ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Y)) << 3;
-       ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Z)) << 6;
-       ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_W)) << 9;
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_X));
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Y)) << 3;
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Z)) << 6;
+       ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_W)) << 9;
 
        return ret;
 }
 
-static INLINE void reset_srcreg(struct prog_src_register* reg)
+struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg);
+
+static inline void reset_srcreg(struct rc_src_register* reg)
 {
-       _mesa_bzero(reg, sizeof(*reg));
-       reg->Swizzle = SWIZZLE_NOOP;
+       memset(reg, 0, sizeof(struct rc_src_register));
+       reg->Swizzle = RC_SWIZZLE_XYZW;
 }
 
 
@@ -92,13 +201,13 @@ static INLINE void reset_srcreg(struct prog_src_register* reg)
  *
  * The function will be called once for each instruction.
  * It has to either emit the appropriate transformed code for the instruction
- * and return GL_TRUE, or return GL_FALSE if it doesn't understand the
+ * and return true, or return false if it doesn't understand the
  * instruction.
  *
  * The function gets passed the userData as last parameter.
  */
 struct radeon_program_transformation {
-       GLboolean (*function)(
+       int (*function)(
                struct radeon_compiler*,
                struct rc_instruction*,
                void*);
@@ -110,12 +219,15 @@ void radeonLocalTransform(
        int num_transformations,
        struct radeon_program_transformation* transformations);
 
-GLint rc_find_free_temporary(struct radeon_compiler * c);
+unsigned int rc_find_free_temporary(struct radeon_compiler * c);
 
 struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
 struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after);
+void rc_insert_instruction(struct rc_instruction * after, struct rc_instruction * inst);
 void rc_remove_instruction(struct rc_instruction * inst);
 
+unsigned int rc_recompute_ips(struct radeon_compiler * c);
+
 void rc_print_program(const struct rc_program *prog);
 
 #endif