Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2013 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
  21.  * DEALINGS IN THE SOFTWARE.
  22.  */
  23.  
  24.  
  25. #include "brw_vs.h"
  26. #include "main/context.h"
  27.  
  28.  
  29. namespace brw {
  30.  
  31. void
  32. vec4_vs_visitor::emit_prolog()
  33. {
  34.    dst_reg sign_recovery_shift;
  35.    dst_reg normalize_factor;
  36.    dst_reg es3_normalize_factor;
  37.  
  38.    for (int i = 0; i < VERT_ATTRIB_MAX; i++) {
  39.       if (vs_prog_data->inputs_read & BITFIELD64_BIT(i)) {
  40.          uint8_t wa_flags = vs_compile->key.gl_attrib_wa_flags[i];
  41.          dst_reg reg(ATTR, i);
  42.          dst_reg reg_d = reg;
  43.          reg_d.type = BRW_REGISTER_TYPE_D;
  44.          dst_reg reg_ud = reg;
  45.          reg_ud.type = BRW_REGISTER_TYPE_UD;
  46.  
  47.          /* Do GL_FIXED rescaling for GLES2.0.  Our GL_FIXED attributes
  48.           * come in as floating point conversions of the integer values.
  49.           */
  50.          if (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK) {
  51.             dst_reg dst = reg;
  52.             dst.type = brw_type_for_base_type(glsl_type::vec4_type);
  53.             dst.writemask = (1 << (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK)) - 1;
  54.             emit(MUL(dst, src_reg(dst), src_reg(1.0f / 65536.0f)));
  55.          }
  56.  
  57.          /* Do sign recovery for 2101010 formats if required. */
  58.          if (wa_flags & BRW_ATTRIB_WA_SIGN) {
  59.             if (sign_recovery_shift.file == BAD_FILE) {
  60.                /* shift constant: <22,22,22,30> */
  61.                sign_recovery_shift = dst_reg(this, glsl_type::uvec4_type);
  62.                emit(MOV(writemask(sign_recovery_shift, WRITEMASK_XYZ), src_reg(22u)));
  63.                emit(MOV(writemask(sign_recovery_shift, WRITEMASK_W), src_reg(30u)));
  64.             }
  65.  
  66.             emit(SHL(reg_ud, src_reg(reg_ud), src_reg(sign_recovery_shift)));
  67.             emit(ASR(reg_d, src_reg(reg_d), src_reg(sign_recovery_shift)));
  68.          }
  69.  
  70.          /* Apply BGRA swizzle if required. */
  71.          if (wa_flags & BRW_ATTRIB_WA_BGRA) {
  72.             src_reg temp = src_reg(reg);
  73.             temp.swizzle = BRW_SWIZZLE4(2,1,0,3);
  74.             emit(MOV(reg, temp));
  75.          }
  76.  
  77.          if (wa_flags & BRW_ATTRIB_WA_NORMALIZE) {
  78.             /* ES 3.0 has different rules for converting signed normalized
  79.              * fixed-point numbers than desktop GL.
  80.              */
  81.             if (_mesa_is_gles3(ctx) && (wa_flags & BRW_ATTRIB_WA_SIGN)) {
  82.                /* According to equation 2.2 of the ES 3.0 specification,
  83.                 * signed normalization conversion is done by:
  84.                 *
  85.                 * f = c / (2^(b-1)-1)
  86.                 */
  87.                if (es3_normalize_factor.file == BAD_FILE) {
  88.                   /* mul constant: 1 / (2^(b-1) - 1) */
  89.                   es3_normalize_factor = dst_reg(this, glsl_type::vec4_type);
  90.                   emit(MOV(writemask(es3_normalize_factor, WRITEMASK_XYZ),
  91.                            src_reg(1.0f / ((1<<9) - 1))));
  92.                   emit(MOV(writemask(es3_normalize_factor, WRITEMASK_W),
  93.                            src_reg(1.0f / ((1<<1) - 1))));
  94.                }
  95.  
  96.                dst_reg dst = reg;
  97.                dst.type = brw_type_for_base_type(glsl_type::vec4_type);
  98.                emit(MOV(dst, src_reg(reg_d)));
  99.                emit(MUL(dst, src_reg(dst), src_reg(es3_normalize_factor)));
  100.                emit_minmax(BRW_CONDITIONAL_GE, dst, src_reg(dst), src_reg(-1.0f));
  101.             } else {
  102.                /* The following equations are from the OpenGL 3.2 specification:
  103.                 *
  104.                 * 2.1 unsigned normalization
  105.                 * f = c/(2^n-1)
  106.                 *
  107.                 * 2.2 signed normalization
  108.                 * f = (2c+1)/(2^n-1)
  109.                 *
  110.                 * Both of these share a common divisor, which is represented by
  111.                 * "normalize_factor" in the code below.
  112.                 */
  113.                if (normalize_factor.file == BAD_FILE) {
  114.                   /* 1 / (2^b - 1) for b=<10,10,10,2> */
  115.                   normalize_factor = dst_reg(this, glsl_type::vec4_type);
  116.                   emit(MOV(writemask(normalize_factor, WRITEMASK_XYZ),
  117.                            src_reg(1.0f / ((1<<10) - 1))));
  118.                   emit(MOV(writemask(normalize_factor, WRITEMASK_W),
  119.                            src_reg(1.0f / ((1<<2) - 1))));
  120.                }
  121.  
  122.                dst_reg dst = reg;
  123.                dst.type = brw_type_for_base_type(glsl_type::vec4_type);
  124.                emit(MOV(dst, src_reg((wa_flags & BRW_ATTRIB_WA_SIGN) ? reg_d : reg_ud)));
  125.  
  126.                /* For signed normalization, we want the numerator to be 2c+1. */
  127.                if (wa_flags & BRW_ATTRIB_WA_SIGN) {
  128.                   emit(MUL(dst, src_reg(dst), src_reg(2.0f)));
  129.                   emit(ADD(dst, src_reg(dst), src_reg(1.0f)));
  130.                }
  131.  
  132.                emit(MUL(dst, src_reg(dst), src_reg(normalize_factor)));
  133.             }
  134.          }
  135.  
  136.          if (wa_flags & BRW_ATTRIB_WA_SCALE) {
  137.             dst_reg dst = reg;
  138.             dst.type = brw_type_for_base_type(glsl_type::vec4_type);
  139.             emit(MOV(dst, src_reg((wa_flags & BRW_ATTRIB_WA_SIGN) ? reg_d : reg_ud)));
  140.          }
  141.       }
  142.    }
  143. }
  144.  
  145.  
  146. dst_reg *
  147. vec4_vs_visitor::make_reg_for_system_value(ir_variable *ir)
  148. {
  149.    /* VertexID is stored by the VF as the last vertex element, but
  150.     * we don't represent it with a flag in inputs_read, so we call
  151.     * it VERT_ATTRIB_MAX, which setup_attributes() picks up on.
  152.     */
  153.    dst_reg *reg = new(mem_ctx) dst_reg(ATTR, VERT_ATTRIB_MAX);
  154.  
  155.    switch (ir->data.location) {
  156.    case SYSTEM_VALUE_BASE_VERTEX:
  157.       reg->writemask = WRITEMASK_X;
  158.       vs_prog_data->uses_vertexid = true;
  159.       break;
  160.    case SYSTEM_VALUE_VERTEX_ID:
  161.    case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
  162.       reg->writemask = WRITEMASK_Z;
  163.       vs_prog_data->uses_vertexid = true;
  164.       break;
  165.    case SYSTEM_VALUE_INSTANCE_ID:
  166.       reg->writemask = WRITEMASK_W;
  167.       vs_prog_data->uses_instanceid = true;
  168.       break;
  169.    default:
  170.       unreachable("not reached");
  171.    }
  172.  
  173.    return reg;
  174. }
  175.  
  176.  
  177. void
  178. vec4_vs_visitor::emit_urb_write_header(int mrf)
  179. {
  180.    /* No need to do anything for VS; an implied write to this MRF will be
  181.     * performed by VS_OPCODE_URB_WRITE.
  182.     */
  183.    (void) mrf;
  184. }
  185.  
  186.  
  187. vec4_instruction *
  188. vec4_vs_visitor::emit_urb_write_opcode(bool complete)
  189. {
  190.    /* For VS, the URB writes end the thread. */
  191.    if (complete) {
  192.       if (INTEL_DEBUG & DEBUG_SHADER_TIME)
  193.          emit_shader_time_end();
  194.    }
  195.  
  196.    vec4_instruction *inst = emit(VS_OPCODE_URB_WRITE);
  197.    inst->urb_write_flags = complete ?
  198.       BRW_URB_WRITE_EOT_COMPLETE : BRW_URB_WRITE_NO_FLAGS;
  199.  
  200.    return inst;
  201. }
  202.  
  203.  
  204. void
  205. vec4_vs_visitor::emit_thread_end()
  206. {
  207.    /* For VS, we always end the thread by emitting a single vertex.
  208.     * emit_urb_write_opcode() will take care of setting the eot flag on the
  209.     * SEND instruction.
  210.     */
  211.    emit_vertex();
  212. }
  213.  
  214.  
  215. vec4_vs_visitor::vec4_vs_visitor(struct brw_context *brw,
  216.                                  struct brw_vs_compile *vs_compile,
  217.                                  struct brw_vs_prog_data *vs_prog_data,
  218.                                  struct gl_shader_program *prog,
  219.                                  void *mem_ctx)
  220.    : vec4_visitor(brw, &vs_compile->base, &vs_compile->vp->program.Base,
  221.                   &vs_compile->key.base, &vs_prog_data->base, prog,
  222.                   MESA_SHADER_VERTEX,
  223.                   mem_ctx, false /* no_spills */,
  224.                   ST_VS, ST_VS_WRITTEN, ST_VS_RESET),
  225.      vs_compile(vs_compile),
  226.      vs_prog_data(vs_prog_data)
  227. {
  228. }
  229.  
  230.  
  231. } /* namespace brw */
  232.