Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2012 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 <gtest/gtest.h>
  25. #include "brw_vec4.h"
  26. #include "brw_vs.h"
  27.  
  28. using namespace brw;
  29.  
  30. int ret = 0;
  31.  
  32. #define register_coalesce(v) _register_coalesce(v, __func__)
  33.  
  34. class register_coalesce_test : public ::testing::Test {
  35.    virtual void SetUp();
  36.  
  37. public:
  38.    struct brw_context *brw;
  39.    struct brw_device_info *devinfo;
  40.    struct gl_context *ctx;
  41.    struct gl_shader_program *shader_prog;
  42.    struct brw_vertex_program *vp;
  43.    vec4_visitor *v;
  44. };
  45.  
  46.  
  47. class register_coalesce_vec4_visitor : public vec4_visitor
  48. {
  49. public:
  50.    register_coalesce_vec4_visitor(struct brw_context *brw,
  51.                                   struct gl_shader_program *shader_prog)
  52.       : vec4_visitor(brw, NULL, NULL, NULL, NULL, shader_prog,
  53.                      MESA_SHADER_VERTEX, NULL,
  54.                      false /* no_spills */,
  55.                      ST_NONE, ST_NONE, ST_NONE)
  56.    {
  57.    }
  58.  
  59. protected:
  60.    virtual dst_reg *make_reg_for_system_value(ir_variable *ir)
  61.    {
  62.       unreachable("Not reached");
  63.    }
  64.  
  65.    virtual void setup_payload()
  66.    {
  67.       unreachable("Not reached");
  68.    }
  69.  
  70.    virtual void emit_prolog()
  71.    {
  72.       unreachable("Not reached");
  73.    }
  74.  
  75.    virtual void emit_program_code()
  76.    {
  77.       unreachable("Not reached");
  78.    }
  79.  
  80.    virtual void emit_thread_end()
  81.    {
  82.       unreachable("Not reached");
  83.    }
  84.  
  85.    virtual void emit_urb_write_header(int mrf)
  86.    {
  87.       unreachable("Not reached");
  88.    }
  89.  
  90.    virtual vec4_instruction *emit_urb_write_opcode(bool complete)
  91.    {
  92.       unreachable("Not reached");
  93.    }
  94. };
  95.  
  96.  
  97. void register_coalesce_test::SetUp()
  98. {
  99.    brw = (struct brw_context *)calloc(1, sizeof(*brw));
  100.    devinfo = (struct brw_device_info *)calloc(1, sizeof(*brw));
  101.    brw->intelScreen = (struct intel_screen *)calloc(1, sizeof(*brw->intelScreen));
  102.    brw->intelScreen->devinfo = devinfo;
  103.    ctx = &brw->ctx;
  104.  
  105.    vp = ralloc(NULL, struct brw_vertex_program);
  106.  
  107.    shader_prog = ralloc(NULL, struct gl_shader_program);
  108.  
  109.    v = new register_coalesce_vec4_visitor(brw, shader_prog);
  110.  
  111.    _mesa_init_vertex_program(ctx, &vp->program, GL_VERTEX_SHADER, 0);
  112.  
  113.    brw->gen = devinfo->gen = 4;
  114. }
  115.  
  116. static void
  117. _register_coalesce(vec4_visitor *v, const char *func)
  118. {
  119.    bool print = false;
  120.  
  121.    if (print) {
  122.       printf("%s: instructions before:\n", func);
  123.       v->dump_instructions();
  124.    }
  125.  
  126.    v->calculate_cfg();
  127.    v->opt_register_coalesce();
  128.  
  129.    if (print) {
  130.       printf("%s: instructions after:\n", func);
  131.       v->dump_instructions();
  132.    }
  133. }
  134.  
  135. TEST_F(register_coalesce_test, test_compute_to_mrf)
  136. {
  137.    src_reg something = src_reg(v, glsl_type::float_type);
  138.    dst_reg temp = dst_reg(v, glsl_type::float_type);
  139.    dst_reg init;
  140.  
  141.    dst_reg m0 = dst_reg(MRF, 0);
  142.    m0.writemask = WRITEMASK_X;
  143.    m0.type = BRW_REGISTER_TYPE_F;
  144.  
  145.    vec4_instruction *mul = v->emit(v->MUL(temp, something, src_reg(1.0f)));
  146.    v->emit(v->MOV(m0, src_reg(temp)));
  147.  
  148.    register_coalesce(v);
  149.  
  150.    EXPECT_EQ(mul->dst.file, MRF);
  151. }
  152.  
  153.  
  154. TEST_F(register_coalesce_test, test_multiple_use)
  155. {
  156.    src_reg something = src_reg(v, glsl_type::float_type);
  157.    dst_reg temp = dst_reg(v, glsl_type::vec4_type);
  158.    dst_reg init;
  159.  
  160.    dst_reg m0 = dst_reg(MRF, 0);
  161.    m0.writemask = WRITEMASK_X;
  162.    m0.type = BRW_REGISTER_TYPE_F;
  163.  
  164.    dst_reg m1 = dst_reg(MRF, 1);
  165.    m1.writemask = WRITEMASK_XYZW;
  166.    m1.type = BRW_REGISTER_TYPE_F;
  167.  
  168.    src_reg src = src_reg(temp);
  169.    vec4_instruction *mul = v->emit(v->MUL(temp, something, src_reg(1.0f)));
  170.    src.swizzle = BRW_SWIZZLE_XXXX;
  171.    v->emit(v->MOV(m0, src));
  172.    src.swizzle = BRW_SWIZZLE_XYZW;
  173.    v->emit(v->MOV(m1, src));
  174.  
  175.    register_coalesce(v);
  176.  
  177.    EXPECT_NE(mul->dst.file, MRF);
  178. }
  179.  
  180. TEST_F(register_coalesce_test, test_dp4_mrf)
  181. {
  182.    src_reg some_src_1 = src_reg(v, glsl_type::vec4_type);
  183.    src_reg some_src_2 = src_reg(v, glsl_type::vec4_type);
  184.    dst_reg init;
  185.  
  186.    dst_reg m0 = dst_reg(MRF, 0);
  187.    m0.writemask = WRITEMASK_Y;
  188.    m0.type = BRW_REGISTER_TYPE_F;
  189.  
  190.    dst_reg temp = dst_reg(v, glsl_type::float_type);
  191.  
  192.    vec4_instruction *dp4 = v->emit(v->DP4(temp, some_src_1, some_src_2));
  193.    v->emit(v->MOV(m0, src_reg(temp)));
  194.  
  195.    register_coalesce(v);
  196.  
  197.    EXPECT_EQ(dp4->dst.file, MRF);
  198.    EXPECT_EQ(dp4->dst.writemask, WRITEMASK_Y);
  199. }
  200.  
  201. TEST_F(register_coalesce_test, test_dp4_grf)
  202. {
  203.    src_reg some_src_1 = src_reg(v, glsl_type::vec4_type);
  204.    src_reg some_src_2 = src_reg(v, glsl_type::vec4_type);
  205.    dst_reg init;
  206.  
  207.    dst_reg to = dst_reg(v, glsl_type::vec4_type);
  208.    dst_reg temp = dst_reg(v, glsl_type::float_type);
  209.  
  210.    vec4_instruction *dp4 = v->emit(v->DP4(temp, some_src_1, some_src_2));
  211.    to.writemask = WRITEMASK_Y;
  212.    v->emit(v->MOV(to, src_reg(temp)));
  213.  
  214.    /* if we don't do something with the result, the automatic dead code
  215.     * elimination will remove all our instructions.
  216.     */
  217.    src_reg src = src_reg(to);
  218.    src.negate = true;
  219.    v->emit(v->MOV(dst_reg(MRF, 0), src));
  220.  
  221.    register_coalesce(v);
  222.  
  223.    EXPECT_EQ(dp4->dst.reg, to.reg);
  224.    EXPECT_EQ(dp4->dst.writemask, WRITEMASK_Y);
  225. }
  226.  
  227. TEST_F(register_coalesce_test, test_channel_mul_grf)
  228. {
  229.    src_reg some_src_1 = src_reg(v, glsl_type::vec4_type);
  230.    src_reg some_src_2 = src_reg(v, glsl_type::vec4_type);
  231.    dst_reg init;
  232.  
  233.    dst_reg to = dst_reg(v, glsl_type::vec4_type);
  234.    dst_reg temp = dst_reg(v, glsl_type::float_type);
  235.  
  236.    vec4_instruction *mul = v->emit(v->MUL(temp, some_src_1, some_src_2));
  237.    to.writemask = WRITEMASK_Y;
  238.    v->emit(v->MOV(to, src_reg(temp)));
  239.  
  240.    /* if we don't do something with the result, the automatic dead code
  241.     * elimination will remove all our instructions.
  242.     */
  243.    src_reg src = src_reg(to);
  244.    src.negate = true;
  245.    v->emit(v->MOV(dst_reg(MRF, 0), src));
  246.  
  247.    register_coalesce(v);
  248.  
  249.    EXPECT_EQ(mul->dst.reg, to.reg);
  250. }
  251.