brw_shader.cpp revision b7b700aeb0eab2cae26a01d9db42feea969333c7
1/*
2 * Copyright © 2010 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
24extern "C" {
25#include "main/macros.h"
26#include "brw_context.h"
27}
28#include "brw_fs.h"
29#include "../glsl/ir_optimization.h"
30#include "../glsl/ir_print_visitor.h"
31
32struct gl_shader *
33brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type)
34{
35   struct brw_shader *shader;
36
37   shader = rzalloc(NULL, struct brw_shader);
38   if (shader) {
39      shader->base.Type = type;
40      shader->base.Name = name;
41      _mesa_init_shader(ctx, &shader->base);
42   }
43
44   return &shader->base;
45}
46
47struct gl_shader_program *
48brw_new_shader_program(struct gl_context *ctx, GLuint name)
49{
50   struct brw_shader_program *prog;
51   prog = rzalloc(NULL, struct brw_shader_program);
52   if (prog) {
53      prog->base.Name = name;
54      _mesa_init_shader_program(ctx, &prog->base);
55   }
56   return &prog->base;
57}
58
59GLboolean
60brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
61{
62   struct brw_context *brw = brw_context(ctx);
63   struct intel_context *intel = &brw->intel;
64
65   struct brw_shader *shader =
66      (struct brw_shader *)prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
67   if (shader != NULL) {
68      void *mem_ctx = ralloc_context(NULL);
69      bool progress;
70
71      if (shader->ir)
72	 ralloc_free(shader->ir);
73      shader->ir = new(shader) exec_list;
74      clone_ir_list(mem_ctx, shader->ir, shader->base.ir);
75
76      do_mat_op_to_vec(shader->ir);
77      lower_instructions(shader->ir,
78			 MOD_TO_FRACT |
79			 DIV_TO_MUL_RCP |
80			 SUB_TO_ADD_NEG |
81			 EXP_TO_EXP2 |
82			 LOG_TO_LOG2);
83
84      /* Pre-gen6 HW can only nest if-statements 16 deep.  Beyond this,
85       * if-statements need to be flattened.
86       */
87      if (intel->gen < 6)
88	 lower_if_to_cond_assign(shader->ir, 16);
89
90      do_lower_texture_projection(shader->ir);
91      do_vec_index_to_cond_assign(shader->ir);
92      brw_do_cubemap_normalize(shader->ir);
93      lower_noise(shader->ir);
94      lower_quadop_vector(shader->ir, false);
95      lower_variable_index_to_cond_assign(shader->ir,
96					  GL_TRUE, /* input */
97					  GL_TRUE, /* output */
98					  GL_TRUE, /* temp */
99					  GL_TRUE /* uniform */
100					  );
101
102      do {
103	 progress = false;
104
105	 brw_do_channel_expressions(shader->ir);
106	 brw_do_vector_splitting(shader->ir);
107
108	 progress = do_lower_jumps(shader->ir, true, true,
109				   true, /* main return */
110				   false, /* continue */
111				   false /* loops */
112				   ) || progress;
113
114	 progress = do_common_optimization(shader->ir, true, 32) || progress;
115      } while (progress);
116
117      validate_ir_tree(shader->ir);
118
119      reparent_ir(shader->ir, shader->ir);
120      ralloc_free(mem_ctx);
121   }
122
123   if (!_mesa_ir_link_shader(ctx, prog))
124      return GL_FALSE;
125
126   return GL_TRUE;
127}
128
129
130int
131brw_type_for_base_type(const struct glsl_type *type)
132{
133   switch (type->base_type) {
134   case GLSL_TYPE_FLOAT:
135      return BRW_REGISTER_TYPE_F;
136   case GLSL_TYPE_INT:
137   case GLSL_TYPE_BOOL:
138      return BRW_REGISTER_TYPE_D;
139   case GLSL_TYPE_UINT:
140      return BRW_REGISTER_TYPE_UD;
141   case GLSL_TYPE_ARRAY:
142   case GLSL_TYPE_STRUCT:
143   case GLSL_TYPE_SAMPLER:
144      /* These should be overridden with the type of the member when
145       * dereferenced into.  BRW_REGISTER_TYPE_UD seems like a likely
146       * way to trip up if we don't.
147       */
148      return BRW_REGISTER_TYPE_UD;
149   default:
150      assert(!"not reached");
151      return BRW_REGISTER_TYPE_F;
152   }
153}
154
155uint32_t
156brw_conditional_for_comparison(unsigned int op)
157{
158   switch (op) {
159   case ir_binop_less:
160      return BRW_CONDITIONAL_L;
161   case ir_binop_greater:
162      return BRW_CONDITIONAL_G;
163   case ir_binop_lequal:
164      return BRW_CONDITIONAL_LE;
165   case ir_binop_gequal:
166      return BRW_CONDITIONAL_GE;
167   case ir_binop_equal:
168   case ir_binop_all_equal: /* same as equal for scalars */
169      return BRW_CONDITIONAL_Z;
170   case ir_binop_nequal:
171   case ir_binop_any_nequal: /* same as nequal for scalars */
172      return BRW_CONDITIONAL_NZ;
173   default:
174      assert(!"not reached: bad operation for comparison");
175      return BRW_CONDITIONAL_NZ;
176   }
177}
178