/* * Copyright © 2010 Intel Corporation * Copyright © 2011 Bryan Cain * Copyright © 2017 Gert Wollny * * 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 ST_GLSL_TO_TGSI_PRIVATE_H #define ST_GLSL_TO_TGSI_PRIVATE_H #include "mesa/main/mtypes.h" #include "program/prog_parameter.h" #include "compiler/glsl_types.h" #include "compiler/glsl/ir.h" #include "tgsi/tgsi_info.h" #include int swizzle_for_size(int size); class st_dst_reg; /** * This struct is a corresponding struct to TGSI ureg_src. */ class st_src_reg { public: st_src_reg(gl_register_file file, int index, const glsl_type *type, int component = 0, unsigned array_id = 0); st_src_reg(gl_register_file file, int index, enum glsl_base_type type); st_src_reg(gl_register_file file, int index, enum glsl_base_type type, int index2D); st_src_reg(); st_src_reg(const st_src_reg ®); void operator=(const st_src_reg ®); void reset(); explicit st_src_reg(st_dst_reg reg); st_src_reg get_abs(); int32_t index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */ int16_t index2D; uint16_t swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ int negate:4; /**< NEGATE_XYZW mask from mesa */ unsigned abs:1; enum glsl_base_type type:6; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ unsigned has_index2:1; gl_register_file file:5; /**< PROGRAM_* from Mesa */ /* * Is this the second half of a double register pair? * currently used for input mapping only. */ unsigned double_reg2:1; unsigned is_double_vertex_input:1; unsigned array_id:10; /** Register index should be offset by the integer in this reg. */ st_src_reg *reladdr; st_src_reg *reladdr2; bool is_legal_tgsi_address_operand() const { /* 2D registers can't be used as an address operand, or if the address * operand itself is a result of indirect addressing. */ return (type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT) && !has_index2 && !reladdr && !reladdr2; } }; bool operator == (const st_src_reg& lhs, const st_src_reg& rhs); std::ostream& operator << (std::ostream& os, const st_src_reg& reg); class st_dst_reg { public: st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index); st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type); st_dst_reg(); st_dst_reg(const st_dst_reg ®); void operator=(const st_dst_reg ®); explicit st_dst_reg(st_src_reg reg); int32_t index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */ int16_t index2D; gl_register_file file:5; /**< PROGRAM_* from Mesa */ unsigned writemask:4; /**< Bitfield of WRITEMASK_[XYZW] */ enum glsl_base_type type:6; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ unsigned has_index2:1; unsigned array_id:10; /** Register index should be offset by the integer in this reg. */ st_src_reg *reladdr; st_src_reg *reladdr2; }; bool operator == (const st_dst_reg& lhs, const st_dst_reg& rhs); std::ostream& operator << (std::ostream& os, const st_dst_reg& reg); class glsl_to_tgsi_instruction : public exec_node { public: DECLARE_RALLOC_CXX_OPERATORS(glsl_to_tgsi_instruction) st_dst_reg dst[2]; st_src_reg src[4]; st_src_reg resource; /**< sampler or buffer register */ st_src_reg *tex_offsets; /** Pointer to the ir source this tree came fe02549fdrom for debugging */ ir_instruction *ir; enum tgsi_opcode op:10; /**< TGSI opcode */ unsigned precise:1; unsigned saturate:1; unsigned is_64bit_expanded:1; unsigned sampler_base:5; unsigned sampler_array_size:6; /**< 1-based size of sampler array, 1 if not array */ gl_texture_index tex_target:5; glsl_base_type tex_type:6; unsigned tex_shadow:1; enum pipe_format image_format:10; unsigned tex_offset_num_offset:3; unsigned dead_mask:4; /**< Used in dead code elimination */ unsigned buffer_access:3; /**< bitmask of TGSI_MEMORY_x bits */ unsigned read_only:1; const struct tgsi_opcode_info *info; void print(std::ostream& os) const; }; inline std::ostream& operator << (std::ostream& os, const glsl_to_tgsi_instruction& instr) { instr.print(os); return os; } struct rename_reg_pair { bool valid; int new_reg; }; inline static bool is_resource_instruction(unsigned opcode) { switch (opcode) { case TGSI_OPCODE_RESQ: case TGSI_OPCODE_LOAD: case TGSI_OPCODE_ATOMUADD: case TGSI_OPCODE_ATOMXCHG: case TGSI_OPCODE_ATOMCAS: case TGSI_OPCODE_ATOMAND: case TGSI_OPCODE_ATOMOR: case TGSI_OPCODE_ATOMXOR: case TGSI_OPCODE_ATOMUMIN: case TGSI_OPCODE_ATOMUMAX: case TGSI_OPCODE_ATOMIMIN: case TGSI_OPCODE_ATOMIMAX: case TGSI_OPCODE_ATOMFADD: case TGSI_OPCODE_IMG2HND: return true; default: return false; } } inline static unsigned num_inst_dst_regs(const glsl_to_tgsi_instruction *op) { return op->info->num_dst; } inline static unsigned num_inst_src_regs(const glsl_to_tgsi_instruction *op) { return op->info->is_tex || is_resource_instruction(op->op) ? op->info->num_src - 1 : op->info->num_src; } #endif