mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 16:30:10 +01:00
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:
parent
447879eb88
commit
bfbb0e84e1
4 changed files with 450 additions and 381 deletions
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
255
src/mesa/drivers/dri/i965/brw_ir_fs.h
Normal file
255
src/mesa/drivers/dri/i965/brw_ir_fs.h
Normal 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 ®) 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
|
||||
192
src/mesa/drivers/dri/i965/brw_ir_vec4.h
Normal file
192
src/mesa/drivers/dri/i965/brw_ir_vec4.h
Normal 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
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue