| /********************************************************** |
| * Copyright 2008-2009 VMware, Inc. All rights reserved. |
| * |
| * 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 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 SVGA_TGSI_EMIT_H |
| #define SVGA_TGSI_EMIT_H |
| |
| #include "tgsi/tgsi_scan.h" |
| #include "svga_hw_reg.h" |
| #include "svga_shader.h" |
| #include "svga_tgsi.h" |
| #include "svga3d_shaderdefs.h" |
| |
| struct src_register |
| { |
| SVGA3dShaderSrcToken base; |
| SVGA3dShaderSrcToken indirect; |
| }; |
| |
| |
| struct svga_arl_consts |
| { |
| int number; |
| int idx; |
| int swizzle; |
| int arl_num; |
| }; |
| |
| |
| /** |
| * This is the context/state used during TGSI->SVGA shader translation. |
| */ |
| struct svga_shader_emitter |
| { |
| unsigned size; |
| char *buf; |
| char *ptr; |
| |
| struct svga_compile_key key; |
| struct tgsi_shader_info info; |
| int unit; |
| |
| int imm_start; |
| |
| int nr_hw_float_const; |
| int nr_hw_int_const; |
| int nr_hw_temp; |
| |
| int insn_offset; |
| |
| int internal_temp_count; |
| int internal_imm_count; |
| |
| int internal_color_idx[2]; /* diffuse, specular */ |
| int internal_color_count; |
| |
| boolean emitted_vface; |
| boolean emit_frontface; |
| int internal_frontface_idx; |
| |
| int ps30_input_count; |
| int vs30_output_count; |
| |
| int dynamic_branching_level; |
| |
| unsigned num_output_writes; |
| boolean constant_color_output; |
| |
| boolean in_main_func; |
| |
| boolean created_common_immediate; |
| int common_immediate_idx[2]; |
| |
| boolean created_loop_const; |
| int loop_const_idx; |
| |
| unsigned inverted_texcoords; /**< bitmask of which texcoords are flipped */ |
| struct src_register ps_true_texcoord[PIPE_MAX_ATTRIBS]; |
| struct src_register ps_inverted_texcoord[PIPE_MAX_ATTRIBS]; |
| unsigned ps_inverted_texcoord_input[PIPE_MAX_ATTRIBS]; |
| |
| unsigned label[32]; |
| unsigned nr_labels; |
| |
| /** input/output register mappings, indexed by register number */ |
| struct src_register input_map[PIPE_MAX_ATTRIBS]; |
| SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS]; |
| |
| boolean ps_reads_pos; |
| boolean emitted_depth_fog; |
| struct src_register ps_true_pos; |
| struct src_register ps_depth_pos; |
| SVGA3dShaderDestToken ps_temp_pos; |
| |
| /* shared input for depth and fog */ |
| struct src_register ps_depth_fog; |
| |
| struct src_register imm_0055; |
| SVGA3dShaderDestToken temp_pos; |
| SVGA3dShaderDestToken true_pos; |
| SVGA3dShaderDestToken depth_pos; |
| |
| /* shared output for depth and fog */ |
| SVGA3dShaderDestToken vs_depth_fog; |
| |
| /* PS output colors (indexed by color semantic index) */ |
| SVGA3dShaderDestToken temp_color_output[PIPE_MAX_COLOR_BUFS]; |
| SVGA3dShaderDestToken true_color_output[PIPE_MAX_COLOR_BUFS]; |
| |
| SVGA3dShaderDestToken temp_psiz; |
| SVGA3dShaderDestToken true_psiz; |
| |
| struct svga_arl_consts arl_consts[12]; |
| int num_arl_consts; |
| int current_arl; |
| |
| unsigned pstipple_sampler_unit; |
| |
| int num_samplers; |
| uint8_t sampler_target[PIPE_MAX_SAMPLERS]; |
| }; |
| |
| |
| boolean |
| svga_shader_emit_dword(struct svga_shader_emitter *emit, unsigned dword); |
| |
| boolean |
| svga_shader_emit_dwords(struct svga_shader_emitter *emit, |
| const unsigned *dwords, unsigned nr); |
| |
| boolean |
| svga_shader_emit_opcode(struct svga_shader_emitter *emit, |
| unsigned opcode); |
| |
| boolean |
| svga_shader_emit_instructions(struct svga_shader_emitter *emit, |
| const struct tgsi_token *tokens); |
| |
| boolean |
| svga_shader_emit_samplers_decl(struct svga_shader_emitter *emit); |
| |
| boolean |
| svga_translate_decl_sm30(struct svga_shader_emitter *emit, |
| const struct tgsi_full_declaration *decl); |
| |
| |
| #define TRANSLATE_SWIZZLE(x,y,z,w) ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6)) |
| #define SWIZZLE_XYZW \ |
| TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W) |
| #define SWIZZLE_XXXX \ |
| TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X) |
| #define SWIZZLE_YYYY \ |
| TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y) |
| #define SWIZZLE_ZZZZ \ |
| TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z) |
| #define SWIZZLE_WWWW \ |
| TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W) |
| |
| |
| /** Emit the given SVGA3dShaderInstToken opcode */ |
| static inline boolean |
| emit_instruction(struct svga_shader_emitter *emit, |
| SVGA3dShaderInstToken opcode) |
| { |
| return svga_shader_emit_opcode(emit, opcode.value); |
| } |
| |
| |
| /** Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode */ |
| static inline SVGA3dShaderInstToken |
| inst_token(SVGA3dShaderOpCodeType opcode) |
| { |
| SVGA3dShaderInstToken inst; |
| |
| inst.value = 0; |
| inst.op = opcode; |
| |
| return inst; |
| } |
| |
| |
| /** |
| * Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode |
| * with the predication flag set. |
| */ |
| static inline SVGA3dShaderInstToken |
| inst_token_predicated(SVGA3dShaderOpCodeType opcode) |
| { |
| SVGA3dShaderInstToken inst; |
| |
| inst.value = 0; |
| inst.op = opcode; |
| inst.predicated = 1; |
| |
| return inst; |
| } |
| |
| |
| /** |
| * Generate a SVGA3dShaderInstToken for a SETP instruction (set predicate) |
| * using the given comparison operator (one of SVGA3DOPCOMP_xx). |
| */ |
| static inline SVGA3dShaderInstToken |
| inst_token_setp(SVGA3dShaderOpCodeCompFnType operator) |
| { |
| SVGA3dShaderInstToken inst; |
| |
| inst.value = 0; |
| inst.op = SVGA3DOP_SETP; |
| inst.control = operator; |
| |
| return inst; |
| } |
| |
| |
| /** |
| * Create an instance of a SVGA3dShaderDestToken. |
| * Note that this function is used to create tokens for output registers, |
| * temp registers AND constants (see emit_def_const()). |
| */ |
| static inline SVGA3dShaderDestToken |
| dst_register(SVGA3dShaderRegType file, int number) |
| { |
| SVGA3dShaderDestToken dest; |
| |
| /* check values against bitfield sizes */ |
| assert(number < (1 << 11)); |
| assert(file <= SVGA3DREG_PREDICATE); |
| |
| dest.value = 0; |
| dest.num = number; |
| dest.type_upper = file >> 3; |
| dest.relAddr = 0; |
| dest.reserved1 = 0; |
| dest.mask = 0xf; |
| dest.dstMod = 0; |
| dest.shfScale = 0; |
| dest.type_lower = file & 0x7; |
| dest.reserved0 = 1; /* is_reg */ |
| |
| return dest; |
| } |
| |
| |
| /** |
| * Apply a writemask to the given SVGA3dShaderDestToken, returning a |
| * new SVGA3dShaderDestToken. |
| */ |
| static inline SVGA3dShaderDestToken |
| writemask(SVGA3dShaderDestToken dest, unsigned mask) |
| { |
| assert(dest.mask & mask); |
| dest.mask &= mask; |
| return dest; |
| } |
| |
| |
| /** Create a SVGA3dShaderSrcToken given a register file and number */ |
| static inline SVGA3dShaderSrcToken |
| src_token(SVGA3dShaderRegType file, int number) |
| { |
| SVGA3dShaderSrcToken src; |
| |
| /* check values against bitfield sizes */ |
| assert(number < (1 << 11)); |
| assert(file <= SVGA3DREG_PREDICATE); |
| |
| src.value = 0; |
| src.num = number; |
| src.type_upper = file >> 3; |
| src.relAddr = 0; |
| src.reserved1 = 0; |
| src.swizzle = SWIZZLE_XYZW; |
| src.srcMod = 0; |
| src.type_lower = file & 0x7; |
| src.reserved0 = 1; /* is_reg */ |
| |
| return src; |
| } |
| |
| |
| /** Create a src_register given a register file and register number */ |
| static inline struct src_register |
| src_register(SVGA3dShaderRegType file, int number) |
| { |
| struct src_register src; |
| |
| src.base = src_token(file, number); |
| src.indirect.value = 0; |
| |
| return src; |
| } |
| |
| /** Translate src_register into SVGA3dShaderDestToken */ |
| static inline SVGA3dShaderDestToken |
| dst(struct src_register src) |
| { |
| return dst_register(SVGA3dShaderGetRegType(src.base.value), src.base.num); |
| } |
| |
| |
| /** Translate SVGA3dShaderDestToken to a src_register */ |
| static inline struct src_register |
| src(SVGA3dShaderDestToken dst) |
| { |
| return src_register(SVGA3dShaderGetRegType(dst.value), dst.num); |
| } |
| |
| #endif |