[Mesa-dev] [PATCH 06/14] intel/blorp: Add initial support for indirect clear colors

Jason Ekstrand jason at jlekstrand.net
Mon Nov 27 15:39:14 UTC 2017


On Wed, Nov 22, 2017 at 12:57 PM, Nanley Chery <nanleychery at gmail.com>
wrote:

> On Mon, Nov 13, 2017 at 08:12:46AM -0800, Jason Ekstrand wrote:
> > ---
> >  src/intel/blorp/blorp.c                     |  1 +
> >  src/intel/blorp/blorp.h                     |  7 +++
> >  src/intel/blorp/blorp_genX_exec.h           | 77
> +++++++++++++++++++++++++++++
> >  src/intel/blorp/blorp_priv.h                |  1 +
> >  src/intel/vulkan/genX_blorp_exec.c          | 10 ++++
> >  src/mesa/drivers/dri/i965/genX_blorp_exec.c | 13 +++++
> >  6 files changed, 109 insertions(+)
> >
> > diff --git a/src/intel/blorp/blorp.c b/src/intel/blorp/blorp.c
> > index 5faba75..8a9d2fd 100644
> > --- a/src/intel/blorp/blorp.c
> > +++ b/src/intel/blorp/blorp.c
> > @@ -100,6 +100,7 @@ brw_blorp_surface_info_init(struct blorp_context
> *blorp,
> >     }
> >
> >     info->clear_color = surf->clear_color;
> > +   info->clear_color_addr = surf->clear_color_addr;
> >
> >     info->view = (struct isl_view) {
> >        .usage = is_render_target ? ISL_SURF_USAGE_RENDER_TARGET_BIT :
> > diff --git a/src/intel/blorp/blorp.h b/src/intel/blorp/blorp.h
> > index 9716c66..c3077aa 100644
> > --- a/src/intel/blorp/blorp.h
> > +++ b/src/intel/blorp/blorp.h
> > @@ -106,6 +106,13 @@ struct blorp_surf
> >     enum isl_aux_usage aux_usage;
> >
> >     union isl_color_value clear_color;
> > +
> > +   /** If set (bo != NULL), clear_color is ignored and the actual clear
> color
>
> The first line of the comment should be blank.
>

Sure


> > +    * this is fetched from this address.  On gen7-8, this is all of
> dword 7 of
>          ^
>          Extra word.
>

Thanks.


> > +    * RENDER_SURFACE_STATE and is the responsibility of the caller to
> ensure
> > +    * that it contains a swizzle of RGBA and resource min LOD of 0.
> > +    */
> > +   struct blorp_address clear_color_addr;
> >  };
> >
> >  void
> > diff --git a/src/intel/blorp/blorp_genX_exec.h
> b/src/intel/blorp/blorp_genX_exec.h
> > index 5389262..4f88650 100644
> > --- a/src/intel/blorp/blorp_genX_exec.h
> > +++ b/src/intel/blorp/blorp_genX_exec.h
> > @@ -78,6 +78,11 @@ static void
> >  blorp_surface_reloc(struct blorp_batch *batch, uint32_t ss_offset,
> >                      struct blorp_address address, uint32_t delta);
> >
> > +#if GEN_GEN >= 7
> > +static struct blorp_address
> > +blorp_get_surface_base_address(struct blorp_batch *batch);
> > +#endif
> > +
> >  static void
> >  blorp_emit_urb_config(struct blorp_batch *batch,
> >                        unsigned vs_entry_size, unsigned sf_entry_size);
> > @@ -1202,6 +1207,42 @@ blorp_emit_pipeline(struct blorp_batch *batch,
> >
> >  #endif /* GEN_GEN >= 6 */
> >
> > +#if GEN_GEN >= 7 && GEN_GEN <= 10
> > +static void
> > +blorp_emit_memcpy(struct blorp_batch *batch,
> > +                  struct blorp_address dst,
> > +                  struct blorp_address src,
> > +                  uint32_t size)
> > +{
> > +   assert(size % 4 == 0);
> > +
> > +   for (unsigned dw = 0; dw < size; dw += 4) {
> > +#if GEN_GEN >= 8
> > +      blorp_emit(batch, GENX(MI_COPY_MEM_MEM), cp) {
> > +         cp.DestinationMemoryAddress = dst;
> > +         cp.SourceMemoryAddress = src;
> > +      }
> > +#else
> > +      /* IVB does not have a general purpose register for command
> streamer
> > +       * commands. Therefore, we use an alternate temporary register.
> > +       */
> > +#define BLORP_TEMP_REG 0x2440 /* GEN7_3DPRIM_BASE_VERTEX */
> > +      blorp_emit(batch, GENX(MI_LOAD_REGISTER_MEM), load) {
> > +         load.RegisterAddress = BLORP_TEMP_REG;
> > +         load.MemoryAddress = src;
> > +      }
> > +      blorp_emit(batch, GENX(MI_STORE_REGISTER_MEM), store) {
> > +         store.RegisterAddress = BLORP_TEMP_REG;
> > +         store.MemoryAddress = dst;
> > +      }
> > +#undef BLORP_TEMP_REG
> > +#endif
> > +      dst.offset += 4;
> > +      src.offset += 4;
> > +   }
> > +}
> > +#endif
> > +
> >  static void
> >  blorp_emit_surface_state(struct blorp_batch *batch,
> >                           const struct brw_blorp_surface_info *surface,
> > @@ -1259,6 +1300,20 @@ blorp_emit_surface_state(struct blorp_batch
> *batch,
> >     }
> >
> >     blorp_flush_range(batch, state, GENX(RENDER_SURFACE_STATE_length) *
> 4);
> > +
> > +#if GEN_GEN > 10
> > +#  error("Implement indirect clear support on gen11+")
> > +#elif GEN_GEN >= 7 && GEN_GEN <= 10
>
> Could we move the #if/elif block under the if statement below and use
> assert(!str) instead of #error? Otherwise we can't run any tests on
> gen11+ until this feature is implemented.
>

Yeah, I think that's reasonable.


> -Nanley
>
> > +   if (surface->clear_color_addr.buffer) {
> > +      struct blorp_address dst_addr = blorp_get_surface_base_
> address(batch);
> > +      dst_addr.offset += state_offset + isl_dev->ss.clear_value_offset;
> > +      blorp_emit_memcpy(batch, dst_addr, surface->clear_color_addr,
> > +                        isl_dev->ss.clear_value_size);
> > +   }
> > +#else
> > +   /* Indirect clears are only supported on gen7+ */
> > +   assert(surface->clear_color_addr.buffer == NULL);
> > +#endif
> >  }
> >
> >  static void
> > @@ -1303,6 +1358,7 @@ blorp_emit_surface_states(struct blorp_batch
> *batch,
> >     uint32_t bind_offset, surface_offsets[2];
> >     void *surface_maps[2];
> >
> > +   MAYBE_UNUSED bool has_indirect_clear_color = false;
> >     if (params->use_pre_baked_binding_table) {
> >        bind_offset = params->pre_baked_binding_table_offset;
> >     } else {
> > @@ -1316,6 +1372,8 @@ blorp_emit_surface_states(struct blorp_batch
> *batch,
> >                                    surface_maps[BLORP_
> RENDERBUFFER_BT_INDEX],
> >                                    surface_offsets[BLORP_
> RENDERBUFFER_BT_INDEX],
> >                                    params->color_write_disable, true);
> > +         if (params->dst.clear_color_addr.buffer != NULL)
> > +            has_indirect_clear_color = true;
> >        } else {
> >           assert(params->depth.enabled || params->stencil.enabled);
> >           const struct brw_blorp_surface_info *surface =
> > @@ -1329,9 +1387,28 @@ blorp_emit_surface_states(struct blorp_batch
> *batch,
> >                                    surface_maps[BLORP_TEXTURE_BT_INDEX],
> >                                    surface_offsets[BLORP_TEXTURE_
> BT_INDEX],
> >                                    NULL, false);
> > +         if (params->src.clear_color_addr.buffer != NULL)
> > +            has_indirect_clear_color = true;
> >        }
> >     }
> >
> > +#if GEN_GEN >= 7 && GEN_GEN <= 10
> > +   if (has_indirect_clear_color) {
> > +      /* Updating a surface state object may require that the state
> cache be
> > +       * invalidated. From the SKL PRM, Shared Functions -> State ->
> State
> > +       * Caching:
> > +       *
> > +       *    Whenever the RENDER_SURFACE_STATE object in memory pointed
> to by
> > +       *    the Binding Table Pointer (BTP) and Binding Table Index
> (BTI) is
> > +       *    modified [...], the L1 state cache must be invalidated to
> ensure
> > +       *    the new surface or sampler state is fetched from system
> memory.
> > +       */
> > +      blorp_emit(batch, GENX(PIPE_CONTROL), pipe) {
> > +         pipe.StateCacheInvalidationEnable = true;
> > +      }
> > +   }
> > +#endif
> > +
> >  #if GEN_GEN >= 7
> >     blorp_emit(batch, GENX(3DSTATE_BINDING_TABLE_POINTERS_VS), bt);
> >     blorp_emit(batch, GENX(3DSTATE_BINDING_TABLE_POINTERS_HS), bt);
> > diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h
> > index d91e436..faa0af1 100644
> > --- a/src/intel/blorp/blorp_priv.h
> > +++ b/src/intel/blorp/blorp_priv.h
> > @@ -56,6 +56,7 @@ struct brw_blorp_surface_info
> >     enum isl_aux_usage aux_usage;
> >
> >     union isl_color_value clear_color;
> > +   struct blorp_address clear_color_addr;
> >
> >     struct isl_view view;
> >
> > diff --git a/src/intel/vulkan/genX_blorp_exec.c
> b/src/intel/vulkan/genX_blorp_exec.c
> > index f041fc7..817b530 100644
> > --- a/src/intel/vulkan/genX_blorp_exec.c
> > +++ b/src/intel/vulkan/genX_blorp_exec.c
> > @@ -64,6 +64,16 @@ blorp_surface_reloc(struct blorp_batch *batch,
> uint32_t ss_offset,
> >        anv_batch_set_error(&cmd_buffer->batch, result);
> >  }
> >
> > +static struct blorp_address
> > +blorp_get_surface_base_address(struct blorp_batch *batch)
> > +{
> > +   struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
> > +   return (struct blorp_address) {
> > +      .buffer = &cmd_buffer->device->surface_state_pool.block_pool.bo,
> > +      .offset = 0,
> > +   };
> > +}
> > +
> >  static void *
> >  blorp_alloc_dynamic_state(struct blorp_batch *batch,
> >                            uint32_t size,
> > diff --git a/src/mesa/drivers/dri/i965/genX_blorp_exec.c
> b/src/mesa/drivers/dri/i965/genX_blorp_exec.c
> > index 3c7a7b4..e47db59 100644
> > --- a/src/mesa/drivers/dri/i965/genX_blorp_exec.c
> > +++ b/src/mesa/drivers/dri/i965/genX_blorp_exec.c
> > @@ -94,6 +94,19 @@ blorp_surface_reloc(struct blorp_batch *batch,
> uint32_t ss_offset,
> >  #endif
> >  }
> >
> > +#if GEN_GEN >= 7
> > +static struct blorp_address
> > +blorp_get_surface_base_address(struct blorp_batch *batch)
> > +{
> > +   assert(batch->blorp->driver_ctx == batch->driver_batch);
> > +   struct brw_context *brw = batch->driver_batch;
> > +   return (struct blorp_address) {
> > +      .buffer = brw->batch.state_bo,
> > +      .offset = 0,
> > +   };
> > +}
> > +#endif
> > +
> >  static void *
> >  blorp_alloc_dynamic_state(struct blorp_batch *batch,
> >                            uint32_t size,
> > --
> > 2.5.0.400.gff86faf
> >
> > _______________________________________________
> > mesa-dev mailing list
> > mesa-dev at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20171127/4ec18634/attachment.html>


More information about the mesa-dev mailing list