Home | History | Annotate | Download | only in i965
      1 /*
      2  * Copyright  2015 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 "brw_context.h"
     25 #include "brw_state.h"
     26 #include "brw_defines.h"
     27 #include "brw_program.h"
     28 #include "intel_batchbuffer.h"
     29 #include "intel_buffer_objects.h"
     30 #include "program/prog_parameter.h"
     31 #include "main/shaderapi.h"
     32 
     33 static uint32_t
     34 f_as_u32(float f)
     35 {
     36    union fi fi = { .f = f };
     37    return fi.ui;
     38 }
     39 
     40 static uint32_t
     41 brw_param_value(struct brw_context *brw,
     42                 const struct gl_program *prog,
     43                 const struct brw_stage_state *stage_state,
     44                 uint32_t param)
     45 {
     46    struct gl_context *ctx = &brw->ctx;
     47 
     48    switch (BRW_PARAM_DOMAIN(param)) {
     49    case BRW_PARAM_DOMAIN_BUILTIN:
     50       if (param == BRW_PARAM_BUILTIN_ZERO) {
     51          return 0;
     52       } else if (BRW_PARAM_BUILTIN_IS_CLIP_PLANE(param)) {
     53          gl_clip_plane *clip_planes = brw_select_clip_planes(ctx);
     54          unsigned idx = BRW_PARAM_BUILTIN_CLIP_PLANE_IDX(param);
     55          unsigned comp = BRW_PARAM_BUILTIN_CLIP_PLANE_COMP(param);
     56          return ((uint32_t *)clip_planes[idx])[comp];
     57       } else if (param >= BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X &&
     58                  param <= BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_W) {
     59          unsigned i = param - BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X;
     60          return f_as_u32(ctx->TessCtrlProgram.patch_default_outer_level[i]);
     61       } else if (param == BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_X) {
     62          return f_as_u32(ctx->TessCtrlProgram.patch_default_inner_level[0]);
     63       } else if (param == BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_Y) {
     64          return f_as_u32(ctx->TessCtrlProgram.patch_default_inner_level[1]);
     65       } else {
     66          unreachable("Invalid param builtin");
     67       }
     68 
     69    case BRW_PARAM_DOMAIN_PARAMETER: {
     70       unsigned idx = BRW_PARAM_PARAMETER_IDX(param);
     71       unsigned comp = BRW_PARAM_PARAMETER_COMP(param);
     72       assert(idx < prog->Parameters->NumParameters);
     73       return prog->Parameters->ParameterValues[idx][comp].u;
     74    }
     75 
     76    case BRW_PARAM_DOMAIN_UNIFORM: {
     77       unsigned idx = BRW_PARAM_UNIFORM_IDX(param);
     78       assert(idx < prog->sh.data->NumUniformDataSlots);
     79       return prog->sh.data->UniformDataSlots[idx].u;
     80    }
     81 
     82    case BRW_PARAM_DOMAIN_IMAGE: {
     83       unsigned idx = BRW_PARAM_IMAGE_IDX(param);
     84       unsigned offset = BRW_PARAM_IMAGE_OFFSET(param);
     85       assert(offset < ARRAY_SIZE(stage_state->image_param));
     86       return ((uint32_t *)&stage_state->image_param[idx])[offset];
     87    }
     88 
     89    default:
     90       unreachable("Invalid param domain");
     91    }
     92 }
     93 
     94 
     95 void
     96 brw_populate_constant_data(struct brw_context *brw,
     97                            const struct gl_program *prog,
     98                            const struct brw_stage_state *stage_state,
     99                            void *void_dst,
    100                            const uint32_t *param,
    101                            unsigned nr_params)
    102 {
    103    uint32_t *dst = void_dst;
    104    for (unsigned i = 0; i < nr_params; i++)
    105       dst[i] = brw_param_value(brw, prog, stage_state, param[i]);
    106 }
    107 
    108 
    109 /**
    110  * Creates a streamed BO containing the push constants for the VS or GS on
    111  * gen6+.
    112  *
    113  * Push constants are constant values (such as GLSL uniforms) that are
    114  * pre-loaded into a shader stage's register space at thread spawn time.
    115  *
    116  * Not all GLSL uniforms will be uploaded as push constants: The hardware has
    117  * a limitation of 32 or 64 EU registers (256 or 512 floats) per stage to be
    118  * uploaded as push constants, while GL 4.4 requires at least 1024 components
    119  * to be usable for the VS.  Plus, currently we always use pull constants
    120  * instead of push constants when doing variable-index array access.
    121  *
    122  * See brw_curbe.c for the equivalent gen4/5 code.
    123  */
    124 void
    125 gen6_upload_push_constants(struct brw_context *brw,
    126                            const struct gl_program *prog,
    127                            const struct brw_stage_prog_data *prog_data,
    128                            struct brw_stage_state *stage_state)
    129 {
    130    const struct gen_device_info *devinfo = &brw->screen->devinfo;
    131    struct gl_context *ctx = &brw->ctx;
    132 
    133    bool active = prog_data &&
    134       (stage_state->stage != MESA_SHADER_TESS_CTRL ||
    135        brw->programs[MESA_SHADER_TESS_EVAL]);
    136 
    137    if (active)
    138       _mesa_shader_write_subroutine_indices(ctx, stage_state->stage);
    139 
    140    if (!active || prog_data->nr_params == 0) {
    141       stage_state->push_const_size = 0;
    142    } else {
    143       /* Updates the ParamaterValues[i] pointers for all parameters of the
    144        * basic type of PROGRAM_STATE_VAR.
    145        */
    146       /* XXX: Should this happen somewhere before to get our state flag set? */
    147       if (prog)
    148          _mesa_load_state_parameters(ctx, prog->Parameters);
    149 
    150       int i;
    151       const int size = prog_data->nr_params * sizeof(gl_constant_value);
    152       gl_constant_value *param;
    153       if (devinfo->gen >= 8 || devinfo->is_haswell) {
    154          param = intel_upload_space(brw, size, 32,
    155                                     &stage_state->push_const_bo,
    156                                     &stage_state->push_const_offset);
    157       } else {
    158          param = brw_state_batch(brw, size, 32,
    159                                  &stage_state->push_const_offset);
    160       }
    161 
    162       STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float));
    163 
    164       /* _NEW_PROGRAM_CONSTANTS
    165        *
    166        * Also _NEW_TRANSFORM -- we may reference clip planes other than as a
    167        * side effect of dereferencing uniforms, so _NEW_PROGRAM_CONSTANTS
    168        * wouldn't be set for them.
    169        */
    170       brw_populate_constant_data(brw, prog, stage_state, param,
    171                                  prog_data->param,
    172                                  prog_data->nr_params);
    173 
    174       if (0) {
    175          fprintf(stderr, "%s constants:\n",
    176                  _mesa_shader_stage_to_string(stage_state->stage));
    177          for (i = 0; i < prog_data->nr_params; i++) {
    178             if ((i & 7) == 0)
    179                fprintf(stderr, "g%d: ",
    180                        prog_data->dispatch_grf_start_reg + i / 8);
    181             fprintf(stderr, "%8f ", param[i].f);
    182             if ((i & 7) == 7)
    183                fprintf(stderr, "\n");
    184          }
    185          if ((i & 7) != 0)
    186             fprintf(stderr, "\n");
    187          fprintf(stderr, "\n");
    188       }
    189 
    190       stage_state->push_const_size = ALIGN(prog_data->nr_params, 8) / 8;
    191       /* We can only push 32 registers of constants at a time. */
    192 
    193       /* From the SNB PRM (vol2, part 1, section 3.2.1.4: 3DSTATE_CONSTANT_VS:
    194        *
    195        *     "The sum of all four read length fields (each incremented to
    196        *      represent the actual read length) must be less than or equal to
    197        *      32"
    198        *
    199        * From the IVB PRM (vol2, part 1, section 3.2.1.3: 3DSTATE_CONSTANT_VS:
    200        *
    201        *     "The sum of all four read length fields must be less than or
    202        *      equal to the size of 64"
    203        *
    204        * The other shader stages all match the VS's limits.
    205        */
    206       assert(stage_state->push_const_size <= 32);
    207    }
    208 
    209    stage_state->push_constants_dirty = true;
    210 }
    211 
    212 
    213 /**
    214  * Creates a temporary BO containing the pull constant data for the shader
    215  * stage, and the SURFACE_STATE struct that points at it.
    216  *
    217  * Pull constants are GLSL uniforms (and other constant data) beyond what we
    218  * could fit as push constants, or that have variable-index array access
    219  * (which is easiest to support using pull constants, and avoids filling
    220  * register space with mostly-unused data).
    221  *
    222  * Compare this path to brw_curbe.c for gen4/5 push constants, and
    223  * gen6_vs_state.c for gen6+ push constants.
    224  */
    225 void
    226 brw_upload_pull_constants(struct brw_context *brw,
    227                           GLbitfield64 brw_new_constbuf,
    228                           const struct gl_program *prog,
    229                           struct brw_stage_state *stage_state,
    230                           const struct brw_stage_prog_data *prog_data)
    231 {
    232    unsigned i;
    233    uint32_t surf_index = prog_data->binding_table.pull_constants_start;
    234 
    235    if (!prog_data->nr_pull_params) {
    236       if (stage_state->surf_offset[surf_index]) {
    237 	 stage_state->surf_offset[surf_index] = 0;
    238 	 brw->ctx.NewDriverState |= brw_new_constbuf;
    239       }
    240       return;
    241    }
    242 
    243    /* Updates the ParamaterValues[i] pointers for all parameters of the
    244     * basic type of PROGRAM_STATE_VAR.
    245     */
    246    _mesa_load_state_parameters(&brw->ctx, prog->Parameters);
    247 
    248    /* BRW_NEW_*_PROG_DATA | _NEW_PROGRAM_CONSTANTS */
    249    uint32_t size = prog_data->nr_pull_params * 4;
    250    struct brw_bo *const_bo = NULL;
    251    uint32_t const_offset;
    252    gl_constant_value *constants = intel_upload_space(brw, size, 64,
    253                                                      &const_bo, &const_offset);
    254 
    255    STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float));
    256 
    257    brw_populate_constant_data(brw, prog, stage_state, constants,
    258                               prog_data->pull_param,
    259                               prog_data->nr_pull_params);
    260 
    261    if (0) {
    262       for (i = 0; i < ALIGN(prog_data->nr_pull_params, 4) / 4; i++) {
    263 	 const gl_constant_value *row = &constants[i * 4];
    264 	 fprintf(stderr, "const surface %3d: %4.3f %4.3f %4.3f %4.3f\n",
    265                  i, row[0].f, row[1].f, row[2].f, row[3].f);
    266       }
    267    }
    268 
    269    brw_emit_buffer_surface_state(brw, &stage_state->surf_offset[surf_index],
    270                                  const_bo, const_offset,
    271                                  ISL_FORMAT_R32G32B32A32_FLOAT,
    272                                  size, 1, 0);
    273 
    274    brw_bo_unreference(const_bo);
    275 
    276    brw->ctx.NewDriverState |= brw_new_constbuf;
    277 }
    278 
    279 /**
    280  * Creates a region containing the push constants for the CS on gen7+.
    281  *
    282  * Push constants are constant values (such as GLSL uniforms) that are
    283  * pre-loaded into a shader stage's register space at thread spawn time.
    284  *
    285  * For other stages, see brw_curbe.c:brw_upload_constant_buffer for the
    286  * equivalent gen4/5 code and gen6_vs_state.c:gen6_upload_push_constants for
    287  * gen6+.
    288  */
    289 void
    290 brw_upload_cs_push_constants(struct brw_context *brw,
    291                              const struct gl_program *prog,
    292                              const struct brw_cs_prog_data *cs_prog_data,
    293                              struct brw_stage_state *stage_state)
    294 {
    295    struct gl_context *ctx = &brw->ctx;
    296    const struct brw_stage_prog_data *prog_data =
    297       (struct brw_stage_prog_data*) cs_prog_data;
    298 
    299    /* Updates the ParamaterValues[i] pointers for all parameters of the
    300     * basic type of PROGRAM_STATE_VAR.
    301     */
    302    /* XXX: Should this happen somewhere before to get our state flag set? */
    303    _mesa_load_state_parameters(ctx, prog->Parameters);
    304 
    305    if (cs_prog_data->push.total.size == 0) {
    306       stage_state->push_const_size = 0;
    307       return;
    308    }
    309 
    310 
    311    uint32_t *param =
    312       brw_state_batch(brw, ALIGN(cs_prog_data->push.total.size, 64),
    313                       64, &stage_state->push_const_offset);
    314    assert(param);
    315 
    316    STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float));
    317 
    318    if (cs_prog_data->push.cross_thread.size > 0) {
    319       uint32_t *param_copy = param;
    320       for (unsigned i = 0;
    321            i < cs_prog_data->push.cross_thread.dwords;
    322            i++) {
    323          assert(prog_data->param[i] != BRW_PARAM_BUILTIN_SUBGROUP_ID);
    324          param_copy[i] = brw_param_value(brw, prog, stage_state,
    325                                          prog_data->param[i]);
    326       }
    327    }
    328 
    329    if (cs_prog_data->push.per_thread.size > 0) {
    330       for (unsigned t = 0; t < cs_prog_data->threads; t++) {
    331          unsigned dst =
    332             8 * (cs_prog_data->push.per_thread.regs * t +
    333                  cs_prog_data->push.cross_thread.regs);
    334          unsigned src = cs_prog_data->push.cross_thread.dwords;
    335          for ( ; src < prog_data->nr_params; src++, dst++) {
    336             if (prog_data->param[src] == BRW_PARAM_BUILTIN_SUBGROUP_ID) {
    337                param[dst] = t;
    338             } else {
    339                param[dst] = brw_param_value(brw, prog, stage_state,
    340                                             prog_data->param[src]);
    341             }
    342          }
    343       }
    344    }
    345 
    346    stage_state->push_const_size =
    347       cs_prog_data->push.cross_thread.regs +
    348       cs_prog_data->push.per_thread.regs;
    349 }
    350