intel/brw: Move shuffle_from_32bit_read implementation to brw_builder
Make it a member function for convenience -- since another member function uses it. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33108>
This commit is contained in:
@@ -5,6 +5,125 @@
|
||||
|
||||
#include "brw_builder.h"
|
||||
|
||||
/*
|
||||
* This helper takes a source register and un/shuffles it into the destination
|
||||
* register.
|
||||
*
|
||||
* If source type size is smaller than destination type size the operation
|
||||
* needed is a component shuffle. The opposite case would be an unshuffle. If
|
||||
* source/destination type size is equal a shuffle is done that would be
|
||||
* equivalent to a simple MOV.
|
||||
*
|
||||
* For example, if source is a 16-bit type and destination is 32-bit. A 3
|
||||
* components .xyz 16-bit vector on SIMD8 would be.
|
||||
*
|
||||
* |x1|x2|x3|x4|x5|x6|x7|x8|y1|y2|y3|y4|y5|y6|y7|y8|
|
||||
* |z1|z2|z3|z4|z5|z6|z7|z8| | | | | | | | |
|
||||
*
|
||||
* This helper will return the following 2 32-bit components with the 16-bit
|
||||
* values shuffled:
|
||||
*
|
||||
* |x1 y1|x2 y2|x3 y3|x4 y4|x5 y5|x6 y6|x7 y7|x8 y8|
|
||||
* |z1 |z2 |z3 |z4 |z5 |z6 |z7 |z8 |
|
||||
*
|
||||
* For unshuffle, the example would be the opposite, a 64-bit type source
|
||||
* and a 32-bit destination. A 2 component .xy 64-bit vector on SIMD8
|
||||
* would be:
|
||||
*
|
||||
* | x1l x1h | x2l x2h | x3l x3h | x4l x4h |
|
||||
* | x5l x5h | x6l x6h | x7l x7h | x8l x8h |
|
||||
* | y1l y1h | y2l y2h | y3l y3h | y4l y4h |
|
||||
* | y5l y5h | y6l y6h | y7l y7h | y8l y8h |
|
||||
*
|
||||
* The returned result would be the following 4 32-bit components unshuffled:
|
||||
*
|
||||
* | x1l | x2l | x3l | x4l | x5l | x6l | x7l | x8l |
|
||||
* | x1h | x2h | x3h | x4h | x5h | x6h | x7h | x8h |
|
||||
* | y1l | y2l | y3l | y4l | y5l | y6l | y7l | y8l |
|
||||
* | y1h | y2h | y3h | y4h | y5h | y6h | y7h | y8h |
|
||||
*
|
||||
* - Source and destination register must not be overlapped.
|
||||
* - components units are measured in terms of the smaller type between
|
||||
* source and destination because we are un/shuffling the smaller
|
||||
* components from/into the bigger ones.
|
||||
* - first_component parameter allows skipping source components.
|
||||
*/
|
||||
static void
|
||||
shuffle_src_to_dst(const brw_builder &bld,
|
||||
const brw_reg &dst,
|
||||
const brw_reg &src,
|
||||
uint32_t first_component,
|
||||
uint32_t components)
|
||||
{
|
||||
if (brw_type_size_bytes(src.type) == brw_type_size_bytes(dst.type)) {
|
||||
assert(!regions_overlap(dst,
|
||||
brw_type_size_bytes(dst.type) * bld.dispatch_width() * components,
|
||||
offset(src, bld, first_component),
|
||||
brw_type_size_bytes(src.type) * bld.dispatch_width() * components));
|
||||
for (unsigned i = 0; i < components; i++) {
|
||||
bld.MOV(retype(offset(dst, bld, i), src.type),
|
||||
offset(src, bld, i + first_component));
|
||||
}
|
||||
} else if (brw_type_size_bytes(src.type) < brw_type_size_bytes(dst.type)) {
|
||||
/* Source is shuffled into destination */
|
||||
unsigned size_ratio = brw_type_size_bytes(dst.type) / brw_type_size_bytes(src.type);
|
||||
assert(!regions_overlap(dst,
|
||||
brw_type_size_bytes(dst.type) * bld.dispatch_width() *
|
||||
DIV_ROUND_UP(components, size_ratio),
|
||||
offset(src, bld, first_component),
|
||||
brw_type_size_bytes(src.type) * bld.dispatch_width() * components));
|
||||
|
||||
brw_reg_type shuffle_type =
|
||||
brw_type_with_size(BRW_TYPE_D, brw_type_size_bits(src.type));
|
||||
for (unsigned i = 0; i < components; i++) {
|
||||
brw_reg shuffle_component_i =
|
||||
subscript(offset(dst, bld, i / size_ratio),
|
||||
shuffle_type, i % size_ratio);
|
||||
bld.MOV(shuffle_component_i,
|
||||
retype(offset(src, bld, i + first_component), shuffle_type));
|
||||
}
|
||||
} else {
|
||||
/* Source is unshuffled into destination */
|
||||
unsigned size_ratio = brw_type_size_bytes(src.type) / brw_type_size_bytes(dst.type);
|
||||
assert(!regions_overlap(dst,
|
||||
brw_type_size_bytes(dst.type) * bld.dispatch_width() * components,
|
||||
offset(src, bld, first_component / size_ratio),
|
||||
brw_type_size_bytes(src.type) * bld.dispatch_width() *
|
||||
DIV_ROUND_UP(components + (first_component % size_ratio),
|
||||
size_ratio)));
|
||||
|
||||
brw_reg_type shuffle_type =
|
||||
brw_type_with_size(BRW_TYPE_D, brw_type_size_bits(dst.type));
|
||||
for (unsigned i = 0; i < components; i++) {
|
||||
brw_reg shuffle_component_i =
|
||||
subscript(offset(src, bld, (first_component + i) / size_ratio),
|
||||
shuffle_type, (first_component + i) % size_ratio);
|
||||
bld.MOV(retype(offset(dst, bld, i), shuffle_type),
|
||||
shuffle_component_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brw_builder::shuffle_from_32bit_read(const brw_reg &dst,
|
||||
const brw_reg &src,
|
||||
uint32_t first_component,
|
||||
uint32_t components) const
|
||||
{
|
||||
assert(brw_type_size_bytes(src.type) == 4);
|
||||
|
||||
/* This function takes components in units of the destination type while
|
||||
* shuffle_src_to_dst takes components in units of the smallest type
|
||||
*/
|
||||
if (brw_type_size_bytes(dst.type) > 4) {
|
||||
assert(brw_type_size_bytes(dst.type) == 8);
|
||||
first_component *= 2;
|
||||
components *= 2;
|
||||
}
|
||||
|
||||
shuffle_src_to_dst(*this, dst, src, first_component, components);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mask of SIMD channels enabled during dispatch and not yet disabled
|
||||
* by discard. Due to the layout of the sample mask in the fragment shader
|
||||
|
||||
@@ -798,7 +798,7 @@ public:
|
||||
vec4_result, srcs, PULL_VARYING_CONSTANT_SRCS);
|
||||
inst->size_written = 4 * vec4_result.component_size(inst->exec_size);
|
||||
|
||||
shuffle_from_32bit_read(*this, dst, vec4_result, 0, components);
|
||||
shuffle_from_32bit_read(dst, vec4_result, 0, components);
|
||||
}
|
||||
|
||||
brw_reg
|
||||
@@ -908,6 +908,11 @@ private:
|
||||
return expanded;
|
||||
}
|
||||
|
||||
void shuffle_from_32bit_read(const brw_reg &dst,
|
||||
const brw_reg &src,
|
||||
uint32_t first_component,
|
||||
uint32_t components) const;
|
||||
|
||||
bblock_t *block;
|
||||
exec_node *cursor;
|
||||
|
||||
|
||||
@@ -486,12 +486,6 @@ namespace brw {
|
||||
lower_src_modifiers(fs_visitor *v, bblock_t *block, fs_inst *inst, unsigned i);
|
||||
}
|
||||
|
||||
void shuffle_from_32bit_read(const brw_builder &bld,
|
||||
const brw_reg &dst,
|
||||
const brw_reg &src,
|
||||
uint32_t first_component,
|
||||
uint32_t components);
|
||||
|
||||
enum intel_barycentric_mode brw_barycentric_mode(const struct brw_wm_prog_key *key,
|
||||
nir_intrinsic_instr *intr);
|
||||
|
||||
|
||||
@@ -7625,126 +7625,6 @@ fs_nir_emit_jump(nir_to_brw_state &ntb, nir_jump_instr *instr)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This helper takes a source register and un/shuffles it into the destination
|
||||
* register.
|
||||
*
|
||||
* If source type size is smaller than destination type size the operation
|
||||
* needed is a component shuffle. The opposite case would be an unshuffle. If
|
||||
* source/destination type size is equal a shuffle is done that would be
|
||||
* equivalent to a simple MOV.
|
||||
*
|
||||
* For example, if source is a 16-bit type and destination is 32-bit. A 3
|
||||
* components .xyz 16-bit vector on SIMD8 would be.
|
||||
*
|
||||
* |x1|x2|x3|x4|x5|x6|x7|x8|y1|y2|y3|y4|y5|y6|y7|y8|
|
||||
* |z1|z2|z3|z4|z5|z6|z7|z8| | | | | | | | |
|
||||
*
|
||||
* This helper will return the following 2 32-bit components with the 16-bit
|
||||
* values shuffled:
|
||||
*
|
||||
* |x1 y1|x2 y2|x3 y3|x4 y4|x5 y5|x6 y6|x7 y7|x8 y8|
|
||||
* |z1 |z2 |z3 |z4 |z5 |z6 |z7 |z8 |
|
||||
*
|
||||
* For unshuffle, the example would be the opposite, a 64-bit type source
|
||||
* and a 32-bit destination. A 2 component .xy 64-bit vector on SIMD8
|
||||
* would be:
|
||||
*
|
||||
* | x1l x1h | x2l x2h | x3l x3h | x4l x4h |
|
||||
* | x5l x5h | x6l x6h | x7l x7h | x8l x8h |
|
||||
* | y1l y1h | y2l y2h | y3l y3h | y4l y4h |
|
||||
* | y5l y5h | y6l y6h | y7l y7h | y8l y8h |
|
||||
*
|
||||
* The returned result would be the following 4 32-bit components unshuffled:
|
||||
*
|
||||
* | x1l | x2l | x3l | x4l | x5l | x6l | x7l | x8l |
|
||||
* | x1h | x2h | x3h | x4h | x5h | x6h | x7h | x8h |
|
||||
* | y1l | y2l | y3l | y4l | y5l | y6l | y7l | y8l |
|
||||
* | y1h | y2h | y3h | y4h | y5h | y6h | y7h | y8h |
|
||||
*
|
||||
* - Source and destination register must not be overlapped.
|
||||
* - components units are measured in terms of the smaller type between
|
||||
* source and destination because we are un/shuffling the smaller
|
||||
* components from/into the bigger ones.
|
||||
* - first_component parameter allows skipping source components.
|
||||
*/
|
||||
void
|
||||
shuffle_src_to_dst(const brw_builder &bld,
|
||||
const brw_reg &dst,
|
||||
const brw_reg &src,
|
||||
uint32_t first_component,
|
||||
uint32_t components)
|
||||
{
|
||||
if (brw_type_size_bytes(src.type) == brw_type_size_bytes(dst.type)) {
|
||||
assert(!regions_overlap(dst,
|
||||
brw_type_size_bytes(dst.type) * bld.dispatch_width() * components,
|
||||
offset(src, bld, first_component),
|
||||
brw_type_size_bytes(src.type) * bld.dispatch_width() * components));
|
||||
for (unsigned i = 0; i < components; i++) {
|
||||
bld.MOV(retype(offset(dst, bld, i), src.type),
|
||||
offset(src, bld, i + first_component));
|
||||
}
|
||||
} else if (brw_type_size_bytes(src.type) < brw_type_size_bytes(dst.type)) {
|
||||
/* Source is shuffled into destination */
|
||||
unsigned size_ratio = brw_type_size_bytes(dst.type) / brw_type_size_bytes(src.type);
|
||||
assert(!regions_overlap(dst,
|
||||
brw_type_size_bytes(dst.type) * bld.dispatch_width() *
|
||||
DIV_ROUND_UP(components, size_ratio),
|
||||
offset(src, bld, first_component),
|
||||
brw_type_size_bytes(src.type) * bld.dispatch_width() * components));
|
||||
|
||||
brw_reg_type shuffle_type =
|
||||
brw_type_with_size(BRW_TYPE_D, brw_type_size_bits(src.type));
|
||||
for (unsigned i = 0; i < components; i++) {
|
||||
brw_reg shuffle_component_i =
|
||||
subscript(offset(dst, bld, i / size_ratio),
|
||||
shuffle_type, i % size_ratio);
|
||||
bld.MOV(shuffle_component_i,
|
||||
retype(offset(src, bld, i + first_component), shuffle_type));
|
||||
}
|
||||
} else {
|
||||
/* Source is unshuffled into destination */
|
||||
unsigned size_ratio = brw_type_size_bytes(src.type) / brw_type_size_bytes(dst.type);
|
||||
assert(!regions_overlap(dst,
|
||||
brw_type_size_bytes(dst.type) * bld.dispatch_width() * components,
|
||||
offset(src, bld, first_component / size_ratio),
|
||||
brw_type_size_bytes(src.type) * bld.dispatch_width() *
|
||||
DIV_ROUND_UP(components + (first_component % size_ratio),
|
||||
size_ratio)));
|
||||
|
||||
brw_reg_type shuffle_type =
|
||||
brw_type_with_size(BRW_TYPE_D, brw_type_size_bits(dst.type));
|
||||
for (unsigned i = 0; i < components; i++) {
|
||||
brw_reg shuffle_component_i =
|
||||
subscript(offset(src, bld, (first_component + i) / size_ratio),
|
||||
shuffle_type, (first_component + i) % size_ratio);
|
||||
bld.MOV(retype(offset(dst, bld, i), shuffle_type),
|
||||
shuffle_component_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shuffle_from_32bit_read(const brw_builder &bld,
|
||||
const brw_reg &dst,
|
||||
const brw_reg &src,
|
||||
uint32_t first_component,
|
||||
uint32_t components)
|
||||
{
|
||||
assert(brw_type_size_bytes(src.type) == 4);
|
||||
|
||||
/* This function takes components in units of the destination type while
|
||||
* shuffle_src_to_dst takes components in units of the smallest type
|
||||
*/
|
||||
if (brw_type_size_bytes(dst.type) > 4) {
|
||||
assert(brw_type_size_bytes(dst.type) == 8);
|
||||
first_component *= 2;
|
||||
components *= 2;
|
||||
}
|
||||
|
||||
shuffle_src_to_dst(bld, dst, src, first_component, components);
|
||||
}
|
||||
|
||||
static void
|
||||
fs_nir_emit_instr(nir_to_brw_state &ntb, nir_instr *instr)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user