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 <mattst88@gmail.com>
This commit is contained in:
Francisco Jerez 2015-02-06 01:11:18 +02:00
parent 447879eb88
commit bfbb0e84e1
4 changed files with 450 additions and 381 deletions

View file

@ -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 &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.
*

View file

@ -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 &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

View file

@ -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

View file

@ -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.
*