aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvfx/nvfx_shader.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nvfx/nvfx_shader.h')
-rw-r--r--src/gallium/drivers/nvfx/nvfx_shader.h194
1 files changed, 143 insertions, 51 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_shader.h b/src/gallium/drivers/nvfx/nvfx_shader.h
index 50830b39164..35006eec3d4 100644
--- a/src/gallium/drivers/nvfx/nvfx_shader.h
+++ b/src/gallium/drivers/nvfx/nvfx_shader.h
@@ -1,6 +1,12 @@
#ifndef __NVFX_SHADER_H__
#define __NVFX_SHADER_H__
+#include <stdint.h>
+
+#include "pipe/p_compiler.h"
+
+#define NVFX_SWZ_IDENTITY ((3 << 6) | (2 << 4) | (1 << 2) | (0 << 0))
+
/* this will resolve to either the NV30 or the NV40 version
* depending on the current hardware */
/* unusual, but very fast and compact method */
@@ -71,11 +77,58 @@
/*
* Each fragment program opcode appears to be comprised of 4 32-bit values.
*
- * 0 - Opcode, output reg/mask, ATTRIB source
- * 1 - Source 0
- * 2 - Source 1
- * 3 - Source 2
+ * 0: OPDEST
+ * 0: program end
+ * 1-6: destination register
+ * 7: destination register is fp16?? (use for outputs)
+ * 8: set condition code
+ * 9: writemask x
+ * 10: writemask y
+ * 11: writemask z
+ * 12: writemask w
+ * 13-16: source attribute register number (e.g. COL0)
+ * 17-20: texture unit number
+ * 21: expand value on texture operation (x -> 2x - 1)
+ * 22-23: precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = s0.8 fixed (nv40-only))
+ * 24-29: opcode
+ * 30: no destination
+ * 31: saturate
+ * 1 - SRC0
+ * 0-17: see common source fields
+ * 18: execute if condition code less
+ * 19: execute if condition code equal
+ * 20: execute if condition code greater
+ * 21-22: condition code swizzle x source component
+ * 23-24: condition code swizzle y source component
+ * 25-26: condition code swizzle z source component
+ * 27-28: condition code swizzle w source component
+ * 29: source 0 absolute
+ * 30: always 0 in renouveau tests
+ * 31: always 0 in renouveau tests
+ * 2 - SRC1
+ * 0-17: see common source fields
+ * 18: source 1 absolute
+ * 19-20: input precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = ???
+ * 21-27: always 0 in renouveau tests
+ * 28-30: scale (0 = 1x, 1 = 2x, 2 = 4x, 3 = 8x, 4 = ???, 5, = 1/2, 6 = 1/4, 7 = 1/8)
+ * 31: opcode is branch
+ * 3 - SRC2
+ * 0-17: see common source fields
+ * 18: source 2 absolute
+ * 19-29: address register displacement
+ * 30: use index register
+ * 31: disable perspective-correct interpolation?
*
+* Common fields of 0, 1, 2 - SRC
+ * 0-1: source register type (0 = temp, 1 = input, 2 = immediate, 3 = ???)
+ * 2-7: source temp register index
+ * 8: source register is fp16??
+ * 9-10: source swizzle x source component
+ * 11-12: source swizzle y source component
+ * 13-14: source swizzle z source component
+ * 15-16: source swizzle w source component
+ * 17: negate
+
* There appears to be no special difference between result regs and temp regs.
* result.color == R0.xyzw
* result.depth == R1.z
@@ -210,6 +263,7 @@
/* NV40 only fragment program opcodes */
#define NVFX_FP_OP_OPCODE_TXL_NV40 0x2F
+
/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
#define NV40_FP_OP_BRA_OPCODE_BRK 0x0
#define NV40_FP_OP_BRA_OPCODE_CAL 0x1
@@ -218,10 +272,11 @@
#define NV40_FP_OP_BRA_OPCODE_REP 0x4
#define NV40_FP_OP_BRA_OPCODE_RET 0x5
+#define NV40_FP_OP_OUT_NONE (1 << 30)
#define NVFX_FP_OP_OUT_SAT (1 << 31)
/* high order bits of SRC0 */
-#define NVFX_FP_OP_OUT_ABS (1 << 29)
+#define NVFX_FP_OP_SRC0_ABS (1 << 29)
#define NVFX_FP_OP_COND_SWZ_W_SHIFT 27
#define NVFX_FP_OP_COND_SWZ_W_MASK (3 << 27)
#define NVFX_FP_OP_COND_SWZ_Z_SHIFT 25
@@ -254,6 +309,7 @@
#define NVFX_FP_OP_DST_SCALE_INV_2X 5
#define NVFX_FP_OP_DST_SCALE_INV_4X 6
#define NVFX_FP_OP_DST_SCALE_INV_8X 7
+#define NVFX_FP_OP_SRC1_ABS (1 << 18)
/* SRC1 LOOP */
#define NV40_FP_OP_LOOP_INCR_SHIFT 19
@@ -263,13 +319,13 @@
#define NV40_FP_OP_LOOP_COUNT_SHIFT 2
#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
-/* SRC1 IF */
-#define NV40_FP_OP_ELSE_ID_SHIFT 2
-#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2)
+/* SRC1 IF: absolute offset in dwords */
+#define NV40_FP_OP_ELSE_OFFSET_SHIFT 0
+#define NV40_FP_OP_ELSE_OFFSET_MASK (0x7FFFFFFF << 0)
/* SRC1 CAL */
-#define NV40_FP_OP_IADDR_SHIFT 2
-#define NV40_FP_OP_IADDR_MASK (0xFF << 2)
+#define NV40_FP_OP_SUB_OFFSET_SHIFT 0
+#define NV40_FP_OP_SUB_OFFSET_MASK (0x7FFFFFFF << 0)
/* SRC1 REP
* I have no idea why there are 3 count values here.. but they
@@ -283,9 +339,9 @@
#define NV40_FP_OP_REP_COUNT3_SHIFT 19
#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
-/* SRC2 REP/IF */
-#define NV40_FP_OP_END_ID_SHIFT 2
-#define NV40_FP_OP_END_ID_MASK (0xFF << 2)
+/* SRC2 REP/IF: absolute offset in dwords */
+#define NV40_FP_OP_END_OFFSET_SHIFT 0
+#define NV40_FP_OP_END_OFFSET_MASK (0x7FFFFFFF << 0)
/* high order bits of SRC2 */
#define NVFX_FP_OP_INDEX_INPUT (1 << 30)
@@ -323,6 +379,7 @@
#define NVFXSR_INPUT 2
#define NVFXSR_TEMP 3
#define NVFXSR_CONST 4
+#define NVFXSR_RELOCATED 5
#define NVFX_COND_FL 0
#define NVFX_COND_LT 1
@@ -352,51 +409,88 @@
#define NVFX_SWZ_Z 2
#define NVFX_SWZ_W 3
-#define swz(s,x,y,z,w) nvfx_sr_swz((s), NVFX_SWZ_##x, NVFX_SWZ_##y, NVFX_SWZ_##z, NVFX_SWZ_##w)
-#define neg(s) nvfx_sr_neg((s))
-#define abs(s) nvfx_sr_abs((s))
-#define scale(s,v) nvfx_sr_scale((s), NVFX_FP_OP_DST_SCALE_##v)
+#define swz(s,x,y,z,w) nvfx_src_swz((s), NVFX_SWZ_##x, NVFX_SWZ_##y, NVFX_SWZ_##z, NVFX_SWZ_##w)
+#define neg(s) nvfx_src_neg((s))
+#define abs(s) nvfx_src_abs((s))
-struct nvfx_sreg {
- int type;
- int index;
+struct nvfx_reg {
+ uint8_t type;
+ uint32_t index;
+};
- int dst_scale;
+struct nvfx_src {
+ struct nvfx_reg reg;
- int negate;
- int abs;
- int swz[4];
+ /* src only */
+ uint8_t negate : 1;
+ uint8_t abs : 1;
+ uint8_t swz[4];
+};
- int cc_update;
- int cc_update_reg;
- int cc_test;
- int cc_test_reg;
- int cc_swz[4];
+struct nvfx_insn
+{
+ uint8_t op;
+ char scale;
+ int8_t unit;
+ uint8_t mask;
+ uint8_t cc_swz[4];
+
+ uint8_t sat : 1;
+ uint8_t cc_update : 1;
+ uint8_t cc_update_reg : 1;
+ uint8_t cc_test : 3;
+ uint8_t cc_test_reg : 1;
+
+ struct nvfx_reg dst;
+ struct nvfx_src src[3];
};
-static INLINE struct nvfx_sreg
-nvfx_sr(int type, int index)
+static INLINE struct nvfx_insn
+nvfx_insn(boolean sat, unsigned op, int unit, struct nvfx_reg dst, unsigned mask, struct nvfx_src s0, struct nvfx_src s1, struct nvfx_src s2)
{
- struct nvfx_sreg temp = {
- .type = type,
- .index = index,
- .dst_scale = 0,
- .abs = 0,
- .negate = 0,
- .swz = { 0, 1, 2, 3 },
+ struct nvfx_insn insn = {
+ .op = op,
+ .scale = 0,
+ .unit = unit,
+ .sat = sat,
+ .mask = mask,
.cc_update = 0,
.cc_update_reg = 0,
.cc_test = NVFX_COND_TR,
.cc_test_reg = 0,
.cc_swz = { 0, 1, 2, 3 },
+ .dst = dst,
+ .src = {s0, s1, s2}
+ };
+ return insn;
+}
+
+static INLINE struct nvfx_reg
+nvfx_reg(int type, int index)
+{
+ struct nvfx_reg temp = {
+ .type = type,
+ .index = index,
};
return temp;
}
-static INLINE struct nvfx_sreg
-nvfx_sr_swz(struct nvfx_sreg src, int x, int y, int z, int w)
+static INLINE struct nvfx_src
+nvfx_src(struct nvfx_reg reg)
{
- struct nvfx_sreg dst = src;
+ struct nvfx_src temp = {
+ .reg = reg,
+ .abs = 0,
+ .negate = 0,
+ .swz = { 0, 1, 2, 3 },
+ };
+ return temp;
+}
+
+static INLINE struct nvfx_src
+nvfx_src_swz(struct nvfx_src src, int x, int y, int z, int w)
+{
+ struct nvfx_src dst = src;
dst.swz[NVFX_SWZ_X] = src.swz[x];
dst.swz[NVFX_SWZ_Y] = src.swz[y];
@@ -405,25 +499,23 @@ nvfx_sr_swz(struct nvfx_sreg src, int x, int y, int z, int w)
return dst;
}
-static INLINE struct nvfx_sreg
-nvfx_sr_neg(struct nvfx_sreg src)
+static INLINE struct nvfx_src
+nvfx_src_neg(struct nvfx_src src)
{
src.negate = !src.negate;
return src;
}
-static INLINE struct nvfx_sreg
-nvfx_sr_abs(struct nvfx_sreg src)
+static INLINE struct nvfx_src
+nvfx_src_abs(struct nvfx_src src)
{
src.abs = 1;
return src;
}
-static INLINE struct nvfx_sreg
-nvfx_sr_scale(struct nvfx_sreg src, int scale)
-{
- src.dst_scale = scale;
- return src;
-}
+struct nvfx_relocation {
+ unsigned location;
+ unsigned target;
+};
#endif