Skip to content

WIP: anv: Emit compute batch when changing from compute to 3d pipeline

Danylo Piliaiev requested to merge GL/mesa:fix/anv-geometry-flickering into master

Without doing this there is a geometry flickering in games which use compute shaders - something goes wrong with binding tables if there is MEDIA_INTERFACE_DESCRIPTOR_LOAD before 3d pipeline.

Bugzilla:
https://bugs.freedesktop.org/show_bug.cgi?id=109630
https://bugs.freedesktop.org/show_bug.cgi?id=109616
https://bugs.freedesktop.org/show_bug.cgi?id=110295

I'm not sure why it fixes the issue hence the WIP. However I think it is much closer to truth than reemitting binding tables which was previous workaround. @jekstrand

About MEDIA_INTERFACE_DESCRIPTOR_LOAD from my comment in bugzilla

A part of the dispatch which seems to lead to the issue is MEDIA_INTERFACE_DESCRIPTOR_LOAD, commenting out everything unnecessary around doesn't make flickering disappear, the moment MEDIA_INTERFACE_DESCRIPTOR_LOAD is commented out - no flicker.

So the minimal reproduction will be commenting out the dispatch and adding this at the start of cmd_buffer_flush_state:

   if((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) &&
      cmd_buffer->state.compute.base.pipeline)
   {
      struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline;
      genX(flush_pipeline_select_gpgpu)(cmd_buffer);
      cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_CS_STALL_BIT;
      genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);

      struct anv_state state =
         anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
               GENX(INTERFACE_DESCRIPTOR_DATA_length), 64);

      uint32_t size = GENX(INTERFACE_DESCRIPTOR_DATA_length) * sizeof(uint32_t);
      anv_batch_emit(&cmd_buffer->batch,
                     GENX(MEDIA_INTERFACE_DESCRIPTOR_LOAD), mid) {
         mid.InterfaceDescriptorTotalLength        = size;
         mid.InterfaceDescriptorDataStartAddress   = 0;
      }

      // Just to be sure...
      cmd_buffer->state.gfx.dirty = ~0;
      cmd_buffer->state.gfx.vb_dirty = ~0;
      cmd_buffer->state.pending_pipe_bits = ~0;
      cmd_buffer->state.descriptors_dirty = ~0;
      cmd_buffer->state.push_constants_dirty = ~0;
   }

Which produces the same issue.

Merge request reports