Home | History | Annotate | Download | only in i965
      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 
     24 extern "C" {
     25 #include "main/macros.h"
     26 #include "brw_context.h"
     27 #include "brw_vs.h"
     28 }
     29 #include "brw_fs.h"
     30 #include "glsl/ir_optimization.h"
     31 #include "glsl/ir_print_visitor.h"
     32 
     33 struct gl_shader *
     34 brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type)
     35 {
     36    struct brw_shader *shader;
     37 
     38    shader = rzalloc(NULL, struct brw_shader);
     39    if (shader) {
     40       shader->base.Type = type;
     41       shader->base.Name = name;
     42       _mesa_init_shader(ctx, &shader->base);
     43    }
     44 
     45    return &shader->base;
     46 }
     47 
     48 struct gl_shader_program *
     49 brw_new_shader_program(struct gl_context *ctx, GLuint name)
     50 {
     51    struct brw_shader_program *prog;
     52    prog = rzalloc(NULL, struct brw_shader_program);
     53    if (prog) {
     54       prog->base.Name = name;
     55       _mesa_init_shader_program(ctx, &prog->base);
     56    }
     57    return &prog->base;
     58 }
     59 
     60 /**
     61  * Performs a compile of the shader stages even when we don't know
     62  * what non-orthogonal state will be set, in the hope that it reflects
     63  * the eventual NOS used, and thus allows us to produce link failures.
     64  */
     65 bool
     66 brw_shader_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
     67 {
     68    struct brw_context *brw = brw_context(ctx);
     69 
     70    if (brw->precompile && !brw_fs_precompile(ctx, prog))
     71       return false;
     72 
     73    if (brw->precompile && !brw_vs_precompile(ctx, prog))
     74       return false;
     75 
     76    return true;
     77 }
     78 
     79 GLboolean
     80 brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
     81 {
     82    struct brw_context *brw = brw_context(ctx);
     83    struct intel_context *intel = &brw->intel;
     84    unsigned int stage;
     85 
     86    for (stage = 0; stage < ARRAY_SIZE(shProg->_LinkedShaders); stage++) {
     87       struct brw_shader *shader =
     88 	 (struct brw_shader *)shProg->_LinkedShaders[stage];
     89       static const GLenum targets[] = {
     90 	 GL_VERTEX_PROGRAM_ARB,
     91 	 GL_FRAGMENT_PROGRAM_ARB,
     92 	 GL_GEOMETRY_PROGRAM_NV
     93       };
     94 
     95       if (!shader)
     96 	 continue;
     97 
     98       struct gl_program *prog =
     99 	 ctx->Driver.NewProgram(ctx, targets[stage], shader->base.Name);
    100       if (!prog)
    101 	return false;
    102       prog->Parameters = _mesa_new_parameter_list();
    103 
    104       _mesa_generate_parameters_list_for_uniforms(shProg, &shader->base,
    105 						  prog->Parameters);
    106 
    107       if (stage == 0) {
    108 	 struct gl_vertex_program *vp = (struct gl_vertex_program *) prog;
    109 	 vp->UsesClipDistance = shProg->Vert.UsesClipDistance;
    110       }
    111 
    112       void *mem_ctx = ralloc_context(NULL);
    113       bool progress;
    114 
    115       if (shader->ir)
    116 	 ralloc_free(shader->ir);
    117       shader->ir = new(shader) exec_list;
    118       clone_ir_list(mem_ctx, shader->ir, shader->base.ir);
    119 
    120       do_mat_op_to_vec(shader->ir);
    121       lower_instructions(shader->ir,
    122 			 MOD_TO_FRACT |
    123 			 DIV_TO_MUL_RCP |
    124 			 SUB_TO_ADD_NEG |
    125 			 EXP_TO_EXP2 |
    126 			 LOG_TO_LOG2);
    127 
    128       /* Pre-gen6 HW can only nest if-statements 16 deep.  Beyond this,
    129        * if-statements need to be flattened.
    130        */
    131       if (intel->gen < 6)
    132 	 lower_if_to_cond_assign(shader->ir, 16);
    133 
    134       do_lower_texture_projection(shader->ir);
    135       if (intel->gen < 8 && !intel->is_haswell)
    136          brw_lower_texture_gradients(shader->ir);
    137       do_vec_index_to_cond_assign(shader->ir);
    138       brw_do_cubemap_normalize(shader->ir);
    139       lower_noise(shader->ir);
    140       lower_quadop_vector(shader->ir, false);
    141 
    142       bool input = true;
    143       bool output = stage == MESA_SHADER_FRAGMENT;
    144       bool temp = stage == MESA_SHADER_FRAGMENT;
    145       bool uniform = stage == MESA_SHADER_FRAGMENT;
    146 
    147       lower_variable_index_to_cond_assign(shader->ir,
    148 					  input, output, temp, uniform);
    149 
    150       /* FINISHME: Do this before the variable index lowering. */
    151       lower_ubo_reference(&shader->base, shader->ir);
    152 
    153       do {
    154 	 progress = false;
    155 
    156 	 if (stage == MESA_SHADER_FRAGMENT) {
    157 	    brw_do_channel_expressions(shader->ir);
    158 	    brw_do_vector_splitting(shader->ir);
    159 	 }
    160 
    161 	 progress = do_lower_jumps(shader->ir, true, true,
    162 				   true, /* main return */
    163 				   false, /* continue */
    164 				   false /* loops */
    165 				   ) || progress;
    166 
    167 	 progress = do_common_optimization(shader->ir, true, true, 32)
    168 	   || progress;
    169       } while (progress);
    170 
    171       /* Make a pass over the IR to add state references for any built-in
    172        * uniforms that are used.  This has to be done now (during linking).
    173        * Code generation doesn't happen until the first time this shader is
    174        * used for rendering.  Waiting until then to generate the parameters is
    175        * too late.  At that point, the values for the built-in informs won't
    176        * get sent to the shader.
    177        */
    178       foreach_list(node, shader->ir) {
    179 	 ir_variable *var = ((ir_instruction *) node)->as_variable();
    180 
    181 	 if ((var == NULL) || (var->mode != ir_var_uniform)
    182 	     || (strncmp(var->name, "gl_", 3) != 0))
    183 	    continue;
    184 
    185 	 const ir_state_slot *const slots = var->state_slots;
    186 	 assert(var->state_slots != NULL);
    187 
    188 	 for (unsigned int i = 0; i < var->num_state_slots; i++) {
    189 	    _mesa_add_state_reference(prog->Parameters,
    190 				      (gl_state_index *) slots[i].tokens);
    191 	 }
    192       }
    193 
    194       validate_ir_tree(shader->ir);
    195 
    196       reparent_ir(shader->ir, shader->ir);
    197       ralloc_free(mem_ctx);
    198 
    199       do_set_program_inouts(shader->ir, prog,
    200 			    shader->base.Type == GL_FRAGMENT_SHADER);
    201 
    202       prog->SamplersUsed = shader->base.active_samplers;
    203       _mesa_update_shader_textures_used(shProg, prog);
    204 
    205       _mesa_reference_program(ctx, &shader->base.Program, prog);
    206 
    207       /* This has to be done last.  Any operation that can cause
    208        * prog->ParameterValues to get reallocated (e.g., anything that adds a
    209        * program constant) has to happen before creating this linkage.
    210        */
    211       _mesa_associate_uniform_storage(ctx, shProg, prog->Parameters);
    212 
    213       _mesa_reference_program(ctx, &prog, NULL);
    214    }
    215 
    216    if (!brw_shader_precompile(ctx, shProg))
    217       return false;
    218 
    219    return true;
    220 }
    221 
    222 
    223 int
    224 brw_type_for_base_type(const struct glsl_type *type)
    225 {
    226    switch (type->base_type) {
    227    case GLSL_TYPE_FLOAT:
    228       return BRW_REGISTER_TYPE_F;
    229    case GLSL_TYPE_INT:
    230    case GLSL_TYPE_BOOL:
    231       return BRW_REGISTER_TYPE_D;
    232    case GLSL_TYPE_UINT:
    233       return BRW_REGISTER_TYPE_UD;
    234    case GLSL_TYPE_ARRAY:
    235       return brw_type_for_base_type(type->fields.array);
    236    case GLSL_TYPE_STRUCT:
    237    case GLSL_TYPE_SAMPLER:
    238       /* These should be overridden with the type of the member when
    239        * dereferenced into.  BRW_REGISTER_TYPE_UD seems like a likely
    240        * way to trip up if we don't.
    241        */
    242       return BRW_REGISTER_TYPE_UD;
    243    default:
    244       assert(!"not reached");
    245       return BRW_REGISTER_TYPE_F;
    246    }
    247 }
    248 
    249 uint32_t
    250 brw_conditional_for_comparison(unsigned int op)
    251 {
    252    switch (op) {
    253    case ir_binop_less:
    254       return BRW_CONDITIONAL_L;
    255    case ir_binop_greater:
    256       return BRW_CONDITIONAL_G;
    257    case ir_binop_lequal:
    258       return BRW_CONDITIONAL_LE;
    259    case ir_binop_gequal:
    260       return BRW_CONDITIONAL_GE;
    261    case ir_binop_equal:
    262    case ir_binop_all_equal: /* same as equal for scalars */
    263       return BRW_CONDITIONAL_Z;
    264    case ir_binop_nequal:
    265    case ir_binop_any_nequal: /* same as nequal for scalars */
    266       return BRW_CONDITIONAL_NZ;
    267    default:
    268       assert(!"not reached: bad operation for comparison");
    269       return BRW_CONDITIONAL_NZ;
    270    }
    271 }
    272 
    273 uint32_t
    274 brw_math_function(enum opcode op)
    275 {
    276    switch (op) {
    277    case SHADER_OPCODE_RCP:
    278       return BRW_MATH_FUNCTION_INV;
    279    case SHADER_OPCODE_RSQ:
    280       return BRW_MATH_FUNCTION_RSQ;
    281    case SHADER_OPCODE_SQRT:
    282       return BRW_MATH_FUNCTION_SQRT;
    283    case SHADER_OPCODE_EXP2:
    284       return BRW_MATH_FUNCTION_EXP;
    285    case SHADER_OPCODE_LOG2:
    286       return BRW_MATH_FUNCTION_LOG;
    287    case SHADER_OPCODE_POW:
    288       return BRW_MATH_FUNCTION_POW;
    289    case SHADER_OPCODE_SIN:
    290       return BRW_MATH_FUNCTION_SIN;
    291    case SHADER_OPCODE_COS:
    292       return BRW_MATH_FUNCTION_COS;
    293    case SHADER_OPCODE_INT_QUOTIENT:
    294       return BRW_MATH_FUNCTION_INT_DIV_QUOTIENT;
    295    case SHADER_OPCODE_INT_REMAINDER:
    296       return BRW_MATH_FUNCTION_INT_DIV_REMAINDER;
    297    default:
    298       assert(!"not reached: unknown math function");
    299       return 0;
    300    }
    301 }
    302 
    303 uint32_t
    304 brw_texture_offset(ir_constant *offset)
    305 {
    306    assert(offset != NULL);
    307 
    308    signed char offsets[3];
    309    for (unsigned i = 0; i < offset->type->vector_elements; i++)
    310       offsets[i] = (signed char) offset->value.i[i];
    311 
    312    /* Combine all three offsets into a single unsigned dword:
    313     *
    314     *    bits 11:8 - U Offset (X component)
    315     *    bits  7:4 - V Offset (Y component)
    316     *    bits  3:0 - R Offset (Z component)
    317     */
    318    unsigned offset_bits = 0;
    319    for (unsigned i = 0; i < offset->type->vector_elements; i++) {
    320       const unsigned shift = 4 * (2 - i);
    321       offset_bits |= (offsets[i] << shift) & (0xF << shift);
    322    }
    323    return offset_bits;
    324 }
    325