From bfbb0e84e11e06af3d751701f157a21915976ca1 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 6 Feb 2015 01:11:18 +0200 Subject: [PATCH] i965: Move IR object definitions to separate header files. One should be able to manipulate i965 IR without pulling the whole FS/VEC4 visitor classes -- Optimization passes and other transformations would ideally be visitor-agnostic. Among other issues this avoids a circular dependency between the header file where such visitor-agnostic code will be defined and the main FS/VEC4 header where both IR (layer below) and visitor (layer above) happen to be defined. Reviewed-by: Matt Turner --- src/mesa/drivers/dri/i965/brw_fs.h | 226 +-------------------- src/mesa/drivers/dri/i965/brw_ir_fs.h | 255 ++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_ir_vec4.h | 192 ++++++++++++++++++ src/mesa/drivers/dri/i965/brw_vec4.h | 158 +-------------- 4 files changed, 450 insertions(+), 381 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/brw_ir_fs.h create mode 100644 src/mesa/drivers/dri/i965/brw_ir_vec4.h diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 2c9b705c07b..a90b12b2522 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -28,6 +28,7 @@ #pragma once #include "brw_shader.h" +#include "brw_ir_fs.h" extern "C" { @@ -64,231 +65,6 @@ namespace brw { class fs_live_variables; } -class fs_inst; -class fs_visitor; - -class fs_reg : public backend_reg { -public: - DECLARE_RALLOC_CXX_OPERATORS(fs_reg) - - void init(); - - fs_reg(); - explicit fs_reg(float f); - explicit fs_reg(int32_t i); - explicit fs_reg(uint32_t u); - explicit fs_reg(uint8_t vf[4]); - explicit fs_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3); - fs_reg(struct brw_reg fixed_hw_reg); - fs_reg(enum register_file file, int reg); - fs_reg(enum register_file file, int reg, enum brw_reg_type type); - fs_reg(enum register_file file, int reg, enum brw_reg_type type, uint8_t width); - - bool equals(const fs_reg &r) const; - bool is_contiguous() const; - - /** Smear a channel of the reg to all channels. */ - fs_reg &set_smear(unsigned subreg); - - /** - * Offset in bytes from the start of the register. Values up to a - * backend_reg::reg_offset unit are valid. - */ - int subreg_offset; - - fs_reg *reladdr; - - /** - * The register width. This indicates how many hardware values are - * represented by each virtual value. Valid values are 1, 8, or 16. - * For immediate values, this is 1. Most of the rest of the time, it - * will be equal to the dispatch width. - */ - uint8_t width; - - /** - * Returns the effective register width when used as a source in the - * given instruction. Registers such as uniforms and immediates - * effectively take on the width of the instruction in which they are - * used. - */ - uint8_t effective_width; - - /** Register region horizontal stride */ - uint8_t stride; -}; - -static inline fs_reg -negate(fs_reg reg) -{ - assert(reg.file != HW_REG && reg.file != IMM); - reg.negate = !reg.negate; - return reg; -} - -static inline fs_reg -retype(fs_reg reg, enum brw_reg_type type) -{ - reg.fixed_hw_reg.type = reg.type = type; - return reg; -} - -static inline fs_reg -byte_offset(fs_reg reg, unsigned delta) -{ - switch (reg.file) { - case BAD_FILE: - break; - case GRF: - case ATTR: - reg.reg_offset += delta / 32; - break; - case MRF: - reg.reg += delta / 32; - break; - default: - assert(delta == 0); - } - reg.subreg_offset += delta % 32; - return reg; -} - -static inline fs_reg -horiz_offset(fs_reg reg, unsigned delta) -{ - switch (reg.file) { - case BAD_FILE: - case UNIFORM: - case IMM: - /* These only have a single component that is implicitly splatted. A - * horizontal offset should be a harmless no-op. - */ - break; - case GRF: - case MRF: - case ATTR: - return byte_offset(reg, delta * reg.stride * type_sz(reg.type)); - default: - assert(delta == 0); - } - return reg; -} - -static inline fs_reg -offset(fs_reg reg, unsigned delta) -{ - assert(reg.stride > 0); - switch (reg.file) { - case BAD_FILE: - break; - case GRF: - case MRF: - case ATTR: - return byte_offset(reg, delta * reg.width * reg.stride * type_sz(reg.type)); - case UNIFORM: - reg.reg_offset += delta; - break; - default: - assert(delta == 0); - } - return reg; -} - -static inline fs_reg -component(fs_reg reg, unsigned idx) -{ - assert(reg.subreg_offset == 0); - assert(idx < reg.width); - reg.subreg_offset = idx * type_sz(reg.type); - reg.width = 1; - return reg; -} - -/** - * Get either of the 8-component halves of a 16-component register. - * - * Note: this also works if \c reg represents a SIMD16 pair of registers. - */ -static inline fs_reg -half(fs_reg reg, unsigned idx) -{ - assert(idx < 2); - - if (reg.file == UNIFORM) - return reg; - - assert(idx == 0 || (reg.file != HW_REG && reg.file != IMM)); - assert(reg.width == 16); - reg.width = 8; - return horiz_offset(reg, 8 * idx); -} - -static const fs_reg reg_undef; - -class fs_inst : public backend_instruction { - fs_inst &operator=(const fs_inst &); - - void init(enum opcode opcode, uint8_t exec_width, const fs_reg &dst, - fs_reg *src, int sources); - -public: - DECLARE_RALLOC_CXX_OPERATORS(fs_inst) - - fs_inst(); - fs_inst(enum opcode opcode, uint8_t exec_size); - fs_inst(enum opcode opcode, const fs_reg &dst); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - const fs_reg &src0); - fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - const fs_reg &src0, const fs_reg &src1); - fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0, - const fs_reg &src1); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - const fs_reg &src0, const fs_reg &src1, const fs_reg &src2); - fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0, - const fs_reg &src1, const fs_reg &src2); - fs_inst(enum opcode opcode, const fs_reg &dst, fs_reg src[], int sources); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - fs_reg src[], int sources); - fs_inst(const fs_inst &that); - - void resize_sources(uint8_t num_sources); - - bool equals(fs_inst *inst) const; - bool overwrites_reg(const fs_reg ®) const; - bool is_send_from_grf() const; - bool is_partial_write() const; - int regs_read(fs_visitor *v, int arg) const; - bool can_do_source_mods(struct brw_context *brw); - - bool reads_flag() const; - bool writes_flag() const; - - fs_reg dst; - fs_reg *src; - - uint8_t sources; /**< Number of fs_reg sources. */ - - /** - * Execution size of the instruction. This is used by the generator to - * generate the correct binary for the given fs_inst. Current valid - * values are 1, 8, 16. - */ - uint8_t exec_size; - - /* Chooses which flag subregister (f0.0 or f0.1) is used for conditional - * mod and predication. - */ - uint8_t flag_subreg; - - uint8_t regs_written; /**< Number of vgrfs written by a SEND message, or 1 */ - bool eot:1; - bool force_uncompressed:1; - bool force_sechalf:1; - bool pi_noperspective:1; /**< Pixel interpolator noperspective flag */ -}; - /** * The fragment shader front-end. * diff --git a/src/mesa/drivers/dri/i965/brw_ir_fs.h b/src/mesa/drivers/dri/i965/brw_ir_fs.h new file mode 100644 index 00000000000..2369834a059 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_ir_fs.h @@ -0,0 +1,255 @@ +/* -*- c++ -*- */ +/* + * Copyright © 2010-2015 Intel Corporation + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef BRW_IR_FS_H +#define BRW_IR_FS_H + +#include "brw_shader.h" + +class fs_inst; +class fs_visitor; + +class fs_reg : public backend_reg { +public: + DECLARE_RALLOC_CXX_OPERATORS(fs_reg) + + void init(); + + fs_reg(); + explicit fs_reg(float f); + explicit fs_reg(int32_t i); + explicit fs_reg(uint32_t u); + explicit fs_reg(uint8_t vf[4]); + explicit fs_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3); + fs_reg(struct brw_reg fixed_hw_reg); + fs_reg(enum register_file file, int reg); + fs_reg(enum register_file file, int reg, enum brw_reg_type type); + fs_reg(enum register_file file, int reg, enum brw_reg_type type, uint8_t width); + + bool equals(const fs_reg &r) const; + bool is_contiguous() const; + + /** Smear a channel of the reg to all channels. */ + fs_reg &set_smear(unsigned subreg); + + /** + * Offset in bytes from the start of the register. Values up to a + * backend_reg::reg_offset unit are valid. + */ + int subreg_offset; + + fs_reg *reladdr; + + /** + * The register width. This indicates how many hardware values are + * represented by each virtual value. Valid values are 1, 8, or 16. + * For immediate values, this is 1. Most of the rest of the time, it + * will be equal to the dispatch width. + */ + uint8_t width; + + /** + * Returns the effective register width when used as a source in the + * given instruction. Registers such as uniforms and immediates + * effectively take on the width of the instruction in which they are + * used. + */ + uint8_t effective_width; + + /** Register region horizontal stride */ + uint8_t stride; +}; + +static inline fs_reg +negate(fs_reg reg) +{ + assert(reg.file != HW_REG && reg.file != IMM); + reg.negate = !reg.negate; + return reg; +} + +static inline fs_reg +retype(fs_reg reg, enum brw_reg_type type) +{ + reg.fixed_hw_reg.type = reg.type = type; + return reg; +} + +static inline fs_reg +byte_offset(fs_reg reg, unsigned delta) +{ + switch (reg.file) { + case BAD_FILE: + break; + case GRF: + case ATTR: + reg.reg_offset += delta / 32; + break; + case MRF: + reg.reg += delta / 32; + break; + default: + assert(delta == 0); + } + reg.subreg_offset += delta % 32; + return reg; +} + +static inline fs_reg +horiz_offset(fs_reg reg, unsigned delta) +{ + switch (reg.file) { + case BAD_FILE: + case UNIFORM: + case IMM: + /* These only have a single component that is implicitly splatted. A + * horizontal offset should be a harmless no-op. + */ + break; + case GRF: + case MRF: + case ATTR: + return byte_offset(reg, delta * reg.stride * type_sz(reg.type)); + default: + assert(delta == 0); + } + return reg; +} + +static inline fs_reg +offset(fs_reg reg, unsigned delta) +{ + assert(reg.stride > 0); + switch (reg.file) { + case BAD_FILE: + break; + case GRF: + case MRF: + case ATTR: + return byte_offset(reg, delta * reg.width * reg.stride * type_sz(reg.type)); + case UNIFORM: + reg.reg_offset += delta; + break; + default: + assert(delta == 0); + } + return reg; +} + +static inline fs_reg +component(fs_reg reg, unsigned idx) +{ + assert(reg.subreg_offset == 0); + assert(idx < reg.width); + reg.subreg_offset = idx * type_sz(reg.type); + reg.width = 1; + return reg; +} + +/** + * Get either of the 8-component halves of a 16-component register. + * + * Note: this also works if \c reg represents a SIMD16 pair of registers. + */ +static inline fs_reg +half(fs_reg reg, unsigned idx) +{ + assert(idx < 2); + + if (reg.file == UNIFORM) + return reg; + + assert(idx == 0 || (reg.file != HW_REG && reg.file != IMM)); + assert(reg.width == 16); + reg.width = 8; + return horiz_offset(reg, 8 * idx); +} + +static const fs_reg reg_undef; + +class fs_inst : public backend_instruction { + fs_inst &operator=(const fs_inst &); + + void init(enum opcode opcode, uint8_t exec_width, const fs_reg &dst, + fs_reg *src, int sources); + +public: + DECLARE_RALLOC_CXX_OPERATORS(fs_inst) + + fs_inst(); + fs_inst(enum opcode opcode, uint8_t exec_size); + fs_inst(enum opcode opcode, const fs_reg &dst); + fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, + const fs_reg &src0); + fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0); + fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, + const fs_reg &src0, const fs_reg &src1); + fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0, + const fs_reg &src1); + fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, + const fs_reg &src0, const fs_reg &src1, const fs_reg &src2); + fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0, + const fs_reg &src1, const fs_reg &src2); + fs_inst(enum opcode opcode, const fs_reg &dst, fs_reg src[], int sources); + fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, + fs_reg src[], int sources); + fs_inst(const fs_inst &that); + + void resize_sources(uint8_t num_sources); + + bool equals(fs_inst *inst) const; + bool overwrites_reg(const fs_reg ®) const; + bool is_send_from_grf() const; + bool is_partial_write() const; + int regs_read(fs_visitor *v, int arg) const; + bool can_do_source_mods(struct brw_context *brw); + + bool reads_flag() const; + bool writes_flag() const; + + fs_reg dst; + fs_reg *src; + + uint8_t sources; /**< Number of fs_reg sources. */ + + /** + * Execution size of the instruction. This is used by the generator to + * generate the correct binary for the given fs_inst. Current valid + * values are 1, 8, 16. + */ + uint8_t exec_size; + + /* Chooses which flag subregister (f0.0 or f0.1) is used for conditional + * mod and predication. + */ + uint8_t flag_subreg; + + uint8_t regs_written; /**< Number of vgrfs written by a SEND message, or 1 */ + bool eot:1; + bool force_uncompressed:1; + bool force_sechalf:1; + bool pi_noperspective:1; /**< Pixel interpolator noperspective flag */ +}; + +#endif diff --git a/src/mesa/drivers/dri/i965/brw_ir_vec4.h b/src/mesa/drivers/dri/i965/brw_ir_vec4.h new file mode 100644 index 00000000000..fd0e78e0729 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_ir_vec4.h @@ -0,0 +1,192 @@ +/* -*- c++ -*- */ +/* + * Copyright © 2011-2015 Intel Corporation + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef BRW_IR_VEC4_H +#define BRW_IR_VEC4_H + +#include "brw_shader.h" +#include "brw_context.h" + +namespace brw { + +class dst_reg; +class vec4_visitor; + +unsigned +swizzle_for_size(int size); + +class src_reg : public backend_reg +{ +public: + DECLARE_RALLOC_CXX_OPERATORS(src_reg) + + void init(); + + src_reg(register_file file, int reg, const glsl_type *type); + src_reg(); + src_reg(float f); + src_reg(uint32_t u); + src_reg(int32_t i); + src_reg(uint8_t vf[4]); + src_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3); + src_reg(struct brw_reg reg); + + bool equals(const src_reg &r) const; + + src_reg(class vec4_visitor *v, const struct glsl_type *type); + src_reg(class vec4_visitor *v, const struct glsl_type *type, int size); + + explicit src_reg(dst_reg reg); + + GLuint swizzle; /**< BRW_SWIZZLE_XYZW macros from brw_reg.h. */ + + src_reg *reladdr; +}; + +static inline src_reg +retype(src_reg reg, enum brw_reg_type type) +{ + reg.fixed_hw_reg.type = reg.type = type; + return reg; +} + +static inline src_reg +offset(src_reg reg, unsigned delta) +{ + assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM)); + reg.reg_offset += delta; + return reg; +} + +/** + * Reswizzle a given source register. + * \sa brw_swizzle(). + */ +static inline src_reg +swizzle(src_reg reg, unsigned swizzle) +{ + assert(reg.file != HW_REG); + reg.swizzle = BRW_SWIZZLE4( + BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 0)), + BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 1)), + BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 2)), + BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 3))); + return reg; +} + +static inline src_reg +negate(src_reg reg) +{ + assert(reg.file != HW_REG && reg.file != IMM); + reg.negate = !reg.negate; + return reg; +} + +class dst_reg : public backend_reg +{ +public: + DECLARE_RALLOC_CXX_OPERATORS(dst_reg) + + void init(); + + dst_reg(); + dst_reg(register_file file, int reg); + dst_reg(register_file file, int reg, const glsl_type *type, int writemask); + dst_reg(struct brw_reg reg); + dst_reg(class vec4_visitor *v, const struct glsl_type *type); + + explicit dst_reg(src_reg reg); + + int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ + + src_reg *reladdr; +}; + +static inline dst_reg +retype(dst_reg reg, enum brw_reg_type type) +{ + reg.fixed_hw_reg.type = reg.type = type; + return reg; +} + +static inline dst_reg +offset(dst_reg reg, unsigned delta) +{ + assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM)); + reg.reg_offset += delta; + return reg; +} + +static inline dst_reg +writemask(dst_reg reg, unsigned mask) +{ + assert(reg.file != HW_REG && reg.file != IMM); + assert((reg.writemask & mask) != 0); + reg.writemask &= mask; + return reg; +} + +class vec4_instruction : public backend_instruction { +public: + DECLARE_RALLOC_CXX_OPERATORS(vec4_instruction) + + vec4_instruction(vec4_visitor *v, enum opcode opcode, + const dst_reg &dst = dst_reg(), + const src_reg &src0 = src_reg(), + const src_reg &src1 = src_reg(), + const src_reg &src2 = src_reg()); + + struct brw_reg get_dst(void); + struct brw_reg get_src(const struct brw_vue_prog_data *prog_data, int i); + + dst_reg dst; + src_reg src[3]; + + enum brw_urb_write_flags urb_write_flags; + + unsigned sol_binding; /**< gen6: SOL binding table index */ + bool sol_final_write; /**< gen6: send commit message */ + unsigned sol_vertex; /**< gen6: used for setting dst index in SVB header */ + + bool is_send_from_grf(); + bool can_reswizzle(int dst_writemask, int swizzle, int swizzle_mask); + void reswizzle(int dst_writemask, int swizzle); + bool can_do_source_mods(struct brw_context *brw); + + bool reads_flag() + { + return predicate || opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2; + } + + bool writes_flag() + { + return (conditional_mod && (opcode != BRW_OPCODE_SEL && + opcode != BRW_OPCODE_IF && + opcode != BRW_OPCODE_WHILE)); + } +}; + +} /* namespace brw */ + +#endif diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 6b710c9bc31..649dc6112b7 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -31,6 +31,8 @@ #include "brw_program.h" #ifdef __cplusplus +#include "brw_ir_vec4.h" + extern "C" { #endif @@ -63,164 +65,8 @@ brw_vue_setup_prog_key_for_precompile(struct gl_context *ctx, namespace brw { -class dst_reg; - class vec4_live_variables; -unsigned -swizzle_for_size(int size); - -class src_reg : public backend_reg -{ -public: - DECLARE_RALLOC_CXX_OPERATORS(src_reg) - - void init(); - - src_reg(register_file file, int reg, const glsl_type *type); - src_reg(); - src_reg(float f); - src_reg(uint32_t u); - src_reg(int32_t i); - src_reg(uint8_t vf[4]); - src_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3); - src_reg(struct brw_reg reg); - - bool equals(const src_reg &r) const; - - src_reg(class vec4_visitor *v, const struct glsl_type *type); - src_reg(class vec4_visitor *v, const struct glsl_type *type, int size); - - explicit src_reg(dst_reg reg); - - GLuint swizzle; /**< BRW_SWIZZLE_XYZW macros from brw_reg.h. */ - - src_reg *reladdr; -}; - -static inline src_reg -retype(src_reg reg, enum brw_reg_type type) -{ - reg.fixed_hw_reg.type = reg.type = type; - return reg; -} - -static inline src_reg -offset(src_reg reg, unsigned delta) -{ - assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM)); - reg.reg_offset += delta; - return reg; -} - -/** - * Reswizzle a given source register. - * \sa brw_swizzle(). - */ -static inline src_reg -swizzle(src_reg reg, unsigned swizzle) -{ - assert(reg.file != HW_REG); - reg.swizzle = BRW_SWIZZLE4( - BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 0)), - BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 1)), - BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 2)), - BRW_GET_SWZ(reg.swizzle, BRW_GET_SWZ(swizzle, 3))); - return reg; -} - -static inline src_reg -negate(src_reg reg) -{ - assert(reg.file != HW_REG && reg.file != IMM); - reg.negate = !reg.negate; - return reg; -} - -class dst_reg : public backend_reg -{ -public: - DECLARE_RALLOC_CXX_OPERATORS(dst_reg) - - void init(); - - dst_reg(); - dst_reg(register_file file, int reg); - dst_reg(register_file file, int reg, const glsl_type *type, int writemask); - dst_reg(struct brw_reg reg); - dst_reg(class vec4_visitor *v, const struct glsl_type *type); - - explicit dst_reg(src_reg reg); - - int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ - - src_reg *reladdr; -}; - -static inline dst_reg -retype(dst_reg reg, enum brw_reg_type type) -{ - reg.fixed_hw_reg.type = reg.type = type; - return reg; -} - -static inline dst_reg -offset(dst_reg reg, unsigned delta) -{ - assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM)); - reg.reg_offset += delta; - return reg; -} - -static inline dst_reg -writemask(dst_reg reg, unsigned mask) -{ - assert(reg.file != HW_REG && reg.file != IMM); - assert((reg.writemask & mask) != 0); - reg.writemask &= mask; - return reg; -} - -class vec4_instruction : public backend_instruction { -public: - DECLARE_RALLOC_CXX_OPERATORS(vec4_instruction) - - vec4_instruction(vec4_visitor *v, enum opcode opcode, - const dst_reg &dst = dst_reg(), - const src_reg &src0 = src_reg(), - const src_reg &src1 = src_reg(), - const src_reg &src2 = src_reg()); - - struct brw_reg get_dst(void); - struct brw_reg get_src(const struct brw_vue_prog_data *prog_data, int i); - - dst_reg dst; - src_reg src[3]; - - enum brw_urb_write_flags urb_write_flags; - - unsigned sol_binding; /**< gen6: SOL binding table index */ - bool sol_final_write; /**< gen6: send commit message */ - unsigned sol_vertex; /**< gen6: used for setting dst index in SVB header */ - - bool is_send_from_grf(); - bool can_reswizzle(int dst_writemask, int swizzle, int swizzle_mask); - void reswizzle(int dst_writemask, int swizzle); - bool can_do_source_mods(struct brw_context *brw); - - bool reads_flag() - { - return predicate || opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2; - } - - bool writes_flag() - { - return (conditional_mod && (opcode != BRW_OPCODE_SEL && - opcode != BRW_OPCODE_IF && - opcode != BRW_OPCODE_WHILE)); - } -}; - /** * The vertex shader front-end. * -- 2.30.2