iris: Track a binding history for buffer resources
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 21 Nov 2018 08:38:49 +0000 (00:38 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:10 +0000 (10:26 -0800)
This will let us know what caches to flush / state to dirty when
altering the contents of a buffer.

src/gallium/drivers/iris/iris_query.c
src/gallium/drivers/iris/iris_resource.h
src/gallium/drivers/iris/iris_state.c

index 145fb5c7416cdffcb723c8a2adbc5545c93f0071..65051905d972c5dcf8e38e935a5f9887610441d4 100644 (file)
@@ -489,9 +489,12 @@ iris_get_query_result_resource(struct pipe_context *ctx,
    struct iris_query *q = (void *) query;
    struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
    const struct gen_device_info *devinfo = &batch->screen->devinfo;
+   struct iris_resource *res = (void *) p_res;
    unsigned snapshots_landed_offset =
       offsetof(struct iris_query_snapshots, snapshots_landed);
 
+   res->bind_history |= PIPE_BIND_QUERY_BUFFER;
+
    if (index == -1) {
       /* They're asking for the availability of the result.  If we still
        * have commands queued up which produce the result, submit them
index 14a780a9011ac0c83bc3d2c10fe3378d6c5a331f..6ec73de39b944a39c4a8d6c3bf036e9378811ed6 100644 (file)
@@ -46,6 +46,12 @@ struct iris_resource {
    enum pipe_format internal_format;
    struct isl_surf surf;
    struct iris_bo *bo;
+
+   /**
+    * A bitfield of PIPE_BIND_* indicating how this resource was bound
+    * in the past.  Only meaningful for PIPE_BUFFER; used for flushing.
+    */
+   unsigned bind_history;
 };
 
 /**
index 7c898a6cd851ff74e9ed1f19914049366d32aa55..36b9fdb9ab7520a37b6f3c07ffae0f100da8db13 100644 (file)
@@ -1672,6 +1672,8 @@ iris_set_shader_images(struct pipe_context *ctx,
          struct iris_resource *res = (void *) img->resource;
          pipe_resource_reference(&shs->image[start_slot + i].res, &res->base);
 
+         res->bind_history |= PIPE_BIND_SHADER_IMAGE;
+
          // XXX: these are not retained forever, use a separate uploader?
          void *map =
             upload_state(ice->state.surface_uploader,
@@ -1746,6 +1748,9 @@ iris_set_sampler_views(struct pipe_context *ctx,
    for (i = 0; i < count; i++) {
       pipe_sampler_view_reference((struct pipe_sampler_view **)
                                   &shs->textures[i], views[i]);
+      struct iris_sampler_view *view = (void *) views[i];
+      if (view)
+         view->res->bind_history |= PIPE_BIND_SAMPLER_VIEW;
    }
    for (; i < shs->num_textures; i++) {
       pipe_sampler_view_reference((struct pipe_sampler_view **)
@@ -2181,6 +2186,9 @@ iris_set_constant_buffer(struct pipe_context *ctx,
       pipe_resource_reference(&cbuf->data.res, input->buffer);
       cbuf->data.offset = input->buffer_offset;
 
+      struct iris_resource *res = (void *) cbuf->data.res;
+      res->bind_history |= PIPE_BIND_CONSTANT_BUFFER;
+
       upload_ubo_surf_state(ice, cbuf, input->buffer_size);
    } else {
       pipe_resource_reference(&cbuf->data.res, NULL);
@@ -2265,6 +2273,8 @@ iris_set_shader_buffers(struct pipe_context *ctx,
          struct iris_resource *res = (void *) buffer->buffer;
          pipe_resource_reference(&shs->ssbo[start_slot + i], &res->base);
 
+         res->bind_history |= PIPE_BIND_SHADER_BUFFER;
+
          // XXX: these are not retained forever, use a separate uploader?
          void *map =
             upload_state(ice->state.surface_uploader,
@@ -2352,6 +2362,9 @@ iris_set_vertex_buffers(struct pipe_context *ctx,
       pipe_resource_reference(&cso->resources[i], buffers[i].buffer.resource);
       struct iris_resource *res = (void *) cso->resources[i];
 
+      if (res)
+         res->bind_history |= PIPE_BIND_VERTEX_BUFFER;
+
       iris_pack_state(GENX(VERTEX_BUFFER_STATE), vb_pack_dest, vb) {
          vb.VertexBufferIndex = start_slot + i;
          vb.MOCS = MOCS_WB;
@@ -2507,16 +2520,19 @@ struct iris_stream_output_target {
  */
 static struct pipe_stream_output_target *
 iris_create_stream_output_target(struct pipe_context *ctx,
-                                 struct pipe_resource *res,
+                                 struct pipe_resource *p_res,
                                  unsigned buffer_offset,
                                  unsigned buffer_size)
 {
+   struct iris_resource *res = (void *) p_res;
    struct iris_stream_output_target *cso = calloc(1, sizeof(*cso));
    if (!cso)
       return NULL;
 
+   res->bind_history |= PIPE_BIND_STREAM_OUTPUT;
+
    pipe_reference_init(&cso->base.reference, 1);
-   pipe_resource_reference(&cso->base.buffer, res);
+   pipe_resource_reference(&cso->base.buffer, p_res);
    cso->base.buffer_offset = buffer_offset;
    cso->base.buffer_size = buffer_size;
    cso->base.context = ctx;
@@ -2525,7 +2541,7 @@ iris_create_stream_output_target(struct pipe_context *ctx,
 
    iris_pack_command(GENX(3DSTATE_SO_BUFFER), cso->so_buffer, sob) {
       sob.SurfaceBaseAddress =
-         rw_bo(NULL, iris_resource_bo(res)->gtt_offset + buffer_offset);
+         rw_bo(NULL, res->bo->gtt_offset + buffer_offset);
       sob.SOBufferEnable = true;
       sob.StreamOffsetWriteEnable = true;
       sob.StreamOutputBufferOffsetAddressEnable = true;
@@ -4436,6 +4452,9 @@ iris_upload_render_state(struct iris_context *ice,
                        draw->count * draw->index_size, 4, draw->index.user,
                        &offset, &ice->state.last_res.index_buffer);
       } else {
+         struct iris_resource *res = (void *) draw->index.resource;
+         res->bind_history |= PIPE_BIND_INDEX_BUFFER;
+
          pipe_resource_reference(&ice->state.last_res.index_buffer,
                                  draw->index.resource);
          offset = 0;