1/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include "compiler/nir/nir_builder.h"
25#include "brw_nir.h"
26
27/**
28 * Prior to Haswell, the hardware can't natively support GL_FIXED or
29 * 2_10_10_10_REV vertex formats.  This pass inserts extra shader code
30 * to produce the correct values.
31 */
32
33struct attr_wa_state {
34   nir_builder builder;
35   bool impl_progress;
36   const uint8_t *wa_flags;
37};
38
39static bool
40apply_attr_wa_block(nir_block *block, struct attr_wa_state *state)
41{
42   nir_builder *b = &state->builder;
43
44   nir_foreach_instr_safe(instr, block) {
45      if (instr->type != nir_instr_type_intrinsic)
46         continue;
47
48      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
49      if (intrin->intrinsic != nir_intrinsic_load_input)
50         continue;
51
52      uint8_t wa_flags = state->wa_flags[intrin->const_index[0]];
53      if (wa_flags == 0)
54         continue;
55
56      b->cursor = nir_after_instr(instr);
57
58      nir_ssa_def *val = &intrin->dest.ssa;
59
60      /* Do GL_FIXED rescaling for GLES2.0.  Our GL_FIXED attributes
61       * come in as floating point conversions of the integer values.
62       */
63      if (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK) {
64         nir_ssa_def *scaled =
65            nir_fmul(b, val, nir_imm_float(b, 1.0f / 65536.0f));
66         nir_ssa_def *comps[4];
67         for (int i = 0; i < val->num_components; i++) {
68            bool rescale = i < (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK);
69            comps[i] = nir_channel(b, rescale ? scaled : val, i);
70         }
71         val = nir_vec(b, comps, val->num_components);
72      }
73
74      /* Do sign recovery for 2101010 formats if required. */
75      if (wa_flags & BRW_ATTRIB_WA_SIGN) {
76         /* sign recovery shift: <22, 22, 22, 30> */
77         nir_ssa_def *shift = nir_imm_ivec4(b, 22, 22, 22, 30);
78         val = nir_ishr(b, nir_ishl(b, val, shift), shift);
79      }
80
81      /* Apply BGRA swizzle if required. */
82      if (wa_flags & BRW_ATTRIB_WA_BGRA) {
83         val = nir_swizzle(b, val, (unsigned[4]){2,1,0,3}, 4, true);
84      }
85
86      if (wa_flags & BRW_ATTRIB_WA_NORMALIZE) {
87         /* ES 3.0 has different rules for converting signed normalized
88          * fixed-point numbers than desktop GL.
89          */
90         if (wa_flags & BRW_ATTRIB_WA_SIGN) {
91            /* According to equation 2.2 of the ES 3.0 specification,
92             * signed normalization conversion is done by:
93             *
94             * f = c / (2^(b-1)-1)
95             *
96             * OpenGL 4.2+ uses this equation as well.  Since most contexts
97             * promote to the new higher version, and this is what Haswell+
98             * hardware does anyway, we just always use this formula.
99             */
100            nir_ssa_def *es3_normalize_factor =
101               nir_imm_vec4(b, 1.0f / ((1 << 9) - 1), 1.0f / ((1 << 9) - 1),
102                               1.0f / ((1 << 9) - 1), 1.0f / ((1 << 1) - 1));
103            val = nir_fmax(b,
104                           nir_fmul(b, nir_i2f32(b, val), es3_normalize_factor),
105                           nir_imm_float(b, -1.0f));
106         } else {
107            /* The following equation is from the OpenGL 3.2 specification:
108             *
109             * 2.1 unsigned normalization
110             * f = c/(2^n-1)
111             */
112            nir_ssa_def *normalize_factor =
113               nir_imm_vec4(b, 1.0f / ((1 << 10) - 1), 1.0f / ((1 << 10) - 1),
114                               1.0f / ((1 << 10) - 1), 1.0f / ((1 << 2)  - 1));
115
116            val = nir_fmul(b, nir_u2f32(b, val), normalize_factor);
117         }
118      }
119
120      if (wa_flags & BRW_ATTRIB_WA_SCALE) {
121         val = (wa_flags & BRW_ATTRIB_WA_SIGN) ? nir_i2f32(b, val)
122                                               : nir_u2f32(b, val);
123      }
124
125      nir_ssa_def_rewrite_uses_after(&intrin->dest.ssa, nir_src_for_ssa(val),
126                                     val->parent_instr);
127      state->impl_progress = true;
128   }
129
130   return true;
131}
132
133bool
134brw_nir_apply_attribute_workarounds(nir_shader *shader,
135                                    const uint8_t *attrib_wa_flags)
136{
137   bool progress = false;
138   struct attr_wa_state state = {
139      .wa_flags = attrib_wa_flags,
140   };
141
142   nir_foreach_function(func, shader) {
143      if (!func->impl)
144         continue;
145
146      nir_builder_init(&state.builder, func->impl);
147      state.impl_progress = false;
148
149      nir_foreach_block(block, func->impl) {
150         apply_attr_wa_block(block, &state);
151      }
152
153      if (state.impl_progress) {
154         nir_metadata_preserve(func->impl, nir_metadata_block_index |
155                                           nir_metadata_dominance);
156         progress = true;
157      }
158   }
159
160   return progress;
161}
162