19f464c52Smaya/*
29f464c52Smaya * Copyright © 2017 Intel Corporation
39f464c52Smaya *
49f464c52Smaya * Permission is hereby granted, free of charge, to any person obtaining a
59f464c52Smaya * copy of this software and associated documentation files (the "Software"),
69f464c52Smaya * to deal in the Software without restriction, including without limitation
79f464c52Smaya * the rights to use, copy, modify, merge, publish, distribute, sublicense,
89f464c52Smaya * and/or sell copies of the Software, and to permit persons to whom the
99f464c52Smaya * Software is furnished to do so, subject to the following conditions:
109f464c52Smaya *
119f464c52Smaya * The above copyright notice and this permission notice shall be included
129f464c52Smaya * in all copies or substantial portions of the Software.
139f464c52Smaya *
149f464c52Smaya * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
159f464c52Smaya * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
169f464c52Smaya * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
179f464c52Smaya * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
189f464c52Smaya * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
199f464c52Smaya * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
209f464c52Smaya * DEALINGS IN THE SOFTWARE.
219f464c52Smaya */
229f464c52Smaya
239f464c52Smaya/**
249f464c52Smaya * @file iris_draw.c
259f464c52Smaya *
269f464c52Smaya * The main driver hooks for drawing and launching compute shaders.
279f464c52Smaya */
289f464c52Smaya
299f464c52Smaya#include <stdio.h>
309f464c52Smaya#include <errno.h>
319f464c52Smaya#include "pipe/p_defines.h"
329f464c52Smaya#include "pipe/p_state.h"
339f464c52Smaya#include "pipe/p_context.h"
349f464c52Smaya#include "pipe/p_screen.h"
357ec681f3Smrg#include "util/u_draw.h"
369f464c52Smaya#include "util/u_inlines.h"
379f464c52Smaya#include "util/u_transfer.h"
389f464c52Smaya#include "util/u_upload_mgr.h"
399f464c52Smaya#include "intel/compiler/brw_compiler.h"
409f464c52Smaya#include "intel/compiler/brw_eu_defines.h"
419f464c52Smaya#include "iris_context.h"
429f464c52Smaya#include "iris_defines.h"
439f464c52Smaya
449f464c52Smayastatic bool
459f464c52Smayaprim_is_points_or_lines(const struct pipe_draw_info *draw)
469f464c52Smaya{
479f464c52Smaya   /* We don't need to worry about adjacency - it can only be used with
489f464c52Smaya    * geometry shaders, and we don't care about this info when GS is on.
499f464c52Smaya    */
509f464c52Smaya   return draw->mode == PIPE_PRIM_POINTS ||
519f464c52Smaya          draw->mode == PIPE_PRIM_LINES ||
529f464c52Smaya          draw->mode == PIPE_PRIM_LINE_LOOP ||
539f464c52Smaya          draw->mode == PIPE_PRIM_LINE_STRIP;
549f464c52Smaya}
559f464c52Smaya
569f464c52Smaya/**
579f464c52Smaya * Record the current primitive mode and restart information, flagging
589f464c52Smaya * related packets as dirty if necessary.
597ec681f3Smrg *
607ec681f3Smrg * This must be called before updating compiled shaders, because the patch
617ec681f3Smrg * information informs the TCS key.
629f464c52Smaya */
639f464c52Smayastatic void
649f464c52Smayairis_update_draw_info(struct iris_context *ice,
659f464c52Smaya                      const struct pipe_draw_info *info)
669f464c52Smaya{
677ec681f3Smrg   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
687ec681f3Smrg   const struct brw_compiler *compiler = screen->compiler;
697ec681f3Smrg
709f464c52Smaya   if (ice->state.prim_mode != info->mode) {
719f464c52Smaya      ice->state.prim_mode = info->mode;
729f464c52Smaya      ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY;
739f464c52Smaya
749f464c52Smaya
759f464c52Smaya      /* For XY Clip enables */
769f464c52Smaya      bool points_or_lines = prim_is_points_or_lines(info);
779f464c52Smaya      if (points_or_lines != ice->state.prim_is_points_or_lines) {
789f464c52Smaya         ice->state.prim_is_points_or_lines = points_or_lines;
799f464c52Smaya         ice->state.dirty |= IRIS_DIRTY_CLIP;
809f464c52Smaya      }
819f464c52Smaya   }
829f464c52Smaya
839f464c52Smaya   if (info->mode == PIPE_PRIM_PATCHES &&
847ec681f3Smrg       ice->state.vertices_per_patch != ice->state.patch_vertices) {
857ec681f3Smrg      ice->state.vertices_per_patch = ice->state.patch_vertices;
869f464c52Smaya      ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY;
879f464c52Smaya
887ec681f3Smrg      /* 8_PATCH TCS needs this for key->input_vertices */
897ec681f3Smrg      if (compiler->use_tcs_8_patch)
907ec681f3Smrg         ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_TCS;
917ec681f3Smrg
929f464c52Smaya      /* Flag constants dirty for gl_PatchVerticesIn if needed. */
939f464c52Smaya      const struct shader_info *tcs_info =
949f464c52Smaya         iris_get_shader_info(ice, MESA_SHADER_TESS_CTRL);
959f464c52Smaya      if (tcs_info &&
967ec681f3Smrg          BITSET_TEST(tcs_info->system_values_read, SYSTEM_VALUE_VERTICES_IN)) {
977ec681f3Smrg         ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_TCS;
987ec681f3Smrg         ice->state.shaders[MESA_SHADER_TESS_CTRL].sysvals_need_upload = true;
999f464c52Smaya      }
1009f464c52Smaya   }
1019f464c52Smaya
1027ec681f3Smrg   /* Track restart_index changes only if primitive_restart is true */
1037ec681f3Smrg   const unsigned cut_index = info->primitive_restart ? info->restart_index :
1047ec681f3Smrg                                                        ice->state.cut_index;
1059f464c52Smaya   if (ice->state.primitive_restart != info->primitive_restart ||
1067ec681f3Smrg       ice->state.cut_index != cut_index) {
1079f464c52Smaya      ice->state.dirty |= IRIS_DIRTY_VF;
1089f464c52Smaya      ice->state.primitive_restart = info->primitive_restart;
1097ec681f3Smrg      ice->state.cut_index = cut_index;
1109f464c52Smaya   }
1117ec681f3Smrg}
1129f464c52Smaya
1137ec681f3Smrg/**
1147ec681f3Smrg * Update shader draw parameters, flagging VF packets as dirty if necessary.
1157ec681f3Smrg */
1167ec681f3Smrgstatic void
1177ec681f3Smrgiris_update_draw_parameters(struct iris_context *ice,
1187ec681f3Smrg                            const struct pipe_draw_info *info,
1197ec681f3Smrg                            unsigned drawid_offset,
1207ec681f3Smrg                            const struct pipe_draw_indirect_info *indirect,
1217ec681f3Smrg                            const struct pipe_draw_start_count_bias *draw)
1227ec681f3Smrg{
1237ec681f3Smrg   bool changed = false;
1247ec681f3Smrg
1257ec681f3Smrg   if (ice->state.vs_uses_draw_params) {
1267ec681f3Smrg      struct iris_state_ref *draw_params = &ice->draw.draw_params;
1277ec681f3Smrg
1287ec681f3Smrg      if (indirect && indirect->buffer) {
1297ec681f3Smrg         pipe_resource_reference(&draw_params->res, indirect->buffer);
1307ec681f3Smrg         draw_params->offset =
1317ec681f3Smrg            indirect->offset + (info->index_size ? 12 : 8);
1327ec681f3Smrg
1337ec681f3Smrg         changed = true;
1347ec681f3Smrg         ice->draw.params_valid = false;
1357ec681f3Smrg      } else {
1367ec681f3Smrg         int firstvertex = info->index_size ? draw->index_bias : draw->start;
1377ec681f3Smrg
1387ec681f3Smrg         if (!ice->draw.params_valid ||
1397ec681f3Smrg             ice->draw.params.firstvertex != firstvertex ||
1407ec681f3Smrg             ice->draw.params.baseinstance != info->start_instance) {
1417ec681f3Smrg
1427ec681f3Smrg            changed = true;
1437ec681f3Smrg            ice->draw.params.firstvertex = firstvertex;
1447ec681f3Smrg            ice->draw.params.baseinstance = info->start_instance;
1457ec681f3Smrg            ice->draw.params_valid = true;
1467ec681f3Smrg
1477ec681f3Smrg            u_upload_data(ice->ctx.const_uploader, 0,
1487ec681f3Smrg                          sizeof(ice->draw.params), 4, &ice->draw.params,
1497ec681f3Smrg                          &draw_params->offset, &draw_params->res);
1507ec681f3Smrg         }
1517ec681f3Smrg      }
1529f464c52Smaya   }
1539f464c52Smaya
1547ec681f3Smrg   if (ice->state.vs_uses_derived_draw_params) {
1557ec681f3Smrg      struct iris_state_ref *derived_params = &ice->draw.derived_draw_params;
1567ec681f3Smrg      int is_indexed_draw = info->index_size ? -1 : 0;
1577ec681f3Smrg
1587ec681f3Smrg      if (ice->draw.derived_params.drawid != drawid_offset ||
1597ec681f3Smrg          ice->draw.derived_params.is_indexed_draw != is_indexed_draw) {
1607ec681f3Smrg
1617ec681f3Smrg         changed = true;
1627ec681f3Smrg         ice->draw.derived_params.drawid = drawid_offset;
1637ec681f3Smrg         ice->draw.derived_params.is_indexed_draw = is_indexed_draw;
1647ec681f3Smrg
1657ec681f3Smrg         u_upload_data(ice->ctx.const_uploader, 0,
1667ec681f3Smrg                       sizeof(ice->draw.derived_params), 4,
1677ec681f3Smrg                       &ice->draw.derived_params,
1687ec681f3Smrg                       &derived_params->offset, &derived_params->res);
1697ec681f3Smrg      }
1707ec681f3Smrg   }
1717ec681f3Smrg
1727ec681f3Smrg   if (changed) {
1739f464c52Smaya      ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS |
1749f464c52Smaya                          IRIS_DIRTY_VERTEX_ELEMENTS |
1759f464c52Smaya                          IRIS_DIRTY_VF_SGVS;
1769f464c52Smaya   }
1779f464c52Smaya}
1789f464c52Smaya
1797ec681f3Smrgstatic void
1807ec681f3Smrgiris_indirect_draw_vbo(struct iris_context *ice,
1817ec681f3Smrg                       const struct pipe_draw_info *dinfo,
1827ec681f3Smrg                       unsigned drawid_offset,
1837ec681f3Smrg                       const struct pipe_draw_indirect_info *dindirect,
1847ec681f3Smrg                       const struct pipe_draw_start_count_bias *draw)
1857ec681f3Smrg{
1867ec681f3Smrg   struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
1877ec681f3Smrg   struct pipe_draw_info info = *dinfo;
1887ec681f3Smrg   struct pipe_draw_indirect_info indirect = *dindirect;
1897ec681f3Smrg
1907ec681f3Smrg   iris_emit_buffer_barrier_for(batch, iris_resource_bo(indirect.buffer),
1917ec681f3Smrg                                IRIS_DOMAIN_VF_READ);
1927ec681f3Smrg
1937ec681f3Smrg   if (indirect.indirect_draw_count) {
1947ec681f3Smrg      struct iris_bo *draw_count_bo =
1957ec681f3Smrg         iris_resource_bo(indirect.indirect_draw_count);
1967ec681f3Smrg      iris_emit_buffer_barrier_for(batch, draw_count_bo,
1977ec681f3Smrg                                   IRIS_DOMAIN_OTHER_READ);
1987ec681f3Smrg
1997ec681f3Smrg      if (ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
2007ec681f3Smrg         /* Upload MI_PREDICATE_RESULT to GPR15.*/
2017ec681f3Smrg         batch->screen->vtbl.load_register_reg64(batch, CS_GPR(15), MI_PREDICATE_RESULT);
2027ec681f3Smrg      }
2037ec681f3Smrg   }
2047ec681f3Smrg
2057ec681f3Smrg   const uint64_t orig_dirty = ice->state.dirty;
2067ec681f3Smrg   const uint64_t orig_stage_dirty = ice->state.stage_dirty;
2077ec681f3Smrg
2087ec681f3Smrg   for (int i = 0; i < indirect.draw_count; i++) {
2097ec681f3Smrg      iris_batch_maybe_flush(batch, 1500);
2107ec681f3Smrg
2117ec681f3Smrg      iris_update_draw_parameters(ice, &info, drawid_offset + i, &indirect, draw);
2127ec681f3Smrg
2137ec681f3Smrg      batch->screen->vtbl.upload_render_state(ice, batch, &info, drawid_offset + i, &indirect, draw);
2147ec681f3Smrg
2157ec681f3Smrg      ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
2167ec681f3Smrg      ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
2177ec681f3Smrg
2187ec681f3Smrg      indirect.offset += indirect.stride;
2197ec681f3Smrg   }
2207ec681f3Smrg
2217ec681f3Smrg   if (indirect.indirect_draw_count &&
2227ec681f3Smrg       ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
2237ec681f3Smrg      /* Restore MI_PREDICATE_RESULT. */
2247ec681f3Smrg      batch->screen->vtbl.load_register_reg64(batch, MI_PREDICATE_RESULT, CS_GPR(15));
2257ec681f3Smrg   }
2267ec681f3Smrg
2277ec681f3Smrg   /* Put this back for post-draw resolves, we'll clear it again after. */
2287ec681f3Smrg   ice->state.dirty = orig_dirty;
2297ec681f3Smrg   ice->state.stage_dirty = orig_stage_dirty;
2307ec681f3Smrg}
2317ec681f3Smrg
2327ec681f3Smrgstatic void
2337ec681f3Smrgiris_simple_draw_vbo(struct iris_context *ice,
2347ec681f3Smrg                     const struct pipe_draw_info *draw,
2357ec681f3Smrg                     unsigned drawid_offset,
2367ec681f3Smrg                     const struct pipe_draw_indirect_info *indirect,
2377ec681f3Smrg                     const struct pipe_draw_start_count_bias *sc)
2387ec681f3Smrg{
2397ec681f3Smrg   struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
2407ec681f3Smrg
2417ec681f3Smrg   iris_batch_maybe_flush(batch, 1500);
2427ec681f3Smrg
2437ec681f3Smrg   iris_update_draw_parameters(ice, draw, drawid_offset, indirect, sc);
2447ec681f3Smrg
2457ec681f3Smrg   batch->screen->vtbl.upload_render_state(ice, batch, draw, drawid_offset, indirect, sc);
2467ec681f3Smrg}
2477ec681f3Smrg
2489f464c52Smaya/**
2499f464c52Smaya * The pipe->draw_vbo() driver hook.  Performs a draw on the GPU.
2509f464c52Smaya */
2519f464c52Smayavoid
2527ec681f3Smrgiris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info,
2537ec681f3Smrg              unsigned drawid_offset,
2547ec681f3Smrg              const struct pipe_draw_indirect_info *indirect,
2557ec681f3Smrg              const struct pipe_draw_start_count_bias *draws,
2567ec681f3Smrg              unsigned num_draws)
2579f464c52Smaya{
2587ec681f3Smrg   if (num_draws > 1) {
2597ec681f3Smrg      util_draw_multi(ctx, info, drawid_offset, indirect, draws, num_draws);
2607ec681f3Smrg      return;
2617ec681f3Smrg   }
2627ec681f3Smrg
2637ec681f3Smrg   if (!indirect && (!draws[0].count || !info->instance_count))
2647ec681f3Smrg      return;
2657ec681f3Smrg
2669f464c52Smaya   struct iris_context *ice = (struct iris_context *) ctx;
2679f464c52Smaya   struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen;
2687ec681f3Smrg   const struct intel_device_info *devinfo = &screen->devinfo;
2699f464c52Smaya   struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
2709f464c52Smaya
2719f464c52Smaya   if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
2729f464c52Smaya      return;
2739f464c52Smaya
2747ec681f3Smrg   if (INTEL_DEBUG(DEBUG_REEMIT)) {
2757ec681f3Smrg      ice->state.dirty |= IRIS_ALL_DIRTY_FOR_RENDER;
2767ec681f3Smrg      ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
2777ec681f3Smrg   }
2789f464c52Smaya
2799f464c52Smaya   iris_update_draw_info(ice, info);
2809f464c52Smaya
2817ec681f3Smrg   if (devinfo->ver == 9)
2827ec681f3Smrg      gfx9_toggle_preemption(ice, batch, info);
2839f464c52Smaya
2849f464c52Smaya   iris_update_compiled_shaders(ice);
2859f464c52Smaya
2869f464c52Smaya   if (ice->state.dirty & IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES) {
2879f464c52Smaya      bool draw_aux_buffer_disabled[BRW_MAX_DRAW_BUFFERS] = { };
2889f464c52Smaya      for (gl_shader_stage stage = 0; stage < MESA_SHADER_COMPUTE; stage++) {
2899f464c52Smaya         if (ice->shaders.prog[stage])
2909f464c52Smaya            iris_predraw_resolve_inputs(ice, batch, draw_aux_buffer_disabled,
2919f464c52Smaya                                        stage, true);
2929f464c52Smaya      }
2939f464c52Smaya      iris_predraw_resolve_framebuffer(ice, batch, draw_aux_buffer_disabled);
2949f464c52Smaya   }
2959f464c52Smaya
2967ec681f3Smrg   if (ice->state.dirty & IRIS_DIRTY_RENDER_MISC_BUFFER_FLUSHES) {
2977ec681f3Smrg      for (gl_shader_stage stage = 0; stage < MESA_SHADER_COMPUTE; stage++)
2987ec681f3Smrg         iris_predraw_flush_buffers(ice, batch, stage);
2997ec681f3Smrg   }
3007ec681f3Smrg
3019f464c52Smaya   iris_binder_reserve_3d(ice);
3029f464c52Smaya
3037ec681f3Smrg   batch->screen->vtbl.update_surface_base_address(batch, &ice->state.binder);
3047ec681f3Smrg
3057ec681f3Smrg   iris_handle_always_flush_cache(batch);
3067ec681f3Smrg
3077ec681f3Smrg   if (indirect && indirect->buffer)
3087ec681f3Smrg      iris_indirect_draw_vbo(ice, info, drawid_offset, indirect, &draws[0]);
3097ec681f3Smrg   else
3107ec681f3Smrg      iris_simple_draw_vbo(ice, info, drawid_offset, indirect, &draws[0]);
3117ec681f3Smrg
3127ec681f3Smrg   iris_handle_always_flush_cache(batch);
3139f464c52Smaya
3149f464c52Smaya   iris_postdraw_update_resolve_tracking(ice, batch);
3159f464c52Smaya
3169f464c52Smaya   ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
3177ec681f3Smrg   ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
3189f464c52Smaya}
3199f464c52Smaya
3209f464c52Smayastatic void
3219f464c52Smayairis_update_grid_size_resource(struct iris_context *ice,
3229f464c52Smaya                               const struct pipe_grid_info *grid)
3239f464c52Smaya{
3249f464c52Smaya   const struct iris_screen *screen = (void *) ice->ctx.screen;
3259f464c52Smaya   const struct isl_device *isl_dev = &screen->isl_dev;
3269f464c52Smaya   struct iris_state_ref *grid_ref = &ice->state.grid_size;
3279f464c52Smaya   struct iris_state_ref *state_ref = &ice->state.grid_surf_state;
3289f464c52Smaya
3297ec681f3Smrg   const struct iris_compiled_shader *shader = ice->shaders.prog[MESA_SHADER_COMPUTE];
3307ec681f3Smrg   bool grid_needs_surface = shader->bt.used_mask[IRIS_SURFACE_GROUP_CS_WORK_GROUPS];
3317ec681f3Smrg   bool grid_updated = false;
3329f464c52Smaya
3339f464c52Smaya   if (grid->indirect) {
3349f464c52Smaya      pipe_resource_reference(&grid_ref->res, grid->indirect);
3359f464c52Smaya      grid_ref->offset = grid->indirect_offset;
3369f464c52Smaya
3379f464c52Smaya      /* Zero out the grid size so that the next non-indirect grid launch will
3389f464c52Smaya       * re-upload it properly.
3399f464c52Smaya       */
3409f464c52Smaya      memset(ice->state.last_grid, 0, sizeof(ice->state.last_grid));
3417ec681f3Smrg      grid_updated = true;
3427ec681f3Smrg   } else if (memcmp(ice->state.last_grid, grid->grid, sizeof(grid->grid)) != 0) {
3439f464c52Smaya      memcpy(ice->state.last_grid, grid->grid, sizeof(grid->grid));
3449f464c52Smaya      u_upload_data(ice->state.dynamic_uploader, 0, sizeof(grid->grid), 4,
3459f464c52Smaya                    grid->grid, &grid_ref->offset, &grid_ref->res);
3467ec681f3Smrg      grid_updated = true;
3479f464c52Smaya   }
3489f464c52Smaya
3497ec681f3Smrg   /* If we changed the grid, the old surface state is invalid. */
3507ec681f3Smrg   if (grid_updated)
3517ec681f3Smrg      pipe_resource_reference(&state_ref->res, NULL);
3527ec681f3Smrg
3537ec681f3Smrg   /* Skip surface upload if we don't need it or we already have one */
3547ec681f3Smrg   if (!grid_needs_surface || state_ref->res)
3557ec681f3Smrg      return;
3567ec681f3Smrg
3577ec681f3Smrg   struct iris_bo *grid_bo = iris_resource_bo(grid_ref->res);
3587ec681f3Smrg
3599f464c52Smaya   void *surf_map = NULL;
3609f464c52Smaya   u_upload_alloc(ice->state.surface_uploader, 0, isl_dev->ss.size,
3619f464c52Smaya                  isl_dev->ss.align, &state_ref->offset, &state_ref->res,
3629f464c52Smaya                  &surf_map);
3639f464c52Smaya   state_ref->offset +=
3649f464c52Smaya      iris_bo_offset_from_base_address(iris_resource_bo(state_ref->res));
3659f464c52Smaya   isl_buffer_fill_state(&screen->isl_dev, surf_map,
3667ec681f3Smrg                         .address = grid_ref->offset + grid_bo->address,
3679f464c52Smaya                         .size_B = sizeof(grid->grid),
3689f464c52Smaya                         .format = ISL_FORMAT_RAW,
3699f464c52Smaya                         .stride_B = 1,
3707ec681f3Smrg                         .mocs = iris_mocs(grid_bo, isl_dev,
3717ec681f3Smrg                                           ISL_SURF_USAGE_CONSTANT_BUFFER_BIT));
3729f464c52Smaya
3737ec681f3Smrg   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_CS;
3749f464c52Smaya}
3759f464c52Smaya
3769f464c52Smayavoid
3779f464c52Smayairis_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid)
3789f464c52Smaya{
3799f464c52Smaya   struct iris_context *ice = (struct iris_context *) ctx;
3809f464c52Smaya   struct iris_batch *batch = &ice->batches[IRIS_BATCH_COMPUTE];
3819f464c52Smaya
3829f464c52Smaya   if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
3839f464c52Smaya      return;
3849f464c52Smaya
3857ec681f3Smrg   if (INTEL_DEBUG(DEBUG_REEMIT)) {
3869f464c52Smaya      ice->state.dirty |= IRIS_ALL_DIRTY_FOR_COMPUTE;
3877ec681f3Smrg      ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE;
3889f464c52Smaya   }
3899f464c52Smaya
3907ec681f3Smrg   if (ice->state.dirty & IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES)
3917ec681f3Smrg      iris_predraw_resolve_inputs(ice, batch, NULL, MESA_SHADER_COMPUTE, false);
3927ec681f3Smrg
3937ec681f3Smrg   if (ice->state.dirty & IRIS_DIRTY_COMPUTE_MISC_BUFFER_FLUSHES)
3947ec681f3Smrg      iris_predraw_flush_buffers(ice, batch, MESA_SHADER_COMPUTE);
3957ec681f3Smrg
3969f464c52Smaya   iris_batch_maybe_flush(batch, 1500);
3979f464c52Smaya
3987ec681f3Smrg   iris_update_compiled_compute_shader(ice);
3997ec681f3Smrg
4007ec681f3Smrg   if (memcmp(ice->state.last_block, grid->block, sizeof(grid->block)) != 0) {
4017ec681f3Smrg      memcpy(ice->state.last_block, grid->block, sizeof(grid->block));
4027ec681f3Smrg      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_CS;
4037ec681f3Smrg      ice->state.shaders[MESA_SHADER_COMPUTE].sysvals_need_upload = true;
4047ec681f3Smrg   }
4059f464c52Smaya
4069f464c52Smaya   iris_update_grid_size_resource(ice, grid);
4079f464c52Smaya
4089f464c52Smaya   iris_binder_reserve_compute(ice);
4097ec681f3Smrg   batch->screen->vtbl.update_surface_base_address(batch, &ice->state.binder);
4109f464c52Smaya
4119f464c52Smaya   if (ice->state.compute_predicate) {
4127ec681f3Smrg      batch->screen->vtbl.load_register_mem64(batch, MI_PREDICATE_RESULT,
4139f464c52Smaya                                    ice->state.compute_predicate, 0);
4149f464c52Smaya      ice->state.compute_predicate = NULL;
4159f464c52Smaya   }
4169f464c52Smaya
4177ec681f3Smrg   iris_handle_always_flush_cache(batch);
4187ec681f3Smrg
4197ec681f3Smrg   batch->screen->vtbl.upload_compute_state(ice, batch, grid);
4207ec681f3Smrg
4217ec681f3Smrg   iris_handle_always_flush_cache(batch);
4229f464c52Smaya
4239f464c52Smaya   ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_COMPUTE;
4247ec681f3Smrg   ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE;
4259f464c52Smaya
4269f464c52Smaya   /* Note: since compute shaders can't access the framebuffer, there's
4279f464c52Smaya    * no need to call iris_postdraw_update_resolve_tracking.
4289f464c52Smaya    */
4299f464c52Smaya}
430