2012-11-09 14:00:15 -08:00
|
|
|
/*
|
|
|
|
|
Copyright (C) Intel Corp. 2006. All Rights Reserved.
|
s/Tungsten Graphics/VMware/
Tungsten Graphics Inc. was acquired by VMware Inc. in 2008. Leaving the
old copyright name is creating unnecessary confusion, hence this change.
This was the sed script I used:
$ cat tg2vmw.sed
# Run as:
#
# git reset --hard HEAD && find include scons src -type f -not -name 'sed*' -print0 | xargs -0 sed -i -f tg2vmw.sed
#
# Rename copyrights
s/Tungsten Gra\(ph\|hp\)ics,\? [iI]nc\.\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./g
/Copyright/s/Tungsten Graphics\(,\? [iI]nc\.\)\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./
s/TUNGSTEN GRAPHICS/VMWARE/g
# Rename emails
s/alanh@tungstengraphics.com/alanh@vmware.com/
s/jens@tungstengraphics.com/jowen@vmware.com/g
s/jrfonseca-at-tungstengraphics-dot-com/jfonseca-at-vmware-dot-com/
s/jrfonseca\?@tungstengraphics.com/jfonseca@vmware.com/g
s/keithw\?@tungstengraphics.com/keithw@vmware.com/g
s/michel@tungstengraphics.com/daenzer@vmware.com/g
s/thomas-at-tungstengraphics-dot-com/thellstom-at-vmware-dot-com/
s/zack@tungstengraphics.com/zackr@vmware.com/
# Remove dead links
s@Tungsten Graphics (http://www.tungstengraphics.com)@Tungsten Graphics@g
# C string src/gallium/state_trackers/vega/api_misc.c
s/"Tungsten Graphics, Inc"/"VMware, Inc"/
Reviewed-by: Brian Paul <brianp@vmware.com>
2014-01-17 16:27:50 +00:00
|
|
|
Intel funded Tungsten Graphics to
|
2012-11-09 14:00:15 -08:00
|
|
|
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:
|
s/Tungsten Graphics/VMware/
Tungsten Graphics Inc. was acquired by VMware Inc. in 2008. Leaving the
old copyright name is creating unnecessary confusion, hence this change.
This was the sed script I used:
$ cat tg2vmw.sed
# Run as:
#
# git reset --hard HEAD && find include scons src -type f -not -name 'sed*' -print0 | xargs -0 sed -i -f tg2vmw.sed
#
# Rename copyrights
s/Tungsten Gra\(ph\|hp\)ics,\? [iI]nc\.\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./g
/Copyright/s/Tungsten Graphics\(,\? [iI]nc\.\)\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./
s/TUNGSTEN GRAPHICS/VMWARE/g
# Rename emails
s/alanh@tungstengraphics.com/alanh@vmware.com/
s/jens@tungstengraphics.com/jowen@vmware.com/g
s/jrfonseca-at-tungstengraphics-dot-com/jfonseca-at-vmware-dot-com/
s/jrfonseca\?@tungstengraphics.com/jfonseca@vmware.com/g
s/keithw\?@tungstengraphics.com/keithw@vmware.com/g
s/michel@tungstengraphics.com/daenzer@vmware.com/g
s/thomas-at-tungstengraphics-dot-com/thellstom-at-vmware-dot-com/
s/zack@tungstengraphics.com/zackr@vmware.com/
# Remove dead links
s@Tungsten Graphics (http://www.tungstengraphics.com)@Tungsten Graphics@g
# C string src/gallium/state_trackers/vega/api_misc.c
s/"Tungsten Graphics, Inc"/"VMware, Inc"/
Reviewed-by: Brian Paul <brianp@vmware.com>
2014-01-17 16:27:50 +00:00
|
|
|
* Keith Whitwell <keithw@vmware.com>
|
2012-11-09 14:00:15 -08:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/** @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>
|
2020-03-25 21:11:44 -04:00
|
|
|
#include "util/compiler.h"
|
2023-08-02 19:24:14 +08:00
|
|
|
#include "util/glheader.h"
|
|
|
|
|
#include "util/macros.h"
|
|
|
|
|
#include "util/rounding.h"
|
|
|
|
|
#include "util/u_math.h"
|
2017-03-09 00:44:29 +00:00
|
|
|
#include "brw_eu_defines.h"
|
2017-07-26 11:08:11 -07:00
|
|
|
#include "brw_reg_type.h"
|
2012-11-09 14:00:15 -08:00
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-04-05 13:19:39 -07:00
|
|
|
struct intel_device_info;
|
2014-07-09 21:17:32 -04:00
|
|
|
|
2022-07-07 01:15:14 -07:00
|
|
|
/** Size of general purpose register space in REG_SIZE units */
|
2012-11-09 21:20:05 -08:00
|
|
|
#define BRW_MAX_GRF 128
|
2022-07-07 01:15:14 -07:00
|
|
|
#define XE2_MAX_GRF 256
|
2012-11-09 21:20:05 -08:00
|
|
|
|
2023-08-02 19:36:27 +08:00
|
|
|
/**
|
|
|
|
|
* BRW hardware swizzles.
|
|
|
|
|
* Only defines XYZW to ensure it can be contained in 2 bits
|
|
|
|
|
*/
|
|
|
|
|
#define BRW_SWIZZLE_X 0
|
|
|
|
|
#define BRW_SWIZZLE_Y 1
|
|
|
|
|
#define BRW_SWIZZLE_Z 2
|
|
|
|
|
#define BRW_SWIZZLE_W 3
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
#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)
|
2016-08-18 11:15:56 +02:00
|
|
|
#define BRW_SWIZZLE_YXYX BRW_SWIZZLE4(1,0,1,0)
|
2016-02-26 17:04:38 -08:00
|
|
|
#define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
|
2013-11-28 18:13:18 -08:00
|
|
|
#define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
|
2016-02-26 17:04:38 -08:00
|
|
|
#define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
|
2013-11-28 18:13:18 -08:00
|
|
|
#define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
|
i965/fs: Improve accuracy of dFdy() to match dFdx().
Previously, we computed dFdy() using the following instruction:
add(8) dst<1>F src<4,4,0)F -src.2<4,4,0>F { align1 1Q }
That had the disadvantage that it computed the same value for all 4
pixels of a 2x2 subspan, which meant that it was less accurate than
dFdx(). This patch changes it to the following instruction when
c->key.high_quality_derivatives is set:
add(8) dst<1>F src<4,4,1>.xyxyF -src<4,4,1>.zwzwF { align16 1Q }
This gives it comparable accuracy to dFdx().
Unfortunately, align16 instructions can't be compressed, so in SIMD16
shaders, instead of emitting this instruction:
add(16) dst<1>F src<4,4,1>.xyxyF -src<4,4,1>.zwzwF { align16 1H }
We need to unroll to two instructions:
add(8) dst<1>F src<4,4,1>.xyxyF -src<4,4,1>.zwzwF { align16 1Q }
add(8) (dst+1)<1>F (src+1)<4,4,1>.xyxyF -(src+1)<4,4,1>.zwzwF { align16 2Q }
Fixes piglit test spec/glsl-1.10/execution/fs-dfdy-accuracy.
Acked-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-09-20 09:04:31 -07:00
|
|
|
#define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
|
2016-08-18 11:15:56 +02:00
|
|
|
#define BRW_SWIZZLE_WZWZ BRW_SWIZZLE4(3,2,3,2)
|
2015-11-17 01:07:39 -08:00
|
|
|
#define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
|
2016-07-19 09:28:04 +02:00
|
|
|
#define BRW_SWIZZLE_XXZZ BRW_SWIZZLE4(0,0,2,2)
|
|
|
|
|
#define BRW_SWIZZLE_YYWW BRW_SWIZZLE4(1,1,3,3)
|
|
|
|
|
#define BRW_SWIZZLE_YXWZ BRW_SWIZZLE4(1,0,3,2)
|
2012-11-09 14:00:15 -08:00
|
|
|
|
2016-06-23 09:32:39 +10:00
|
|
|
#define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
|
|
|
|
|
#define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
static inline bool
|
2015-03-18 14:32:37 +02:00
|
|
|
brw_is_single_value_swizzle(unsigned swiz)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return (swiz == BRW_SWIZZLE_XXXX ||
|
|
|
|
|
swiz == BRW_SWIZZLE_YYYY ||
|
|
|
|
|
swiz == BRW_SWIZZLE_ZZZZ ||
|
|
|
|
|
swiz == BRW_SWIZZLE_WWWW);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-18 14:34:51 +02:00
|
|
|
/**
|
|
|
|
|
* Compute the swizzle obtained from the application of \p swz0 on the result
|
|
|
|
|
* of \p swz1. The argument ordering is expected to match function
|
|
|
|
|
* composition.
|
|
|
|
|
*/
|
|
|
|
|
static inline unsigned
|
|
|
|
|
brw_compose_swizzle(unsigned swz0, unsigned swz1)
|
|
|
|
|
{
|
|
|
|
|
return BRW_SWIZZLE4(
|
|
|
|
|
BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
|
|
|
|
|
BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
|
|
|
|
|
BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
|
|
|
|
|
BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Construct an identity swizzle for the set of enabled channels given by \p
|
|
|
|
|
* mask. The result will only reference channels enabled in the provided \p
|
|
|
|
|
* mask, assuming that \p mask is non-zero. The constructed swizzle will
|
|
|
|
|
* satisfy the property that for any instruction OP and any mask:
|
|
|
|
|
*
|
|
|
|
|
* brw_OP(p, brw_writemask(dst, mask),
|
|
|
|
|
* brw_swizzle(src, brw_swizzle_for_mask(mask)));
|
|
|
|
|
*
|
|
|
|
|
* will be equivalent to the same instruction without swizzle:
|
|
|
|
|
*
|
|
|
|
|
* brw_OP(p, brw_writemask(dst, mask), src);
|
|
|
|
|
*/
|
|
|
|
|
static inline unsigned
|
|
|
|
|
brw_swizzle_for_mask(unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
unsigned last = (mask ? ffs(mask) - 1 : 0);
|
|
|
|
|
unsigned swz[4];
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < 4; i++)
|
|
|
|
|
last = swz[i] = (mask & (1 << i) ? i : last);
|
|
|
|
|
|
|
|
|
|
return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-26 17:12:27 -08:00
|
|
|
uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
|
i965: Abstract BRW_REGISTER_TYPE_* into an enum with unique values.
On released hardware, values 4-6 are overloaded. For normal registers,
they mean UB/B/DF. But for immediates, they mean UV/VF/V.
Previously, we just created #defines for each name, reusing the same
value. This meant we could directly splat the brw_reg::type field into
the assembly encoding, which was fairly nice, and worked well.
Unfortunately, Broadwell makes this infeasible: the HF and DF types are
represented as different numeric values depending on whether the
source register is an immediate or not.
To preserve sanity, I decided to simply convert BRW_REGISTER_TYPE_* to
an abstract enum that has a unique value for each register type, and
write translation functions. One nice benefit is that we can add
assertions about register files and generations.
I've chosen not to convert brw_reg::type to the enum, since converting
it caused a lot of trouble due to C++ enum rules (even though it's
defined in an extern "C" block...).
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-12-10 00:33:56 -08:00
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
#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 {
|
2016-05-13 16:41:13 -07:00
|
|
|
union {
|
|
|
|
|
struct {
|
|
|
|
|
enum brw_reg_type type:4;
|
|
|
|
|
enum brw_reg_file file:3; /* :2 hardware format */
|
|
|
|
|
unsigned negate:1; /* source only */
|
|
|
|
|
unsigned abs:1; /* source only */
|
|
|
|
|
unsigned address_mode:1; /* relative addressing, hopefully! */
|
2018-12-10 11:48:54 -08:00
|
|
|
unsigned pad0:17;
|
2016-05-13 16:41:13 -07:00
|
|
|
unsigned subnr:5; /* :1 in align16 */
|
|
|
|
|
};
|
|
|
|
|
uint32_t bits;
|
|
|
|
|
};
|
2012-11-09 14:00:15 -08:00
|
|
|
|
|
|
|
|
union {
|
|
|
|
|
struct {
|
2018-12-10 11:48:54 -08:00
|
|
|
unsigned nr;
|
2012-11-09 14:00:15 -08:00
|
|
|
unsigned swizzle:8; /* src only, align16 only */
|
|
|
|
|
unsigned writemask:4; /* dest only, align16 only */
|
|
|
|
|
int indirect_offset:10; /* relative addressing offset */
|
2015-10-23 12:17:03 -07:00
|
|
|
unsigned vstride:4; /* source only */
|
|
|
|
|
unsigned width:3; /* src only, align1 only */
|
|
|
|
|
unsigned hstride:2; /* align1 only */
|
|
|
|
|
unsigned pad1:1;
|
2015-10-22 19:41:30 -07:00
|
|
|
};
|
2012-11-09 14:00:15 -08:00
|
|
|
|
2015-11-12 12:40:38 +01:00
|
|
|
double df;
|
2016-05-16 17:28:19 -07:00
|
|
|
uint64_t u64;
|
2016-09-01 11:48:26 -07:00
|
|
|
int64_t d64;
|
2012-11-09 14:00:15 -08:00
|
|
|
float f;
|
|
|
|
|
int d;
|
|
|
|
|
unsigned ud;
|
2015-10-22 19:41:30 -07:00
|
|
|
};
|
2012-11-09 14:00:15 -08:00
|
|
|
};
|
|
|
|
|
|
2022-07-07 01:09:32 -07:00
|
|
|
static inline unsigned
|
|
|
|
|
phys_nr(const struct intel_device_info *devinfo, const struct brw_reg reg)
|
|
|
|
|
{
|
|
|
|
|
if (devinfo->ver >= 20) {
|
|
|
|
|
if (reg.file == BRW_GENERAL_REGISTER_FILE)
|
|
|
|
|
return reg.nr / 2;
|
|
|
|
|
else if (reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
|
|
|
|
|
reg.nr >= BRW_ARF_ACCUMULATOR &&
|
|
|
|
|
reg.nr < BRW_ARF_FLAG)
|
|
|
|
|
return BRW_ARF_ACCUMULATOR + (reg.nr - BRW_ARF_ACCUMULATOR) / 2;
|
|
|
|
|
else
|
|
|
|
|
return reg.nr;
|
|
|
|
|
} else {
|
|
|
|
|
return reg.nr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline unsigned
|
|
|
|
|
phys_subnr(const struct intel_device_info *devinfo, const struct brw_reg reg)
|
|
|
|
|
{
|
|
|
|
|
if (devinfo->ver >= 20) {
|
|
|
|
|
if (reg.file == BRW_GENERAL_REGISTER_FILE ||
|
|
|
|
|
(reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
|
|
|
|
|
reg.nr >= BRW_ARF_ACCUMULATOR &&
|
|
|
|
|
reg.nr < BRW_ARF_FLAG))
|
|
|
|
|
return (reg.nr & 1) * REG_SIZE + reg.subnr;
|
|
|
|
|
else
|
|
|
|
|
return reg.subnr;
|
|
|
|
|
} else {
|
|
|
|
|
return reg.subnr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-13 16:41:13 -07:00
|
|
|
static inline bool
|
|
|
|
|
brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
|
|
|
|
|
{
|
2018-12-10 11:48:54 -08:00
|
|
|
return a->bits == b->bits && a->u64 == b->u64;
|
2016-05-13 16:41:13 -07:00
|
|
|
}
|
2012-11-09 14:00:15 -08:00
|
|
|
|
2015-04-07 16:11:37 -07:00
|
|
|
static inline bool
|
|
|
|
|
brw_regs_negative_equal(const struct brw_reg *a, const struct brw_reg *b)
|
|
|
|
|
{
|
|
|
|
|
if (a->file == IMM) {
|
|
|
|
|
if (a->bits != b->bits)
|
|
|
|
|
return false;
|
|
|
|
|
|
2018-03-29 11:29:09 -07:00
|
|
|
switch ((enum brw_reg_type) a->type) {
|
2015-04-07 16:11:37 -07:00
|
|
|
case BRW_REGISTER_TYPE_UQ:
|
|
|
|
|
case BRW_REGISTER_TYPE_Q:
|
|
|
|
|
return a->d64 == -b->d64;
|
|
|
|
|
case BRW_REGISTER_TYPE_DF:
|
|
|
|
|
return a->df == -b->df;
|
|
|
|
|
case BRW_REGISTER_TYPE_UD:
|
|
|
|
|
case BRW_REGISTER_TYPE_D:
|
|
|
|
|
return a->d == -b->d;
|
|
|
|
|
case BRW_REGISTER_TYPE_F:
|
|
|
|
|
return a->f == -b->f;
|
|
|
|
|
case BRW_REGISTER_TYPE_VF:
|
|
|
|
|
/* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
|
|
|
|
|
* of -0). There are occasions where 0 or -0 is used and the exact
|
|
|
|
|
* bit pattern is desired. At the very least, changing this to allow
|
|
|
|
|
* 0 as a negation of 0 causes some fp64 tests to fail on IVB.
|
|
|
|
|
*/
|
|
|
|
|
return a->ud == (b->ud ^ 0x80808080);
|
|
|
|
|
case BRW_REGISTER_TYPE_UW:
|
|
|
|
|
case BRW_REGISTER_TYPE_W:
|
|
|
|
|
case BRW_REGISTER_TYPE_UV:
|
|
|
|
|
case BRW_REGISTER_TYPE_V:
|
|
|
|
|
case BRW_REGISTER_TYPE_HF:
|
|
|
|
|
/* FINISHME: Implement support for these types once there is
|
|
|
|
|
* something in the compiler that can generate them. Until then,
|
|
|
|
|
* they cannot be tested.
|
|
|
|
|
*/
|
|
|
|
|
return false;
|
|
|
|
|
case BRW_REGISTER_TYPE_UB:
|
|
|
|
|
case BRW_REGISTER_TYPE_B:
|
2018-04-03 14:41:18 +01:00
|
|
|
default:
|
2015-04-07 16:11:37 -07:00
|
|
|
unreachable("not reached");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
struct brw_reg tmp = *a;
|
|
|
|
|
|
|
|
|
|
tmp.negate = !tmp.negate;
|
|
|
|
|
|
|
|
|
|
return brw_regs_equal(&tmp, b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
struct brw_indirect {
|
|
|
|
|
unsigned addr_subnr:4;
|
|
|
|
|
int addr_offset:10;
|
|
|
|
|
unsigned pad:18;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2015-04-11 14:49:50 -07:00
|
|
|
static inline unsigned
|
2012-11-09 14:00:15 -08:00
|
|
|
type_sz(unsigned type)
|
|
|
|
|
{
|
|
|
|
|
switch(type) {
|
2014-12-22 19:29:13 -08:00
|
|
|
case BRW_REGISTER_TYPE_UQ:
|
|
|
|
|
case BRW_REGISTER_TYPE_Q:
|
2014-09-03 20:10:30 +03:00
|
|
|
case BRW_REGISTER_TYPE_DF:
|
2014-12-22 19:29:13 -08:00
|
|
|
return 8;
|
2012-11-09 14:00:15 -08:00
|
|
|
case BRW_REGISTER_TYPE_UD:
|
|
|
|
|
case BRW_REGISTER_TYPE_D:
|
|
|
|
|
case BRW_REGISTER_TYPE_F:
|
2016-05-24 15:10:25 -07:00
|
|
|
case BRW_REGISTER_TYPE_VF:
|
2012-11-09 14:00:15 -08:00
|
|
|
return 4;
|
|
|
|
|
case BRW_REGISTER_TYPE_UW:
|
|
|
|
|
case BRW_REGISTER_TYPE_W:
|
2021-07-01 14:46:48 +02:00
|
|
|
case BRW_REGISTER_TYPE_HF:
|
|
|
|
|
/* [U]V components are 4-bit, but HW unpacks them to 16-bit (2 bytes) */
|
2016-05-24 15:10:25 -07:00
|
|
|
case BRW_REGISTER_TYPE_UV:
|
|
|
|
|
case BRW_REGISTER_TYPE_V:
|
2012-11-09 14:00:15 -08:00
|
|
|
return 2;
|
|
|
|
|
case BRW_REGISTER_TYPE_UB:
|
|
|
|
|
case BRW_REGISTER_TYPE_B:
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
2016-05-24 15:10:25 -07:00
|
|
|
unreachable("not reached");
|
2012-11-09 14:00:15 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-18 07:17:39 +00:00
|
|
|
static inline enum brw_reg_type
|
|
|
|
|
get_exec_type(const enum brw_reg_type type)
|
|
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case BRW_REGISTER_TYPE_B:
|
|
|
|
|
case BRW_REGISTER_TYPE_V:
|
|
|
|
|
return BRW_REGISTER_TYPE_W;
|
|
|
|
|
case BRW_REGISTER_TYPE_UB:
|
|
|
|
|
case BRW_REGISTER_TYPE_UV:
|
|
|
|
|
return BRW_REGISTER_TYPE_UW;
|
|
|
|
|
case BRW_REGISTER_TYPE_VF:
|
|
|
|
|
return BRW_REGISTER_TYPE_F;
|
|
|
|
|
default:
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-25 17:35:52 -07:00
|
|
|
/**
|
|
|
|
|
* Return an integer type of the requested size and signedness.
|
|
|
|
|
*/
|
|
|
|
|
static inline enum brw_reg_type
|
|
|
|
|
brw_int_type(unsigned sz, bool is_signed)
|
|
|
|
|
{
|
|
|
|
|
switch (sz) {
|
|
|
|
|
case 1:
|
|
|
|
|
return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
|
|
|
|
|
case 2:
|
|
|
|
|
return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
|
|
|
|
|
case 4:
|
|
|
|
|
return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
|
|
|
|
|
case 8:
|
|
|
|
|
return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Not reached.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
/**
|
|
|
|
|
* Construct a brw_reg.
|
|
|
|
|
* \param file one of the BRW_x_REGISTER_FILE values
|
|
|
|
|
* \param nr register number/index
|
|
|
|
|
* \param subnr register sub number
|
2014-12-12 17:19:07 +01:00
|
|
|
* \param negate register negate modifier
|
|
|
|
|
* \param abs register abs modifier
|
2012-11-09 14:00:15 -08:00
|
|
|
* \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
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_reg(enum brw_reg_file file,
|
2012-11-09 14:00:15 -08:00
|
|
|
unsigned nr,
|
|
|
|
|
unsigned subnr,
|
2014-12-12 17:19:07 +01:00
|
|
|
unsigned negate,
|
|
|
|
|
unsigned abs,
|
2014-06-29 16:02:59 -07:00
|
|
|
enum brw_reg_type type,
|
2012-11-09 14:00:15 -08:00
|
|
|
unsigned vstride,
|
|
|
|
|
unsigned width,
|
|
|
|
|
unsigned hstride,
|
|
|
|
|
unsigned swizzle,
|
|
|
|
|
unsigned writemask)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg reg;
|
|
|
|
|
if (file == BRW_GENERAL_REGISTER_FILE)
|
2022-07-07 01:15:14 -07:00
|
|
|
assert(nr < XE2_MAX_GRF);
|
2012-11-09 14:00:15 -08:00
|
|
|
else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
|
|
|
|
|
assert(nr <= BRW_ARF_TIMESTAMP);
|
|
|
|
|
|
|
|
|
|
reg.type = type;
|
|
|
|
|
reg.file = file;
|
2014-12-12 17:19:07 +01:00
|
|
|
reg.negate = negate;
|
|
|
|
|
reg.abs = abs;
|
2012-11-09 14:00:15 -08:00
|
|
|
reg.address_mode = BRW_ADDRESS_DIRECT;
|
|
|
|
|
reg.pad0 = 0;
|
2015-10-26 04:35:14 -07:00
|
|
|
reg.subnr = subnr * type_sz(type);
|
|
|
|
|
reg.nr = nr;
|
2012-11-09 14:00:15 -08:00
|
|
|
|
|
|
|
|
/* 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?
|
|
|
|
|
*/
|
2015-10-22 19:41:30 -07:00
|
|
|
reg.swizzle = swizzle;
|
|
|
|
|
reg.writemask = writemask;
|
|
|
|
|
reg.indirect_offset = 0;
|
2015-10-23 12:17:03 -07:00
|
|
|
reg.vstride = vstride;
|
|
|
|
|
reg.width = width;
|
|
|
|
|
reg.hstride = hstride;
|
2015-10-22 19:41:30 -07:00
|
|
|
reg.pad1 = 0;
|
2012-11-09 14:00:15 -08:00
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Construct float[16] register */
|
|
|
|
|
static inline struct brw_reg
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return brw_reg(file,
|
|
|
|
|
nr,
|
|
|
|
|
subnr,
|
2014-12-12 17:19:07 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2012-11-09 14:00:15 -08:00
|
|
|
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
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return brw_reg(file,
|
|
|
|
|
nr,
|
|
|
|
|
subnr,
|
2014-12-12 17:19:07 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2012-11-09 14:00:15 -08:00
|
|
|
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
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return brw_reg(file,
|
|
|
|
|
nr,
|
|
|
|
|
subnr,
|
2014-12-12 17:19:07 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2012-11-09 14:00:15 -08:00
|
|
|
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
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return brw_reg(file,
|
|
|
|
|
nr,
|
|
|
|
|
subnr,
|
2014-12-12 17:19:07 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2012-11-09 14:00:15 -08:00
|
|
|
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
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return brw_reg(file,
|
|
|
|
|
nr,
|
|
|
|
|
subnr,
|
2014-12-12 17:19:07 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2012-11-09 14:00:15 -08:00
|
|
|
BRW_REGISTER_TYPE_F,
|
|
|
|
|
BRW_VERTICAL_STRIDE_0,
|
|
|
|
|
BRW_WIDTH_1,
|
|
|
|
|
BRW_HORIZONTAL_STRIDE_0,
|
|
|
|
|
BRW_SWIZZLE_XXXX,
|
|
|
|
|
WRITEMASK_X);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-11 14:19:47 -07:00
|
|
|
static inline struct brw_reg
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_vecn_reg(unsigned width, enum brw_reg_file file,
|
|
|
|
|
unsigned nr, unsigned subnr)
|
2013-09-11 14:19:47 -07:00
|
|
|
{
|
|
|
|
|
switch (width) {
|
|
|
|
|
case 1:
|
|
|
|
|
return brw_vec1_reg(file, nr, subnr);
|
|
|
|
|
case 2:
|
|
|
|
|
return brw_vec2_reg(file, nr, subnr);
|
|
|
|
|
case 4:
|
|
|
|
|
return brw_vec4_reg(file, nr, subnr);
|
|
|
|
|
case 8:
|
|
|
|
|
return brw_vec8_reg(file, nr, subnr);
|
|
|
|
|
case 16:
|
|
|
|
|
return brw_vec16_reg(file, nr, subnr);
|
|
|
|
|
default:
|
2014-06-29 19:12:04 -07:00
|
|
|
unreachable("Invalid register width");
|
2013-09-11 14:19:47 -07:00
|
|
|
}
|
|
|
|
|
}
|
2012-11-09 14:00:15 -08:00
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
2014-06-29 16:02:59 -07:00
|
|
|
retype(struct brw_reg reg, enum brw_reg_type type)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
reg.type = type;
|
|
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-13 12:23:47 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
firsthalf(struct brw_reg reg)
|
|
|
|
|
{
|
|
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
sechalf(struct brw_reg reg)
|
|
|
|
|
{
|
|
|
|
|
if (reg.vstride)
|
|
|
|
|
reg.nr++;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-27 12:23:44 +02:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
suboffset(struct brw_reg reg, unsigned delta)
|
|
|
|
|
{
|
|
|
|
|
return byte_offset(reg, delta * type_sz(reg.type));
|
|
|
|
|
}
|
2012-11-09 14:00:15 -08:00
|
|
|
|
|
|
|
|
/** Construct unsigned word[16] register */
|
|
|
|
|
static inline struct brw_reg
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Construct unsigned word[8] register */
|
|
|
|
|
static inline struct brw_reg
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Construct unsigned word[1] register */
|
|
|
|
|
static inline struct brw_reg
|
2015-10-23 13:11:44 -07:00
|
|
|
brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 16:52:10 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_ud8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return retype(brw_vec8_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-14 15:09:32 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_ud1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return retype(brw_vec1_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
static inline struct brw_reg
|
2014-06-29 16:02:59 -07:00
|
|
|
brw_imm_reg(enum brw_reg_type type)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
|
|
|
|
return brw_reg(BRW_IMMEDIATE_VALUE,
|
2014-12-12 17:19:07 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2012-11-09 14:00:15 -08:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
type,
|
|
|
|
|
BRW_VERTICAL_STRIDE_0,
|
|
|
|
|
BRW_WIDTH_1,
|
|
|
|
|
BRW_HORIZONTAL_STRIDE_0,
|
|
|
|
|
0,
|
|
|
|
|
0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Construct float immediate register */
|
2015-11-12 12:40:38 +01:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_imm_df(double df)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
|
|
|
|
|
imm.df = df;
|
|
|
|
|
return imm;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-31 22:12:48 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_imm_u64(uint64_t u64)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
|
|
|
|
|
imm.u64 = u64;
|
|
|
|
|
return imm;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_imm_f(float f)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
|
2015-10-22 19:41:30 -07:00
|
|
|
imm.f = f;
|
2012-11-09 14:00:15 -08:00
|
|
|
return imm;
|
2017-11-02 18:29:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Construct int64_t immediate register */
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_imm_q(int64_t q)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_Q);
|
|
|
|
|
imm.d64 = q;
|
|
|
|
|
return imm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Construct int64_t immediate register */
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_imm_uq(uint64_t uq)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
|
|
|
|
|
imm.u64 = uq;
|
|
|
|
|
return imm;
|
2012-11-09 14:00:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 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);
|
2015-10-22 19:41:30 -07:00
|
|
|
imm.d = d;
|
2012-11-09 14:00:15 -08:00
|
|
|
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);
|
2015-10-22 19:41:30 -07:00
|
|
|
imm.ud = ud;
|
2012-11-09 14:00:15 -08:00
|
|
|
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);
|
2015-10-22 19:41:30 -07:00
|
|
|
imm.ud = uw | (uw << 16);
|
2012-11-09 14:00:15 -08:00
|
|
|
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);
|
intel/compiler: fix brw_imm_w for negative 16-bit integers
16-bit immediates need to replicate the 16-bit immediate value
in both words of the 32-bit value. This needs to be careful
to avoid sign-extension, which the previous implementation was
not handling properly.
For example, with the previous implementation, storing the value
-3 would generate imm.d = 0xfffffffd due to signed integer sign
extension, which is not correct. Instead, we should cast to
uint16_t, which gives us the correct result: imm.ud = 0xfffdfffd.
We only had a couple of cases hitting this path in the driver
until now, one with value -1, which would work since all bits are
one in this case, and another with value -2 in brw_clip_tri(),
which would hit the aforementioned issue (this case only affects
gen4 although we are not aware of whether this was causing an
actual bug somewhere).
v2: Make explicit uint32_t casting for left shift (Jason Ekstrand)
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Cc: "18.0 18.1" <mesa-stable@lists.freedesktop.org>
2018-05-03 01:38:47 +02:00
|
|
|
imm.ud = (uint16_t)w | (uint32_t)(uint16_t)w << 16;
|
2012-11-09 14:00:15 -08:00
|
|
|
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);
|
2015-10-22 19:41:30 -07:00
|
|
|
imm.ud = v;
|
2012-11-09 14:00:15 -08:00
|
|
|
return imm;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 09:29:01 -08:00
|
|
|
/** Construct vector of eight unsigned half-byte values */
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_imm_uv(unsigned uv)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
|
|
|
|
|
imm.ud = uv;
|
|
|
|
|
return imm;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
/** 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);
|
2015-10-22 19:41:30 -07:00
|
|
|
imm.ud = v;
|
2012-11-09 14:00:15 -08:00
|
|
|
return imm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
2015-11-02 10:29:45 -08:00
|
|
|
brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
2015-11-02 10:29:45 -08:00
|
|
|
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.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
|
|
|
|
|
return imm;
|
2012-11-09 14:00:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-16 15:13:02 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
xe2_vec1_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
/** 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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-16 15:13:02 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
xe2_vec2_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
/** 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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-16 15:13:02 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
xe2_vec4_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
/** 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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-16 15:13:02 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
xe2_vec8_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-06 17:44:40 -07:00
|
|
|
/** Construct float[16] general-purpose register */
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_vec16_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-16 15:13:02 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
xe2_vec16_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-13 14:22:03 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-16 15:13:02 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
xe2_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr + subnr / 8, subnr % 8);
|
|
|
|
|
}
|
2012-11-09 14:00:15 -08:00
|
|
|
|
2023-04-05 12:16:33 +02:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_uw1_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 16:52:10 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_ud8_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_ud8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_ud1_grf(unsigned nr, unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_ud1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
|
|
|
|
|
/** 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);
|
2014-09-10 11:28:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_null_vec(unsigned width)
|
|
|
|
|
{
|
|
|
|
|
return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
|
2012-11-09 14:00:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_address_reg(unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-06 11:41:54 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_tdr_reg(void)
|
|
|
|
|
{
|
|
|
|
|
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_TDR, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
/* 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,
|
2014-12-12 17:19:07 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2012-11-09 14:00:15 -08:00
|
|
|
BRW_REGISTER_TYPE_UD,
|
|
|
|
|
BRW_VERTICAL_STRIDE_4, /* ? */
|
|
|
|
|
BRW_WIDTH_1,
|
|
|
|
|
BRW_HORIZONTAL_STRIDE_0,
|
|
|
|
|
BRW_SWIZZLE_XYZW, /* NOTE! */
|
|
|
|
|
WRITEMASK_XYZW); /* NOTE! */
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-04 17:52:42 -08:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_notification_reg(void)
|
|
|
|
|
{
|
|
|
|
|
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
|
|
|
|
BRW_ARF_NOTIFICATION_COUNT,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
BRW_REGISTER_TYPE_UD,
|
|
|
|
|
BRW_VERTICAL_STRIDE_0,
|
|
|
|
|
BRW_WIDTH_1,
|
|
|
|
|
BRW_HORIZONTAL_STRIDE_0,
|
|
|
|
|
BRW_SWIZZLE_XXXX,
|
|
|
|
|
WRITEMASK_X);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-01 08:11:58 +02:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_cr0_reg(unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_CONTROL, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-20 01:22:08 -08:00
|
|
|
static inline struct brw_reg
|
2016-09-14 15:09:32 -07:00
|
|
|
brw_sr0_reg(unsigned subnr)
|
2016-02-20 01:22:08 -08:00
|
|
|
{
|
2016-09-14 15:09:32 -07:00
|
|
|
return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_STATE, subnr);
|
2016-02-20 01:22:08 -08:00
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
static inline struct brw_reg
|
2014-09-30 10:15:23 -07:00
|
|
|
brw_acc_reg(unsigned width)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
2014-09-30 10:15:23 -07:00
|
|
|
return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
|
|
|
|
|
BRW_ARF_ACCUMULATOR, 0);
|
2012-11-09 14:00:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-12 12:05:02 -08:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_flag_subreg(unsigned subreg)
|
|
|
|
|
{
|
|
|
|
|
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
|
|
|
|
BRW_ARF_FLAG + subreg / 2, subreg % 2);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-06 17:37:12 +03:00
|
|
|
/**
|
2021-03-29 15:46:12 -07:00
|
|
|
* Return the mask register present in Gfx4-5, or the related register present
|
|
|
|
|
* in Gfx7.5 and later hardware referred to as "channel enable" register in
|
2015-05-06 17:37:12 +03:00
|
|
|
* the documentation.
|
|
|
|
|
*/
|
2012-11-09 14:00:15 -08:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_mask_reg(unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-14 15:09:33 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_vmask_reg()
|
|
|
|
|
{
|
|
|
|
|
return brw_sr0_reg(3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_dmask_reg()
|
|
|
|
|
{
|
|
|
|
|
return brw_sr0_reg(2);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-25 14:59:30 -05:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_mask_stack_reg(unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return suboffset(retype(brw_vec16_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
|
|
|
|
BRW_ARF_MASK_STACK, 0),
|
|
|
|
|
BRW_REGISTER_TYPE_UB), subnr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_mask_stack_depth_reg(unsigned subnr)
|
|
|
|
|
{
|
|
|
|
|
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
|
|
|
|
BRW_ARF_MASK_STACK_DEPTH, subnr);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
/* 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;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-04 17:58:49 +02:00
|
|
|
/**
|
|
|
|
|
* Multiply the vertical and horizontal stride of a register by the given
|
|
|
|
|
* factor \a s.
|
|
|
|
|
*/
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
spread(struct brw_reg reg, unsigned s)
|
|
|
|
|
{
|
|
|
|
|
if (s) {
|
2018-09-06 11:36:19 -07:00
|
|
|
assert(util_is_power_of_two_nonzero(s));
|
2015-02-04 17:58:49 +02:00
|
|
|
|
|
|
|
|
if (reg.hstride)
|
|
|
|
|
reg.hstride += cvt(s) - 1;
|
|
|
|
|
|
|
|
|
|
if (reg.vstride)
|
|
|
|
|
reg.vstride += cvt(s) - 1;
|
|
|
|
|
|
|
|
|
|
return reg;
|
|
|
|
|
} else {
|
|
|
|
|
return stride(reg, 0, 1, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-09 14:00:15 -08:00
|
|
|
|
2017-10-17 19:50:36 -07:00
|
|
|
/**
|
|
|
|
|
* Reinterpret each channel of register \p reg as a vector of values of the
|
|
|
|
|
* given smaller type and take the i-th subcomponent from each.
|
|
|
|
|
*/
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
subscript(struct brw_reg reg, enum brw_reg_type type, unsigned i)
|
|
|
|
|
{
|
|
|
|
|
unsigned scale = type_sz(reg.type) / type_sz(type);
|
|
|
|
|
assert(scale >= 1 && i < scale);
|
|
|
|
|
|
2020-10-26 13:27:43 -05:00
|
|
|
if (reg.file == IMM) {
|
|
|
|
|
unsigned bit_size = type_sz(type) * 8;
|
|
|
|
|
reg.u64 >>= i * bit_size;
|
|
|
|
|
reg.u64 &= BITFIELD64_MASK(bit_size);
|
|
|
|
|
if (bit_size <= 16)
|
|
|
|
|
reg.u64 |= reg.u64 << 16;
|
|
|
|
|
return retype(reg, type);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-17 19:50:36 -07:00
|
|
|
return suboffset(retype(spread(reg, scale), type), i);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
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
|
2016-02-26 17:04:38 -08:00
|
|
|
brw_swizzle(struct brw_reg reg, unsigned swz)
|
2012-11-09 14:00:15 -08:00
|
|
|
{
|
2016-02-26 17:12:27 -08:00
|
|
|
if (reg.file == BRW_IMMEDIATE_VALUE)
|
|
|
|
|
reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
|
|
|
|
|
else
|
|
|
|
|
reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
|
2012-11-09 14:00:15 -08:00
|
|
|
|
|
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_writemask(struct brw_reg reg, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
2015-10-22 19:41:30 -07:00
|
|
|
reg.writemask &= mask;
|
2012-11-09 14:00:15 -08:00
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_set_writemask(struct brw_reg reg, unsigned mask)
|
|
|
|
|
{
|
|
|
|
|
assert(reg.file != BRW_IMMEDIATE_VALUE);
|
2015-10-22 19:41:30 -07:00
|
|
|
reg.writemask = mask;
|
2012-11-09 14:00:15 -08:00
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-16 20:53:28 +02:00
|
|
|
static inline unsigned
|
|
|
|
|
brw_writemask_for_size(unsigned n)
|
|
|
|
|
{
|
|
|
|
|
return (1 << n) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-23 12:52:05 +10:00
|
|
|
static inline unsigned
|
|
|
|
|
brw_writemask_for_component_packing(unsigned n, unsigned first_component)
|
|
|
|
|
{
|
|
|
|
|
assert(first_component + n <= 4);
|
|
|
|
|
return (((1 << n) - 1) << first_component);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
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;
|
2015-10-22 19:41:30 -07:00
|
|
|
reg.indirect_offset = offset;
|
2012-11-09 14:00:15 -08:00
|
|
|
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;
|
2015-10-22 19:41:30 -07:00
|
|
|
reg.indirect_offset = offset;
|
2012-11-09 14:00:15 -08:00
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-19 22:15:33 -07:00
|
|
|
static inline struct brw_reg
|
|
|
|
|
brw_VxH_indirect(unsigned subnr, int offset)
|
|
|
|
|
{
|
|
|
|
|
struct brw_reg reg = brw_vec1_grf(0, 0);
|
|
|
|
|
reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
|
|
|
|
|
reg.subnr = subnr;
|
|
|
|
|
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
|
2015-10-22 19:41:30 -07:00
|
|
|
reg.indirect_offset = offset;
|
2015-08-19 22:15:33 -07:00
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-22 19:29:22 -08:00
|
|
|
static inline bool
|
|
|
|
|
region_matches(struct brw_reg reg, enum brw_vertical_stride v,
|
|
|
|
|
enum brw_width w, enum brw_horizontal_stride h)
|
|
|
|
|
{
|
|
|
|
|
return reg.vstride == v &&
|
|
|
|
|
reg.width == w &&
|
|
|
|
|
reg.hstride == h;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define has_scalar_region(reg) \
|
|
|
|
|
region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
|
|
|
|
|
BRW_HORIZONTAL_STRIDE_0)
|
|
|
|
|
|
2021-12-20 01:54:57 -08:00
|
|
|
/**
|
|
|
|
|
* Return the size in bytes per data element of register \p reg on the
|
|
|
|
|
* corresponding register file.
|
|
|
|
|
*/
|
|
|
|
|
static inline unsigned
|
|
|
|
|
element_sz(struct brw_reg reg)
|
|
|
|
|
{
|
|
|
|
|
if (reg.file == BRW_IMMEDIATE_VALUE || has_scalar_region(reg)) {
|
|
|
|
|
return type_sz(reg.type);
|
|
|
|
|
|
|
|
|
|
} else if (reg.width == BRW_WIDTH_1 &&
|
|
|
|
|
reg.hstride == BRW_HORIZONTAL_STRIDE_0) {
|
|
|
|
|
assert(reg.vstride != BRW_VERTICAL_STRIDE_0);
|
|
|
|
|
return type_sz(reg.type) << (reg.vstride - 1);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
assert(reg.hstride != BRW_HORIZONTAL_STRIDE_0);
|
|
|
|
|
assert(reg.vstride == reg.hstride + reg.width);
|
|
|
|
|
return type_sz(reg.type) << (reg.hstride - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-03 14:59:26 -07:00
|
|
|
/* brw_packed_float.c */
|
|
|
|
|
int brw_float_to_vf(float f);
|
|
|
|
|
float brw_vf_to_float(unsigned char vf);
|
|
|
|
|
|
2012-11-09 14:00:15 -08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|