iris: state ref tuple
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 28 Jun 2018 07:57:49 +0000 (00:57 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:07 +0000 (10:26 -0800)
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_program_cache.c
src/gallium/drivers/iris/iris_resource.h
src/gallium/drivers/iris/iris_state.c

index 5e6b9e0228003a2c38e7cbaf1aa57828cb8467b6..597dfc2806592ee7141275d6c3a383873a8d00c8 100644 (file)
@@ -30,6 +30,7 @@
 #include "intel/common/gen_debug.h"
 #include "intel/compiler/brw_compiler.h"
 #include "iris_batch.h"
+#include "iris_resource.h"
 #include "iris_screen.h"
 
 struct iris_bo;
@@ -157,8 +158,8 @@ enum pipe_control_flags
 /** @} */
 
 struct iris_compiled_shader {
-   /** Buffer containing the uploaded assembly. */
-   struct pipe_resource *buffer;
+   /** Reference to the uploaded assembly. */
+   struct iris_state_ref assembly;
 
    /** Pointer to the assembly in the BO's map. */
    void *map;
@@ -166,9 +167,6 @@ struct iris_compiled_shader {
    /** The program data (owned by the program cache hash table) */
    struct brw_stage_prog_data *prog_data;
 
-   /** Offset where the assembly lives in the BO. */
-   unsigned offset;
-
    /**
     * Shader packets and other data derived from prog_data.  These must be
     * completely determined from prog_data.
@@ -178,12 +176,10 @@ struct iris_compiled_shader {
 
 struct iris_const_buffer {
    /** The resource and offset for the actual constant data */
-   struct pipe_resource *resource;
-   unsigned offset;
+   struct iris_state_ref data;
 
    /** The resource and offset for the SURFACE_STATE for pull access. */
-   struct pipe_resource *surface_state_resource;
-   unsigned surface_state_offset;
+   struct iris_state_ref surface_state;
 };
 
 struct iris_shader_state {
@@ -262,15 +258,13 @@ struct iris_context {
       struct pipe_framebuffer_state framebuffer;
       struct iris_depth_buffer_state *cso_depthbuffer;
 
-      struct pipe_resource *sampler_table_resource[MESA_SHADER_STAGES];
-      uint32_t sampler_table_offset[MESA_SHADER_STAGES];
+      struct iris_state_ref sampler_table[MESA_SHADER_STAGES];
       struct iris_sampler_state *samplers[MESA_SHADER_STAGES][IRIS_MAX_TEXTURE_SAMPLERS];
       struct iris_sampler_view *textures[MESA_SHADER_STAGES][IRIS_MAX_TEXTURE_SAMPLERS];
       unsigned num_samplers[MESA_SHADER_STAGES];
       unsigned num_textures[MESA_SHADER_STAGES];
 
-      struct pipe_resource *unbound_tex_surface_state_resource;
-      unsigned unbound_tex_surface_state_offset;
+      struct iris_state_ref unbound_tex;
 
       struct u_upload_mgr *surface_uploader;
       // XXX: may want a separate uploader for "hey I made a CSO!" vs
index 700648f0d4e9fa8e213f0cac998b9c109c84ede1..17e92566392dd42e5d8edeadb47318f80c7a8df0 100644 (file)
@@ -229,13 +229,14 @@ iris_upload_shader(struct iris_context *ice,
     * backend.
     */
    if (existing) {
-      pipe_resource_reference(&shader->buffer, existing->buffer);
-      shader->offset = existing->offset;
+      pipe_resource_reference(&shader->assembly.res, existing->assembly.res);
+      shader->assembly.offset = existing->assembly.offset;
       shader->map = existing->map;
    } else {
-      shader->buffer = NULL;
-      u_upload_alloc(ice->shaders.uploader, 0, prog_data->program_size,
-                     64, &shader->offset, &shader->buffer, &shader->map);
+      shader->assembly.res = NULL;
+      u_upload_alloc(ice->shaders.uploader, 0, prog_data->program_size, 64,
+                     &shader->assembly.offset, &shader->assembly.res,
+                     &shader->map);
       memcpy(shader->map, assembly, prog_data->program_size);
    }
 
@@ -290,8 +291,9 @@ iris_blorp_lookup_shader(struct blorp_batch *blorp_batch,
    if (!shader)
       return false;
 
-   struct iris_bo *bo = iris_resource_bo(shader->buffer);
-   *kernel_out = iris_bo_offset_from_base_address(bo) + shader->offset;
+   struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
+   *kernel_out =
+      iris_bo_offset_from_base_address(bo) + shader->assembly.offset;
    *((void **) prog_data_out) = shader->prog_data;
 
    iris_use_pinned_bo(batch, bo, false);
@@ -318,8 +320,9 @@ iris_blorp_upload_shader(struct blorp_batch *blorp_batch,
       iris_upload_shader(ice, IRIS_CACHE_BLORP, key_size, key, kernel,
                          prog_data);
 
-   struct iris_bo *bo = iris_resource_bo(shader->buffer);
-   *kernel_out = iris_bo_offset_from_base_address(bo) + shader->offset;
+   struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
+   *kernel_out =
+      iris_bo_offset_from_base_address(bo) + shader->assembly.offset;
    *((void **) prog_data_out) = shader->prog_data;
 
    iris_use_pinned_bo(batch, bo, false);
@@ -347,7 +350,7 @@ iris_destroy_program_cache(struct iris_context *ice)
 
    hash_table_foreach(ice->shaders.cache, entry) {
       struct iris_compiled_shader *shader = entry->data;
-      pipe_resource_reference(&shader->buffer, NULL);
+      pipe_resource_reference(&shader->assembly.res, NULL);
    }
 
    u_upload_destroy(ice->shaders.uploader);
index 45b8cf6a6c7847449a997cb10e9fdf37221f7f17..3280dc1c49cd8adf2d15fe1f0f3871fe5dd55018 100644 (file)
@@ -33,6 +33,15 @@ struct iris_resource {
    struct iris_bo *bo;
 };
 
+/**
+ * A simple <resource, offset> tuple for storing a reference to a
+ * piece of state stored in a GPU buffer object.
+ */
+struct iris_state_ref {
+   struct pipe_resource *res;
+   uint32_t offset;
+};
+
 enum isl_format iris_isl_format_for_pipe_format(enum pipe_format pf);
 
 void iris_init_screen_resource_functions(struct pipe_screen *pscreen);
@@ -49,8 +58,7 @@ struct iris_surface {
    struct isl_view view;
 
    /** The resource (BO) holding our SURFACE_STATE. */
-   struct pipe_resource *surface_state_resource;
-   unsigned surface_state_offset;
+   struct iris_state_ref surface_state;
 };
 
 #endif
index 4efef936ac4c3286055d87d1ccceb9a0c2fb5a87..5bfab87a0ce5b3a6c024554fd99b558b0c0663a7 100644 (file)
@@ -276,6 +276,17 @@ ro_bo(struct iris_bo *bo, uint64_t offset)
    return (struct iris_address) { .bo = bo, .offset = offset };
 }
 
+static void *
+upload_state(struct u_upload_mgr *uploader,
+             struct iris_state_ref *ref,
+             unsigned size,
+             unsigned alignment)
+{
+   void *p = NULL;
+   u_upload_alloc(uploader, 0, size, alignment, &ref->offset, &ref->res, &p);
+   return p;
+}
+
 static uint32_t *
 stream_state(struct iris_batch *batch,
              struct u_upload_mgr *uploader,
@@ -861,17 +872,14 @@ iris_bind_sampler_states(struct pipe_context *ctx,
    /* Assemble the SAMPLER_STATEs into a contiguous chunk of memory
     * relative to Dynamic State Base Address.
     */
-   void *map = NULL;
-   u_upload_alloc(ice->state.dynamic_uploader, 0,
-                  count * 4 * GENX(SAMPLER_STATE_length), 32,
-                  &ice->state.sampler_table_offset[stage],
-                  &ice->state.sampler_table_resource[stage],
-                  &map);
+   void *map = upload_state(ice->state.dynamic_uploader,
+                            &ice->state.sampler_table[stage],
+                            count * 4 * GENX(SAMPLER_STATE_length), 32);
    if (unlikely(!map))
       return;
 
-   struct pipe_resource *res = ice->state.sampler_table_resource[stage];
-   ice->state.sampler_table_offset[stage] +=
+   struct pipe_resource *res = ice->state.sampler_table[stage].res;
+   ice->state.sampler_table[stage].offset +=
       iris_bo_offset_from_base_address(iris_resource_bo(res));
 
    for (int i = 0; i < count; i++) {
@@ -898,8 +906,7 @@ struct iris_sampler_view {
    struct isl_view view;
 
    /** The resource (BO) holding our SURFACE_STATE. */
-   struct pipe_resource *surface_state_resource;
-   unsigned surface_state_offset;
+   struct iris_state_ref surface_state;
 };
 
 /**
@@ -958,17 +965,13 @@ iris_create_sampler_view(struct pipe_context *ctx,
       .usage = ISL_SURF_USAGE_TEXTURE_BIT,
    };
 
-   void *map = NULL;
-   u_upload_alloc(ice->state.surface_uploader, 0,
-                  4 * GENX(RENDER_SURFACE_STATE_length), 64,
-                  &isv->surface_state_offset,
-                  &isv->surface_state_resource,
-                  &map);
+   void *map = upload_state(ice->state.surface_uploader, &isv->surface_state,
+                            4 * GENX(RENDER_SURFACE_STATE_length), 64);
    if (!unlikely(map))
       return NULL;
 
-   struct iris_bo *state_bo = iris_resource_bo(isv->surface_state_resource);
-   isv->surface_state_offset += iris_bo_offset_from_base_address(state_bo);
+   struct iris_bo *state_bo = iris_resource_bo(isv->surface_state.res);
+   isv->surface_state.offset += iris_bo_offset_from_base_address(state_bo);
 
    isl_surf_fill_state(&screen->isl_dev, map,
                        .surf = &itex->surf, .view = &isv->view,
@@ -1028,17 +1031,14 @@ iris_create_surface(struct pipe_context *ctx,
                           ISL_SURF_USAGE_STENCIL_BIT))
       return psurf;
 
-   void *map = NULL;
-   u_upload_alloc(ice->state.surface_uploader, 0,
-                  4 * GENX(RENDER_SURFACE_STATE_length), 64,
-                  &surf->surface_state_offset,
-                  &surf->surface_state_resource,
-                  &map);
+
+   void *map = upload_state(ice->state.surface_uploader, &surf->surface_state,
+                            4 * GENX(RENDER_SURFACE_STATE_length), 64);
    if (!unlikely(map))
       return NULL;
 
-   struct iris_bo *state_bo = iris_resource_bo(surf->surface_state_resource);
-   surf->surface_state_offset += iris_bo_offset_from_base_address(state_bo);
+   struct iris_bo *state_bo = iris_resource_bo(surf->surface_state.res);
+   surf->surface_state.offset += iris_bo_offset_from_base_address(state_bo);
 
    isl_surf_fill_state(&screen->isl_dev, map,
                        .surf = &res->surf, .view = &surf->view,
@@ -1361,36 +1361,34 @@ iris_set_constant_buffer(struct pipe_context *ctx,
    if (input && (input->buffer || input->user_buffer)) {
       if (input->user_buffer) {
          u_upload_data(ctx->const_uploader, 0, input->buffer_size, 32,
-                       input->user_buffer, &cbuf->offset, &cbuf->resource);
+                       input->user_buffer, &cbuf->data.offset,
+                       &cbuf->data.res);
       } else {
-         pipe_resource_reference(&cbuf->resource, input->buffer);
+         pipe_resource_reference(&cbuf->data.res, input->buffer);
       }
 
-      void *map = NULL;
       // XXX: these are not retained forever, use a separate uploader?
-      u_upload_alloc(ice->state.surface_uploader, 0,
-                     4 * GENX(RENDER_SURFACE_STATE_length), 64,
-                     &cbuf->surface_state_offset,
-                     &cbuf->surface_state_resource,
-                     &map);
+      void *map =
+         upload_state(ice->state.surface_uploader, &cbuf->surface_state,
+                      4 * GENX(RENDER_SURFACE_STATE_length), 64);
       if (!unlikely(map)) {
-         pipe_resource_reference(&cbuf->resource, NULL);
+         pipe_resource_reference(&cbuf->data.res, NULL);
          return;
       }
 
-      struct iris_resource *res = (void *) cbuf->resource;
-      struct iris_bo *surf_bo = iris_resource_bo(cbuf->surface_state_resource);
-      cbuf->surface_state_offset += iris_bo_offset_from_base_address(surf_bo);
+      struct iris_resource *res = (void *) cbuf->data.res;
+      struct iris_bo *surf_bo = iris_resource_bo(cbuf->surface_state.res);
+      cbuf->surface_state.offset += iris_bo_offset_from_base_address(surf_bo);
 
       isl_buffer_fill_state(&screen->isl_dev, map,
-                            .address = res->bo->gtt_offset + cbuf->offset,
+                            .address = res->bo->gtt_offset + cbuf->data.offset,
                             .size_B = input->buffer_size,
                             .format = ISL_FORMAT_R32G32B32A32_FLOAT,
                             .stride_B = 1,
                             .mocs = MOCS_WB)
    } else {
-      pipe_resource_reference(&cbuf->resource, NULL);
-      pipe_resource_reference(&cbuf->surface_state_resource, NULL);
+      pipe_resource_reference(&cbuf->data.res, NULL);
+      pipe_resource_reference(&cbuf->surface_state.res, NULL);
    }
 
    ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS << stage;
@@ -1404,7 +1402,7 @@ iris_sampler_view_destroy(struct pipe_context *ctx,
 {
    struct iris_sampler_view *isv = (void *) state;
    pipe_resource_reference(&state->texture, NULL);
-   pipe_resource_reference(&isv->surface_state_resource, NULL);
+   pipe_resource_reference(&isv->surface_state.res, NULL);
    free(isv);
 }
 
@@ -1414,7 +1412,7 @@ iris_surface_destroy(struct pipe_context *ctx, struct pipe_surface *p_surf)
 {
    struct iris_surface *surf = (void *) p_surf;
    pipe_resource_reference(&p_surf->texture, NULL);
-   pipe_resource_reference(&surf->surface_state_resource, NULL);
+   pipe_resource_reference(&surf->surface_state.res, NULL);
    free(surf);
 }
 
@@ -1916,8 +1914,8 @@ iris_populate_fs_key(const struct iris_context *ice,
 static uint64_t
 KSP(const struct iris_compiled_shader *shader)
 {
-   struct iris_resource *res = (void *) shader->buffer;
-   return res->bo->gtt_offset + shader->offset;
+   struct iris_resource *res = (void *) shader->assembly.res;
+   return iris_bo_offset_from_base_address(res->bo) + shader->assembly.offset;
 }
 
 #define INIT_THREAD_DISPATCH_FIELDS(pkt, prefix)                          \
@@ -2230,45 +2228,39 @@ use_surface(struct iris_batch *batch,
             bool writeable)
 {
    struct iris_surface *surf = (void *) p_surf;
-   struct iris_resource *res = (void *) p_surf->texture;
-   struct iris_resource *state_res = (void *) surf->surface_state_resource;
-   iris_use_pinned_bo(batch, res->bo, writeable);
-   iris_use_pinned_bo(batch, state_res->bo, false);
 
-   return surf->surface_state_offset;
+   iris_use_pinned_bo(batch, iris_resource_bo(p_surf->texture), writeable);
+   iris_use_pinned_bo(batch, iris_resource_bo(surf->surface_state.res), false);
+
+   return surf->surface_state.offset;
 }
 
 static uint32_t
 use_sampler_view(struct iris_batch *batch, struct iris_sampler_view *isv)
 {
-   struct iris_resource *res = (void *) isv->pipe.texture;
-   struct iris_resource *state_res = (void *) isv->surface_state_resource;
-   iris_use_pinned_bo(batch, res->bo, false);
-   iris_use_pinned_bo(batch, state_res->bo, false);
+   iris_use_pinned_bo(batch, iris_resource_bo(isv->pipe.texture), false);
+   iris_use_pinned_bo(batch, iris_resource_bo(isv->surface_state.res), false);
 
-   return isv->surface_state_offset;
+   return isv->surface_state.offset;
 }
 
 static uint32_t
 use_const_buffer(struct iris_batch *batch, struct iris_const_buffer *cbuf)
 {
-   struct iris_resource *res = (void *) cbuf->resource;
-   struct iris_resource *state_res = (void *) cbuf->surface_state_resource;
-   iris_use_pinned_bo(batch, res->bo, false);
-   iris_use_pinned_bo(batch, state_res->bo, false);
+   iris_use_pinned_bo(batch, iris_resource_bo(cbuf->data.res), false);
+   iris_use_pinned_bo(batch, iris_resource_bo(cbuf->surface_state.res), false);
 
-   return cbuf->surface_state_offset;
+   return cbuf->surface_state.offset;
 }
 
 static uint32_t
 use_null_surface(struct iris_batch *batch, struct iris_context *ice)
 {
-   struct iris_resource *state_res =
-      (void *) ice->state.unbound_tex_surface_state_resource;
+   struct iris_bo *state_bo = iris_resource_bo(ice->state.unbound_tex.res);
 
-   iris_use_pinned_bo(batch, state_res->bo, false);
+   iris_use_pinned_bo(batch, state_bo, false);
 
-   return ice->state.unbound_tex_surface_state_offset;
+   return ice->state.unbound_tex.offset;
 }
 
 static void
@@ -2312,7 +2304,7 @@ iris_populate_binding_table(struct iris_context *ice,
    struct iris_shader_state *shs = &ice->shaders.state[stage];
    for (int i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
       struct iris_const_buffer *cbuf = &shs->constbuf[i];
-      if (!cbuf->surface_state_resource)
+      if (!cbuf->surface_state.res)
          break;
 
       bt_map[s++] = use_const_buffer(batch, cbuf);
@@ -2402,7 +2394,7 @@ iris_restore_context_saved_bos(struct iris_context *ice,
             continue;
 
          struct iris_const_buffer *cbuf = &shs->constbuf[range->block];
-         struct iris_resource *res = (void *) cbuf->resource;
+         struct iris_resource *res = (void *) cbuf->data.res;
 
          if (res)
             iris_use_pinned_bo(batch, res->bo, false);
@@ -2412,7 +2404,7 @@ iris_restore_context_saved_bos(struct iris_context *ice,
    }
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      struct pipe_resource *res = ice->state.sampler_table_resource[stage];
+      struct pipe_resource *res = ice->state.sampler_table[stage].res;
       if (res)
          iris_use_pinned_bo(batch, iris_resource_bo(res), false);
    }
@@ -2420,8 +2412,10 @@ iris_restore_context_saved_bos(struct iris_context *ice,
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
       if (clean & (IRIS_DIRTY_VS << stage)) {
          struct iris_compiled_shader *shader = ice->shaders.prog[stage];
-         if (shader)
-            iris_use_pinned_bo(batch, iris_resource_bo(shader->buffer), false);
+         if (shader) {
+            struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
+            iris_use_pinned_bo(batch, bo, false);
+         }
 
          // XXX: scratch buffer
       }
@@ -2577,13 +2571,13 @@ iris_upload_render_state(struct iris_context *ice,
 
                // XXX: is range->block a constbuf index?  it would be nice
                struct iris_const_buffer *cbuf = &shs->constbuf[range->block];
-               struct iris_resource *res = (void *) cbuf->resource;
+               struct iris_resource *res = (void *) cbuf->data.res;
 
-               assert(cbuf->offset % 32 == 0);
+               assert(cbuf->data.offset % 32 == 0);
 
                pkt.ConstantBody.ReadLength[n] = range->length;
                pkt.ConstantBody.Buffer[n] =
-                  res ? ro_bo(res->bo, range->start * 32 + cbuf->offset)
+                  res ? ro_bo(res->bo, range->start * 32 + cbuf->data.offset)
                       : ro_bo(batch->screen->workaround_bo, 0);
                n--;
             }
@@ -2613,13 +2607,13 @@ iris_upload_render_state(struct iris_context *ice,
           !ice->shaders.prog[stage])
          continue;
 
-      struct pipe_resource *res = ice->state.sampler_table_resource[stage];
+      struct pipe_resource *res = ice->state.sampler_table[stage].res;
       if (res)
          iris_use_pinned_bo(batch, iris_resource_bo(res), false);
 
       iris_emit_cmd(batch, GENX(3DSTATE_SAMPLER_STATE_POINTERS_VS), ptr) {
          ptr._3DCommandSubOpcode = 43 + stage;
-         ptr.PointertoVSSamplerState = ice->state.sampler_table_offset[stage];
+         ptr.PointertoVSSamplerState = ice->state.sampler_table[stage].offset;
       }
    }
 
@@ -2645,7 +2639,7 @@ iris_upload_render_state(struct iris_context *ice,
       struct iris_compiled_shader *shader = ice->shaders.prog[stage];
 
       if (shader) {
-         struct iris_resource *cache = (void *) shader->buffer;
+         struct iris_resource *cache = (void *) shader->assembly.res;
          iris_use_pinned_bo(batch, cache->bo, false);
          iris_batch_emit(batch, shader->derived_data,
                          iris_derived_program_state_size(stage));
@@ -2884,7 +2878,7 @@ iris_destroy_state(struct iris_context *ice)
    pipe_surface_reference(&ice->state.framebuffer.zsbuf, NULL);
 
    for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) {
-      pipe_resource_reference(&ice->state.sampler_table_resource[stage], NULL);
+      pipe_resource_reference(&ice->state.sampler_table[stage].res, NULL);
    }
    free(ice->state.cso_vp);
    free(ice->state.cso_depthbuffer);
@@ -3371,11 +3365,8 @@ genX(init_state)(struct iris_context *ice)
       calloc(1, sizeof(struct iris_vertex_buffer_state));
 
    /* Make a 1x1x1 null surface for unbound textures */
-   void *null_surf_map = NULL;
-   u_upload_alloc(ice->state.surface_uploader, 0,
-                  4 * GENX(RENDER_SURFACE_STATE_length), 64,
-                  &ice->state.unbound_tex_surface_state_offset,
-                  &ice->state.unbound_tex_surface_state_resource,
-                  &null_surf_map);
+   void *null_surf_map =
+      upload_state(ice->state.surface_uploader, &ice->state.unbound_tex,
+                   4 * GENX(RENDER_SURFACE_STATE_length), 64);
    isl_null_fill_state(&screen->isl_dev, null_surf_map, isl_extent3d(1, 1, 1));
 }