Francisco Jerez <curroje...@riseup.net> writes: > This is not a real IR in the sense of a long-lived representation of > the program. An SVEC4 instruction, defined as an opcode operating on > 4-vectors of FS registers, is broken up into its scalar components > (each an fs_inst) as soon as it's emitted. The svec4_inst object is a > convenient way to carry around the expanded FS instructions and apply > some transformations on them (using the back-end-independent exec_*() > API introduced by a future commit). > > A src_svec4 register is a vector of FS registers with its components > ordered according to a swizzle, and a dst_svec4 register is a subset > of vector components used as destination of some vector operation, > pretty much like the source and destination registers of the VEC4 > back-end. > > On the one hand this simplifies the translation of VEC4 higher level > languages (e.g. GLSL IR) and VEC4-centric APIs > (e.g. ARB_shader_image_load_store) into the scalar i965 back-end IR, > and on the other hand it can greatly reduce the amount of duplication > between back-ends, as it provides an interface to generate scalar IR > with semantics consistent with the VEC4 IR interface. > > This patch only defines the essential data structures of the SVEC4 > pseudo-IR. The interface to construct, scalarize and emit SVEC4 > instructions will be introduced in a future commit. > --- > src/mesa/drivers/dri/i965/Makefile.sources | 1 + > src/mesa/drivers/dri/i965/brw_ir_svec4.h | 296 > +++++++++++++++++++++++++++++ > src/mesa/drivers/dri/i965/brw_ir_vec4.h | 18 ++ > 3 files changed, 315 insertions(+) > create mode 100644 src/mesa/drivers/dri/i965/brw_ir_svec4.h > > diff --git a/src/mesa/drivers/dri/i965/Makefile.sources > b/src/mesa/drivers/dri/i965/Makefile.sources > index 6d4659f..83acbd0 100644 > --- a/src/mesa/drivers/dri/i965/Makefile.sources > +++ b/src/mesa/drivers/dri/i965/Makefile.sources > @@ -66,6 +66,7 @@ i965_FILES = \ > brw_interpolation_map.c \ > brw_ir_allocator.h \ > brw_ir_fs.h \ > + brw_ir_svec4.h \ > brw_ir_vec4.h \ > brw_lower_texture_gradients.cpp \ > brw_lower_unnormalized_offset.cpp \ > diff --git a/src/mesa/drivers/dri/i965/brw_ir_svec4.h > b/src/mesa/drivers/dri/i965/brw_ir_svec4.h > new file mode 100644 > index 0000000..d1eafdd > --- /dev/null > +++ b/src/mesa/drivers/dri/i965/brw_ir_svec4.h > @@ -0,0 +1,296 @@ > +/* -*- c++ -*- */ > +/* > + * Copyright © 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_SVEC4_H > +#define BRW_IR_SVEC4_H > + > +#include "brw_ir_fs.h" > + > +namespace brw { > + class dst_svec4; > + > + /** > + * Source vector of one to four scalar FS registers. These are the > sources > + * of SVEC4 pseudo-instructions and provide VEC4-like semantics in the > + * scalar back-end with implicit scalarization. > + * > + * It inherits from fs_reg privately because there is an > + * implemented-in-terms-of relationship rather than an is-a relationship > + * (the Liskov substitution principle doesn't hold). > + */ > + class src_svec4 : private fs_reg {
Every product I've worked on has disallowed private inheritance as a policy. I'm surprised to see usage of such an obscure feature, because it seems like Mesa has a pretty limited subset of c++ that is used. If you need an implemented-in-terms-of relationship, it seems like composition should be used. One example of a public c++ style guide that disallows private inheritance: http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Inheritance > + public: > + src_svec4() : fs_reg(), swizzle(0) > + { > + } > + > + src_svec4(const fs_reg ®, unsigned swizzle = BRW_SWIZZLE_NOOP) : > + fs_reg(reg), swizzle(swizzle) > + { > + } > + > + src_svec4(float f) : fs_reg(f), swizzle(BRW_SWIZZLE_XXXX) > + { > + } > + > + src_svec4(int32_t i) : fs_reg(i), swizzle(BRW_SWIZZLE_XXXX) > + { > + } > + > + src_svec4(uint32_t u) : fs_reg(u), swizzle(BRW_SWIZZLE_XXXX) > + { > + } > + > + /** > + * Construct a source vector from a destination vector. > + */ > + inline > + src_svec4(const dst_svec4 ®); > + > + /** > + * Return the standard representation of this register in the IR. This > + * is basically an up-cast but it's exposed as a function to prevent > + * accidental casts which are unsafe in general. > + */ > + friend const fs_reg & > + repr(const src_svec4 ®) > + { > + return reg; > + } > + > + using fs_reg::is_null; > + using fs_reg::is_accumulator; > + using fs_reg::file; > + using fs_reg::type; > + using fs_reg::reg; > + using fs_reg::reg_offset; > + using fs_reg::fixed_hw_reg; > + using fs_reg::negate; > + using fs_reg::abs; > + using fs_reg::reladdr; > + > + unsigned swizzle; > + }; > + > + /** > + * Construct a source vector of \p n components starting from \p reg. > + */ > + inline src_svec4 > + src_vector(const fs_reg ®, unsigned n) > + { > + return src_svec4(reg, brw_swizzle_for_size(n)); > + } > + > + inline src_svec4 > + retype(src_svec4 reg, enum brw_reg_type type) > + { > + reg.fixed_hw_reg.type = reg.type = type; > + return reg; > + } > + > + inline src_svec4 > + offset(const src_svec4 ®, unsigned delta) > + { > + return src_svec4(offset(repr(reg), delta), reg.swizzle); > + } > + > + inline src_svec4 > + swizzle(src_svec4 reg, unsigned swizzle) > + { > + assert(reg.file != HW_REG); > + reg.swizzle = brw_compose_swizzle(swizzle, reg.swizzle); > + return reg; > + } > + > + inline src_svec4 > + negate(src_svec4 reg) > + { > + assert(reg.file != HW_REG && reg.file != IMM); > + reg.negate = !reg.negate; > + return reg; > + } > + > + /** > + * Return the i-th logical component of register \p reg. A logical > + * component is itself a vector with as many channels as the SIMD width of > + * \p reg. > + */ > + inline fs_reg > + component(const src_svec4 ®, unsigned i) > + { > + assert(i < 4); > + if (reg.is_null()) > + return repr(reg); > + else > + return offset(repr(reg), BRW_GET_SWZ(reg.swizzle, i)); > + } > + > + /** > + * Return a register with the first \p n components of \p reg. > + */ > + inline src_svec4 > + resize(const src_svec4 ®, unsigned n) > + { > + return swizzle(reg, brw_swizzle_for_size(n)); > + } > + > + /** > + * Destination vector of one to four scalar FS registers. This is the > + * destination of an SVEC4 pseudo-instruction and provides VEC4-like > + * semantics in the scalar back-end with implicit scalarization. > + * > + * \sa brw::src_svec4 > + */ > + class dst_svec4 : private fs_reg { > + public: > + dst_svec4() : fs_reg(), writemask(0) > + { > + } > + > + dst_svec4(const fs_reg ®, unsigned writemask = WRITEMASK_XYZW) : > + fs_reg(reg), writemask(writemask) > + { > + } > + > + /** > + * Construct a destination vector from a source vector. Marked > explicit > + * because the swizzle-to-writemask conversion is many-to-one and loses > + * information about the ordering of components. > + */ > + explicit > + dst_svec4(const src_svec4 ®) : > + fs_reg(repr(reg)), > + writemask(brw_mask_for_swizzle(reg.swizzle)) > + { > + } > + > + /** > + * Return the standard representation of this register in the IR. This > + * is basically an up-cast but it's exposed as a function to prevent > + * accidental casts which are unsafe in general. > + */ > + friend const fs_reg & > + repr(const dst_svec4 ®) > + { > + return reg; > + } > + > + using fs_reg::is_null; > + using fs_reg::is_accumulator; > + using fs_reg::file; > + using fs_reg::type; > + using fs_reg::reg; > + using fs_reg::reg_offset; > + using fs_reg::fixed_hw_reg; > + using fs_reg::negate; > + using fs_reg::abs; > + using fs_reg::reladdr; > + > + unsigned writemask; > + }; > + > + /** > + * Construct a destination vector of \p n components starting from \p reg. > + */ > + inline dst_svec4 > + dst_vector(const fs_reg ®, unsigned n) > + { > + return dst_svec4(reg, (1 << n) - 1); > + } > + > + inline dst_svec4 > + retype(dst_svec4 reg, enum brw_reg_type type) > + { > + reg.fixed_hw_reg.type = reg.type = type; > + return reg; > + } > + > + inline dst_svec4 > + offset(const dst_svec4 ®, unsigned delta) > + { > + return dst_svec4(offset(repr(reg), delta), reg.writemask); > + } > + > + inline dst_svec4 > + writemask(dst_svec4 reg, unsigned mask) > + { > + assert(reg.file != HW_REG && reg.file != IMM); > + reg.writemask &= mask; > + return reg; > + } > + > + /** > + * Return the i-th logical component of register \p reg. A logical > + * component is itself a vector with as many channels as the SIMD width of > + * \p reg. > + */ > + inline fs_reg > + component(const dst_svec4 ®, unsigned i) > + { > + assert(reg.writemask & (1 << i)); > + if (reg.is_null()) > + return repr(reg); > + else > + return offset(repr(reg), i); > + } > + > + /** > + * Return a register with the first \p n components of \p reg. > + */ > + inline dst_svec4 > + resize(dst_svec4 reg, unsigned n) > + { > + return writemask(reg, (1 << n) - 1); > + } > + > + src_svec4::src_svec4(const dst_svec4 ®) : > + fs_reg(repr(reg)), > + swizzle(brw_swizzle_for_mask(reg.writemask)) > + { > + } > + > + /** > + * Vector of scalar FS instructions. It represents a vector operation > that > + * has been expanded to its scalar components. The interface provided > + * through the exec_*() helpers is intended to be compatible with its VEC4 > + * counterpart in order to enable generic FS/VEC4 programming. > + */ > + class svec4_inst { > + private: > + svec4_inst(const svec4_inst &inst); > + svec4_inst & > + operator=(svec4_inst inst); > + > + public: > + DECLARE_RALLOC_CXX_OPERATORS(svec4_inst) > + > + svec4_inst() : v() > + { > + } > + > + fs_inst *v[4]; > + }; > +} > + > +#endif > diff --git a/src/mesa/drivers/dri/i965/brw_ir_vec4.h > b/src/mesa/drivers/dri/i965/brw_ir_vec4.h > index 7bb9459..9deb694 100644 > --- a/src/mesa/drivers/dri/i965/brw_ir_vec4.h > +++ b/src/mesa/drivers/dri/i965/brw_ir_vec4.h > @@ -114,6 +114,15 @@ resize(const src_reg ®, unsigned n) > return swizzle(reg, brw_swizzle_for_size(n)); > } > > +/** > + * Construct a source vector of \p n components starting from \p reg. > + */ > +static inline src_reg > +src_vector(const src_reg ®, unsigned n) > +{ > + return resize(reg, n); > +} > + > static inline bool > is_uniform(const src_reg ®) > { > @@ -188,6 +197,15 @@ resize(const dst_reg ®, unsigned n) > return writemask(reg, (1 << n) - 1); > } > > +/** > + * Construct a destination vector of \p n components starting from \p reg. > + */ > +static inline dst_reg > +dst_vector(const src_reg ®, unsigned n) > +{ > + return resize(dst_reg(reg), n); > +} > + > class vec4_instruction : public backend_instruction { > public: > DECLARE_RALLOC_CXX_OPERATORS(vec4_instruction) > -- > 2.3.5 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev