mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 19:40:10 +01:00
i965: Split struct brw_reg out from brw_eu.h into its own header.
struct brw_instruction and the related instruction emitting code won't be useful on Gen8+, as the instruction encoding changed. However, the struct brw_reg code is still extremely valuable. While we're at it, fix up some style points: - s/GLuint/unsigned/g - s/GLint/int/g - s/GLshort/int16_t/g - s/GLushort/uint16_t/g - s/INLINE/inline/g - Replace tabs with spaces - Put return types on a separate line from the function name/parameters - Remove trailing whitespace - Remove extraneous whitespace around function parameters Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
e1ca88f098
commit
1db1283563
2 changed files with 778 additions and 709 deletions
|
|
@ -36,76 +36,13 @@
|
|||
#include <stdbool.h>
|
||||
#include "brw_structs.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_reg.h"
|
||||
#include "program/prog_instruction.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
|
||||
#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
|
||||
|
||||
#define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
|
||||
#define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
|
||||
#define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
|
||||
#define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
|
||||
#define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
|
||||
#define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
|
||||
#define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
|
||||
|
||||
static inline bool brw_is_single_value_swizzle(int swiz)
|
||||
{
|
||||
return (swiz == BRW_SWIZZLE_XXXX ||
|
||||
swiz == BRW_SWIZZLE_YYYY ||
|
||||
swiz == BRW_SWIZZLE_ZZZZ ||
|
||||
swiz == BRW_SWIZZLE_WWWW);
|
||||
}
|
||||
|
||||
#define REG_SIZE (8*4)
|
||||
|
||||
|
||||
/* These aren't hardware structs, just something useful for us to pass around:
|
||||
*
|
||||
* Align1 operation has a lot of control over input ranges. Used in
|
||||
* WM programs to implement shaders decomposed into "channel serial"
|
||||
* or "structure of array" form:
|
||||
*/
|
||||
struct brw_reg
|
||||
{
|
||||
GLuint type:4;
|
||||
GLuint file:2;
|
||||
GLuint nr:8;
|
||||
GLuint subnr:5; /* :1 in align16 */
|
||||
GLuint negate:1; /* source only */
|
||||
GLuint abs:1; /* source only */
|
||||
GLuint vstride:4; /* source only */
|
||||
GLuint width:3; /* src only, align1 only */
|
||||
GLuint hstride:2; /* align1 only */
|
||||
GLuint address_mode:1; /* relative addressing, hopefully! */
|
||||
GLuint pad0:1;
|
||||
|
||||
union {
|
||||
struct {
|
||||
GLuint swizzle:8; /* src only, align16 only */
|
||||
GLuint writemask:4; /* dest only, align16 only */
|
||||
GLint indirect_offset:10; /* relative addressing offset */
|
||||
GLuint pad1:10; /* two dwords total */
|
||||
} bits;
|
||||
|
||||
GLfloat f;
|
||||
GLint d;
|
||||
GLuint ud;
|
||||
} dw1;
|
||||
};
|
||||
|
||||
|
||||
struct brw_indirect {
|
||||
GLuint addr_subnr:4;
|
||||
GLint addr_offset:10;
|
||||
GLuint pad:18;
|
||||
};
|
||||
|
||||
|
||||
#define BRW_EU_MAX_INSN_STACK 5
|
||||
|
||||
struct brw_compile {
|
||||
|
|
@ -153,648 +90,6 @@ struct brw_compile {
|
|||
int loop_stack_array_size;
|
||||
};
|
||||
|
||||
static INLINE int type_sz( GLuint type )
|
||||
{
|
||||
switch( type ) {
|
||||
case BRW_REGISTER_TYPE_UD:
|
||||
case BRW_REGISTER_TYPE_D:
|
||||
case BRW_REGISTER_TYPE_F:
|
||||
return 4;
|
||||
case BRW_REGISTER_TYPE_HF:
|
||||
case BRW_REGISTER_TYPE_UW:
|
||||
case BRW_REGISTER_TYPE_W:
|
||||
return 2;
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a brw_reg.
|
||||
* \param file one of the BRW_x_REGISTER_FILE values
|
||||
* \param nr register number/index
|
||||
* \param subnr register sub number
|
||||
* \param type one of BRW_REGISTER_TYPE_x
|
||||
* \param vstride one of BRW_VERTICAL_STRIDE_x
|
||||
* \param width one of BRW_WIDTH_x
|
||||
* \param hstride one of BRW_HORIZONTAL_STRIDE_x
|
||||
* \param swizzle one of BRW_SWIZZLE_x
|
||||
* \param writemask WRITEMASK_X/Y/Z/W bitfield
|
||||
*/
|
||||
static INLINE struct brw_reg brw_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr,
|
||||
GLuint type,
|
||||
GLuint vstride,
|
||||
GLuint width,
|
||||
GLuint hstride,
|
||||
GLuint swizzle,
|
||||
GLuint writemask )
|
||||
{
|
||||
struct brw_reg reg;
|
||||
if (file == BRW_GENERAL_REGISTER_FILE)
|
||||
assert(nr < BRW_MAX_GRF);
|
||||
else if (file == BRW_MESSAGE_REGISTER_FILE)
|
||||
assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
|
||||
else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
|
||||
assert(nr <= BRW_ARF_TIMESTAMP);
|
||||
|
||||
reg.type = type;
|
||||
reg.file = file;
|
||||
reg.nr = nr;
|
||||
reg.subnr = subnr * type_sz(type);
|
||||
reg.negate = 0;
|
||||
reg.abs = 0;
|
||||
reg.vstride = vstride;
|
||||
reg.width = width;
|
||||
reg.hstride = hstride;
|
||||
reg.address_mode = BRW_ADDRESS_DIRECT;
|
||||
reg.pad0 = 0;
|
||||
|
||||
/* Could do better: If the reg is r5.3<0;1,0>, we probably want to
|
||||
* set swizzle and writemask to W, as the lower bits of subnr will
|
||||
* be lost when converted to align16. This is probably too much to
|
||||
* keep track of as you'd want it adjusted by suboffset(), etc.
|
||||
* Perhaps fix up when converting to align16?
|
||||
*/
|
||||
reg.dw1.bits.swizzle = swizzle;
|
||||
reg.dw1.bits.writemask = writemask;
|
||||
reg.dw1.bits.indirect_offset = 0;
|
||||
reg.dw1.bits.pad1 = 0;
|
||||
return reg;
|
||||
}
|
||||
|
||||
/** Construct float[16] register */
|
||||
static INLINE struct brw_reg brw_vec16_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_16,
|
||||
BRW_WIDTH_16,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
/** Construct float[8] register */
|
||||
static INLINE struct brw_reg brw_vec8_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_8,
|
||||
BRW_WIDTH_8,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
/** Construct float[4] register */
|
||||
static INLINE struct brw_reg brw_vec4_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_4,
|
||||
BRW_WIDTH_4,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
/** Construct float[2] register */
|
||||
static INLINE struct brw_reg brw_vec2_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_2,
|
||||
BRW_WIDTH_2,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYXY,
|
||||
WRITEMASK_XY);
|
||||
}
|
||||
|
||||
/** Construct float[1] register */
|
||||
static INLINE struct brw_reg brw_vec1_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XXXX,
|
||||
WRITEMASK_X);
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg retype( struct brw_reg reg,
|
||||
GLuint type )
|
||||
{
|
||||
reg.type = type;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
sechalf(struct brw_reg reg)
|
||||
{
|
||||
if (reg.vstride)
|
||||
reg.nr++;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg suboffset( struct brw_reg reg,
|
||||
GLuint delta )
|
||||
{
|
||||
reg.subnr += delta * type_sz(reg.type);
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg offset( struct brw_reg reg,
|
||||
GLuint delta )
|
||||
{
|
||||
reg.nr += delta;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg byte_offset( struct brw_reg reg,
|
||||
GLuint bytes )
|
||||
{
|
||||
GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
|
||||
reg.nr = newoffset / REG_SIZE;
|
||||
reg.subnr = newoffset % REG_SIZE;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
/** Construct unsigned word[16] register */
|
||||
static INLINE struct brw_reg brw_uw16_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
/** Construct unsigned word[8] register */
|
||||
static INLINE struct brw_reg brw_uw8_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
/** Construct unsigned word[1] register */
|
||||
static INLINE struct brw_reg brw_uw1_reg( GLuint file,
|
||||
GLuint nr,
|
||||
GLuint subnr )
|
||||
{
|
||||
return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_imm_reg( GLuint type )
|
||||
{
|
||||
return brw_reg( BRW_IMMEDIATE_VALUE,
|
||||
0,
|
||||
0,
|
||||
type,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
/** Construct float immediate register */
|
||||
static INLINE struct brw_reg brw_imm_f( GLfloat f )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
|
||||
imm.dw1.f = f;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct integer immediate register */
|
||||
static INLINE struct brw_reg brw_imm_d( GLint d )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
|
||||
imm.dw1.d = d;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct uint immediate register */
|
||||
static INLINE struct brw_reg brw_imm_ud( GLuint ud )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
|
||||
imm.dw1.ud = ud;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct ushort immediate register */
|
||||
static INLINE struct brw_reg brw_imm_uw( GLushort uw )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
|
||||
imm.dw1.ud = uw | (uw << 16);
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct short immediate register */
|
||||
static INLINE struct brw_reg brw_imm_w( GLshort w )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
|
||||
imm.dw1.d = w | (w << 16);
|
||||
return imm;
|
||||
}
|
||||
|
||||
/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
|
||||
* numbers alias with _V and _VF below:
|
||||
*/
|
||||
|
||||
/** Construct vector of eight signed half-byte values */
|
||||
static INLINE struct brw_reg brw_imm_v( GLuint v )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_8;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = v;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct vector of four 8-bit float values */
|
||||
static INLINE struct brw_reg brw_imm_vf( GLuint v )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_4;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = v;
|
||||
return imm;
|
||||
}
|
||||
|
||||
#define VF_ZERO 0x0
|
||||
#define VF_ONE 0x30
|
||||
#define VF_NEG (1<<7)
|
||||
|
||||
static INLINE struct brw_reg brw_imm_vf4( GLuint v0,
|
||||
GLuint v1,
|
||||
GLuint v2,
|
||||
GLuint v3)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_4;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = ((v0 << 0) |
|
||||
(v1 << 8) |
|
||||
(v2 << 16) |
|
||||
(v3 << 24));
|
||||
return imm;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg brw_address( struct brw_reg reg )
|
||||
{
|
||||
return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
|
||||
}
|
||||
|
||||
/** Construct float[1] general-purpose register */
|
||||
static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
|
||||
{
|
||||
return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
/** Construct float[2] general-purpose register */
|
||||
static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
|
||||
{
|
||||
return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
/** Construct float[4] general-purpose register */
|
||||
static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
|
||||
{
|
||||
return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
/** Construct float[8] general-purpose register */
|
||||
static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
|
||||
{
|
||||
return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
|
||||
{
|
||||
return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
|
||||
{
|
||||
return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
|
||||
/** Construct null register (usually used for setting condition codes) */
|
||||
static INLINE struct brw_reg brw_null_reg( void )
|
||||
{
|
||||
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_address_reg( GLuint subnr )
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_ADDRESS,
|
||||
subnr);
|
||||
}
|
||||
|
||||
/* If/else instructions break in align16 mode if writemask & swizzle
|
||||
* aren't xyzw. This goes against the convention for other scalar
|
||||
* regs:
|
||||
*/
|
||||
static INLINE struct brw_reg brw_ip_reg( void )
|
||||
{
|
||||
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_IP,
|
||||
0,
|
||||
BRW_REGISTER_TYPE_UD,
|
||||
BRW_VERTICAL_STRIDE_4, /* ? */
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XYZW, /* NOTE! */
|
||||
WRITEMASK_XYZW); /* NOTE! */
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_acc_reg( void )
|
||||
{
|
||||
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_ACCUMULATOR,
|
||||
0);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_notification_1_reg(void)
|
||||
{
|
||||
|
||||
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_NOTIFICATION_COUNT,
|
||||
1,
|
||||
BRW_REGISTER_TYPE_UD,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XXXX,
|
||||
WRITEMASK_X);
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg brw_flag_reg(int reg, int subreg)
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_FLAG + reg,
|
||||
subreg);
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_MASK,
|
||||
subnr);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_message_reg( GLuint nr )
|
||||
{
|
||||
assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
|
||||
return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
|
||||
nr,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* This is almost always called with a numeric constant argument, so
|
||||
* make things easy to evaluate at compile time:
|
||||
*/
|
||||
static INLINE GLuint cvt( GLuint val )
|
||||
{
|
||||
switch (val) {
|
||||
case 0: return 0;
|
||||
case 1: return 1;
|
||||
case 2: return 2;
|
||||
case 4: return 3;
|
||||
case 8: return 4;
|
||||
case 16: return 5;
|
||||
case 32: return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg stride( struct brw_reg reg,
|
||||
GLuint vstride,
|
||||
GLuint width,
|
||||
GLuint hstride )
|
||||
{
|
||||
reg.vstride = cvt(vstride);
|
||||
reg.width = cvt(width) - 1;
|
||||
reg.hstride = cvt(hstride);
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg vec16( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 16,16,1);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg vec8( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 8,8,1);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg vec4( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 4,4,1);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg vec2( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 2,2,1);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg vec1( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 0,1,0);
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
|
||||
{
|
||||
return vec1(suboffset(reg, elt));
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
|
||||
{
|
||||
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg get_element_d( struct brw_reg reg, GLuint elt )
|
||||
{
|
||||
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
|
||||
GLuint x,
|
||||
GLuint y,
|
||||
GLuint z,
|
||||
GLuint w)
|
||||
{
|
||||
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
||||
|
||||
reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
|
||||
GLuint x )
|
||||
{
|
||||
return brw_swizzle(reg, x, x, x, x);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
|
||||
GLuint mask )
|
||||
{
|
||||
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
||||
reg.dw1.bits.writemask &= mask;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
|
||||
GLuint mask )
|
||||
{
|
||||
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
||||
reg.dw1.bits.writemask = mask;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg negate( struct brw_reg reg )
|
||||
{
|
||||
reg.negate ^= 1;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_abs( struct brw_reg reg )
|
||||
{
|
||||
reg.abs = 1;
|
||||
reg.negate = 0;
|
||||
return reg;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
|
||||
GLint offset )
|
||||
{
|
||||
struct brw_reg reg = brw_vec4_grf(0, 0);
|
||||
reg.subnr = subnr;
|
||||
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
|
||||
reg.dw1.bits.indirect_offset = offset;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
|
||||
GLint offset )
|
||||
{
|
||||
struct brw_reg reg = brw_vec1_grf(0, 0);
|
||||
reg.subnr = subnr;
|
||||
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
|
||||
reg.dw1.bits.indirect_offset = offset;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
|
||||
{
|
||||
return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
|
||||
{
|
||||
return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
|
||||
{
|
||||
return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
|
||||
}
|
||||
|
||||
static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
|
||||
{
|
||||
return brw_address_reg(ptr.addr_subnr);
|
||||
}
|
||||
|
||||
static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
|
||||
{
|
||||
ptr.addr_offset += offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
|
||||
{
|
||||
struct brw_indirect ptr;
|
||||
ptr.addr_subnr = addr_subnr;
|
||||
ptr.addr_offset = offset;
|
||||
ptr.pad = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/** Do two brw_regs refer to the same register? */
|
||||
static INLINE bool
|
||||
brw_same_reg(struct brw_reg r1, struct brw_reg r2)
|
||||
{
|
||||
return r1.file == r2.file && r1.nr == r2.nr;
|
||||
}
|
||||
|
||||
static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
|
||||
{
|
||||
return &p->store[p->nr_insn];
|
||||
|
|
@ -1052,9 +347,6 @@ void brw_CMP(struct brw_compile *p,
|
|||
struct brw_reg src0,
|
||||
struct brw_reg src1);
|
||||
|
||||
void brw_print_reg( struct brw_reg reg );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* brw_eu_util.c:
|
||||
*/
|
||||
|
|
|
|||
777
src/mesa/drivers/dri/i965/brw_reg.h
Normal file
777
src/mesa/drivers/dri/i965/brw_reg.h
Normal file
|
|
@ -0,0 +1,777 @@
|
|||
/*
|
||||
Copyright (C) Intel Corp. 2006. All Rights Reserved.
|
||||
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
|
||||
develop this 3D driver.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
/** @file brw_reg.h
|
||||
*
|
||||
* This file defines struct brw_reg, which is our representation for EU
|
||||
* registers. They're not a hardware specific format, just an abstraction
|
||||
* that intends to capture the full flexibility of the hardware registers.
|
||||
*
|
||||
* The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
|
||||
* the abstract brw_reg type into the actual hardware instruction encoding.
|
||||
*/
|
||||
|
||||
#ifndef BRW_REG_H
|
||||
#define BRW_REG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "program/prog_instruction.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
|
||||
#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
|
||||
|
||||
#define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
|
||||
#define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
|
||||
#define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
|
||||
#define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
|
||||
#define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
|
||||
#define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
|
||||
#define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
|
||||
|
||||
static inline bool
|
||||
brw_is_single_value_swizzle(int swiz)
|
||||
{
|
||||
return (swiz == BRW_SWIZZLE_XXXX ||
|
||||
swiz == BRW_SWIZZLE_YYYY ||
|
||||
swiz == BRW_SWIZZLE_ZZZZ ||
|
||||
swiz == BRW_SWIZZLE_WWWW);
|
||||
}
|
||||
|
||||
#define REG_SIZE (8*4)
|
||||
|
||||
/* These aren't hardware structs, just something useful for us to pass around:
|
||||
*
|
||||
* Align1 operation has a lot of control over input ranges. Used in
|
||||
* WM programs to implement shaders decomposed into "channel serial"
|
||||
* or "structure of array" form:
|
||||
*/
|
||||
struct brw_reg {
|
||||
unsigned type:4;
|
||||
unsigned file:2;
|
||||
unsigned nr:8;
|
||||
unsigned subnr:5; /* :1 in align16 */
|
||||
unsigned negate:1; /* source only */
|
||||
unsigned abs:1; /* source only */
|
||||
unsigned vstride:4; /* source only */
|
||||
unsigned width:3; /* src only, align1 only */
|
||||
unsigned hstride:2; /* align1 only */
|
||||
unsigned address_mode:1; /* relative addressing, hopefully! */
|
||||
unsigned pad0:1;
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned swizzle:8; /* src only, align16 only */
|
||||
unsigned writemask:4; /* dest only, align16 only */
|
||||
int indirect_offset:10; /* relative addressing offset */
|
||||
unsigned pad1:10; /* two dwords total */
|
||||
} bits;
|
||||
|
||||
float f;
|
||||
int d;
|
||||
unsigned ud;
|
||||
} dw1;
|
||||
};
|
||||
|
||||
|
||||
struct brw_indirect {
|
||||
unsigned addr_subnr:4;
|
||||
int addr_offset:10;
|
||||
unsigned pad:18;
|
||||
};
|
||||
|
||||
|
||||
static inline int
|
||||
type_sz(unsigned type)
|
||||
{
|
||||
switch(type) {
|
||||
case BRW_REGISTER_TYPE_UD:
|
||||
case BRW_REGISTER_TYPE_D:
|
||||
case BRW_REGISTER_TYPE_F:
|
||||
return 4;
|
||||
case BRW_REGISTER_TYPE_HF:
|
||||
case BRW_REGISTER_TYPE_UW:
|
||||
case BRW_REGISTER_TYPE_W:
|
||||
return 2;
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a brw_reg.
|
||||
* \param file one of the BRW_x_REGISTER_FILE values
|
||||
* \param nr register number/index
|
||||
* \param subnr register sub number
|
||||
* \param type one of BRW_REGISTER_TYPE_x
|
||||
* \param vstride one of BRW_VERTICAL_STRIDE_x
|
||||
* \param width one of BRW_WIDTH_x
|
||||
* \param hstride one of BRW_HORIZONTAL_STRIDE_x
|
||||
* \param swizzle one of BRW_SWIZZLE_x
|
||||
* \param writemask WRITEMASK_X/Y/Z/W bitfield
|
||||
*/
|
||||
static inline struct brw_reg
|
||||
brw_reg(unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr,
|
||||
unsigned type,
|
||||
unsigned vstride,
|
||||
unsigned width,
|
||||
unsigned hstride,
|
||||
unsigned swizzle,
|
||||
unsigned writemask)
|
||||
{
|
||||
struct brw_reg reg;
|
||||
if (file == BRW_GENERAL_REGISTER_FILE)
|
||||
assert(nr < BRW_MAX_GRF);
|
||||
else if (file == BRW_MESSAGE_REGISTER_FILE)
|
||||
assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
|
||||
else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
|
||||
assert(nr <= BRW_ARF_TIMESTAMP);
|
||||
|
||||
reg.type = type;
|
||||
reg.file = file;
|
||||
reg.nr = nr;
|
||||
reg.subnr = subnr * type_sz(type);
|
||||
reg.negate = 0;
|
||||
reg.abs = 0;
|
||||
reg.vstride = vstride;
|
||||
reg.width = width;
|
||||
reg.hstride = hstride;
|
||||
reg.address_mode = BRW_ADDRESS_DIRECT;
|
||||
reg.pad0 = 0;
|
||||
|
||||
/* Could do better: If the reg is r5.3<0;1,0>, we probably want to
|
||||
* set swizzle and writemask to W, as the lower bits of subnr will
|
||||
* be lost when converted to align16. This is probably too much to
|
||||
* keep track of as you'd want it adjusted by suboffset(), etc.
|
||||
* Perhaps fix up when converting to align16?
|
||||
*/
|
||||
reg.dw1.bits.swizzle = swizzle;
|
||||
reg.dw1.bits.writemask = writemask;
|
||||
reg.dw1.bits.indirect_offset = 0;
|
||||
reg.dw1.bits.pad1 = 0;
|
||||
return reg;
|
||||
}
|
||||
|
||||
/** Construct float[16] register */
|
||||
static inline struct brw_reg
|
||||
brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_16,
|
||||
BRW_WIDTH_16,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
/** Construct float[8] register */
|
||||
static inline struct brw_reg
|
||||
brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_8,
|
||||
BRW_WIDTH_8,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
/** Construct float[4] register */
|
||||
static inline struct brw_reg
|
||||
brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_4,
|
||||
BRW_WIDTH_4,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
/** Construct float[2] register */
|
||||
static inline struct brw_reg
|
||||
brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_2,
|
||||
BRW_WIDTH_2,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYXY,
|
||||
WRITEMASK_XY);
|
||||
}
|
||||
|
||||
/** Construct float[1] register */
|
||||
static inline struct brw_reg
|
||||
brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XXXX,
|
||||
WRITEMASK_X);
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
retype(struct brw_reg reg, unsigned type)
|
||||
{
|
||||
reg.type = type;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
sechalf(struct brw_reg reg)
|
||||
{
|
||||
if (reg.vstride)
|
||||
reg.nr++;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
suboffset(struct brw_reg reg, unsigned delta)
|
||||
{
|
||||
reg.subnr += delta * type_sz(reg.type);
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
offset(struct brw_reg reg, unsigned delta)
|
||||
{
|
||||
reg.nr += delta;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
byte_offset(struct brw_reg reg, unsigned bytes)
|
||||
{
|
||||
unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
|
||||
reg.nr = newoffset / REG_SIZE;
|
||||
reg.subnr = newoffset % REG_SIZE;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
/** Construct unsigned word[16] register */
|
||||
static inline struct brw_reg
|
||||
brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
/** Construct unsigned word[8] register */
|
||||
static inline struct brw_reg
|
||||
brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
/** Construct unsigned word[1] register */
|
||||
static inline struct brw_reg
|
||||
brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
|
||||
{
|
||||
return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_imm_reg(unsigned type)
|
||||
{
|
||||
return brw_reg(BRW_IMMEDIATE_VALUE,
|
||||
0,
|
||||
0,
|
||||
type,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
/** Construct float immediate register */
|
||||
static inline struct brw_reg
|
||||
brw_imm_f(float f)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
|
||||
imm.dw1.f = f;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct integer immediate register */
|
||||
static inline struct brw_reg
|
||||
brw_imm_d(int d)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
|
||||
imm.dw1.d = d;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct uint immediate register */
|
||||
static inline struct brw_reg
|
||||
brw_imm_ud(unsigned ud)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
|
||||
imm.dw1.ud = ud;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct ushort immediate register */
|
||||
static inline struct brw_reg
|
||||
brw_imm_uw(uint16_t uw)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
|
||||
imm.dw1.ud = uw | (uw << 16);
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct short immediate register */
|
||||
static inline struct brw_reg
|
||||
brw_imm_w(int16_t w)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
|
||||
imm.dw1.d = w | (w << 16);
|
||||
return imm;
|
||||
}
|
||||
|
||||
/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
|
||||
* numbers alias with _V and _VF below:
|
||||
*/
|
||||
|
||||
/** Construct vector of eight signed half-byte values */
|
||||
static inline struct brw_reg
|
||||
brw_imm_v(unsigned v)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_8;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = v;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/** Construct vector of four 8-bit float values */
|
||||
static inline struct brw_reg
|
||||
brw_imm_vf(unsigned v)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_4;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = v;
|
||||
return imm;
|
||||
}
|
||||
|
||||
#define VF_ZERO 0x0
|
||||
#define VF_ONE 0x30
|
||||
#define VF_NEG (1<<7)
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_4;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
|
||||
return imm;
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_address(struct brw_reg reg)
|
||||
{
|
||||
return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
|
||||
}
|
||||
|
||||
/** Construct float[1] general-purpose register */
|
||||
static inline struct brw_reg
|
||||
brw_vec1_grf(unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
/** Construct float[2] general-purpose register */
|
||||
static inline struct brw_reg
|
||||
brw_vec2_grf(unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
/** Construct float[4] general-purpose register */
|
||||
static inline struct brw_reg
|
||||
brw_vec4_grf(unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
/** Construct float[8] general-purpose register */
|
||||
static inline struct brw_reg
|
||||
brw_vec8_grf(unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_uw8_grf(unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_uw16_grf(unsigned nr, unsigned subnr)
|
||||
{
|
||||
return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
|
||||
/** Construct null register (usually used for setting condition codes) */
|
||||
static inline struct brw_reg
|
||||
brw_null_reg(void)
|
||||
{
|
||||
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_address_reg(unsigned subnr)
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
|
||||
}
|
||||
|
||||
/* If/else instructions break in align16 mode if writemask & swizzle
|
||||
* aren't xyzw. This goes against the convention for other scalar
|
||||
* regs:
|
||||
*/
|
||||
static inline struct brw_reg
|
||||
brw_ip_reg(void)
|
||||
{
|
||||
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_IP,
|
||||
0,
|
||||
BRW_REGISTER_TYPE_UD,
|
||||
BRW_VERTICAL_STRIDE_4, /* ? */
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XYZW, /* NOTE! */
|
||||
WRITEMASK_XYZW); /* NOTE! */
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_acc_reg(void)
|
||||
{
|
||||
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_notification_1_reg(void)
|
||||
{
|
||||
|
||||
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_NOTIFICATION_COUNT,
|
||||
1,
|
||||
BRW_REGISTER_TYPE_UD,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XXXX,
|
||||
WRITEMASK_X);
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_flag_reg(int reg, int subreg)
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_FLAG + reg, subreg);
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_mask_reg(unsigned subnr)
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_message_reg(unsigned nr)
|
||||
{
|
||||
assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
|
||||
return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
|
||||
}
|
||||
|
||||
|
||||
/* This is almost always called with a numeric constant argument, so
|
||||
* make things easy to evaluate at compile time:
|
||||
*/
|
||||
static inline unsigned cvt(unsigned val)
|
||||
{
|
||||
switch (val) {
|
||||
case 0: return 0;
|
||||
case 1: return 1;
|
||||
case 2: return 2;
|
||||
case 4: return 3;
|
||||
case 8: return 4;
|
||||
case 16: return 5;
|
||||
case 32: return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
|
||||
{
|
||||
reg.vstride = cvt(vstride);
|
||||
reg.width = cvt(width) - 1;
|
||||
reg.hstride = cvt(hstride);
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
vec16(struct brw_reg reg)
|
||||
{
|
||||
return stride(reg, 16,16,1);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
vec8(struct brw_reg reg)
|
||||
{
|
||||
return stride(reg, 8,8,1);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
vec4(struct brw_reg reg)
|
||||
{
|
||||
return stride(reg, 4,4,1);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
vec2(struct brw_reg reg)
|
||||
{
|
||||
return stride(reg, 2,2,1);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
vec1(struct brw_reg reg)
|
||||
{
|
||||
return stride(reg, 0,1,0);
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
get_element(struct brw_reg reg, unsigned elt)
|
||||
{
|
||||
return vec1(suboffset(reg, elt));
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
get_element_ud(struct brw_reg reg, unsigned elt)
|
||||
{
|
||||
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
get_element_d(struct brw_reg reg, unsigned elt)
|
||||
{
|
||||
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
|
||||
{
|
||||
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
||||
|
||||
reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_swizzle1(struct brw_reg reg, unsigned x)
|
||||
{
|
||||
return brw_swizzle(reg, x, x, x, x);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_writemask(struct brw_reg reg, unsigned mask)
|
||||
{
|
||||
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
||||
reg.dw1.bits.writemask &= mask;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_set_writemask(struct brw_reg reg, unsigned mask)
|
||||
{
|
||||
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
||||
reg.dw1.bits.writemask = mask;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
negate(struct brw_reg reg)
|
||||
{
|
||||
reg.negate ^= 1;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_abs(struct brw_reg reg)
|
||||
{
|
||||
reg.abs = 1;
|
||||
reg.negate = 0;
|
||||
return reg;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_vec4_indirect(unsigned subnr, int offset)
|
||||
{
|
||||
struct brw_reg reg = brw_vec4_grf(0, 0);
|
||||
reg.subnr = subnr;
|
||||
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
|
||||
reg.dw1.bits.indirect_offset = offset;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
brw_vec1_indirect(unsigned subnr, int offset)
|
||||
{
|
||||
struct brw_reg reg = brw_vec1_grf(0, 0);
|
||||
reg.subnr = subnr;
|
||||
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
|
||||
reg.dw1.bits.indirect_offset = offset;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
deref_4f(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
deref_1f(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
deref_4b(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
deref_1uw(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
deref_1d(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
deref_1ud(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
|
||||
}
|
||||
|
||||
static inline struct brw_reg
|
||||
get_addr_reg(struct brw_indirect ptr)
|
||||
{
|
||||
return brw_address_reg(ptr.addr_subnr);
|
||||
}
|
||||
|
||||
static inline struct brw_indirect
|
||||
brw_indirect_offset(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
ptr.addr_offset += offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline struct brw_indirect
|
||||
brw_indirect(unsigned addr_subnr, int offset)
|
||||
{
|
||||
struct brw_indirect ptr;
|
||||
ptr.addr_subnr = addr_subnr;
|
||||
ptr.addr_offset = offset;
|
||||
ptr.pad = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/** Do two brw_regs refer to the same register? */
|
||||
static inline bool
|
||||
brw_same_reg(struct brw_reg r1, struct brw_reg r2)
|
||||
{
|
||||
return r1.file == r2.file && r1.nr == r2.nr;
|
||||
}
|
||||
|
||||
void brw_print_reg(struct brw_reg reg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue