iris: implement set_shader_images hook
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 30 Aug 2018 22:45:36 +0000 (15:45 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:09 +0000 (10:26 -0800)
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_state.c

index a2704ab8b3b5773dc119a5ac4e4b3fb0588d146f..83978aebb9945e9706472ac3bffb423307451a53 100644 (file)
@@ -247,10 +247,17 @@ struct iris_const_buffer {
  * API context state that is replicated per shader stage.
  */
 struct iris_shader_state {
+   /** Uniform Buffers */
    struct iris_const_buffer constbuf[PIPE_MAX_CONSTANT_BUFFERS];
+
+   /** Shader Storage Buffers */
    struct pipe_resource *ssbo[PIPE_MAX_SHADER_BUFFERS];
    struct iris_state_ref ssbo_surface_state[PIPE_MAX_SHADER_BUFFERS];
 
+   /** Shader Storage Images (image load store) */
+   struct pipe_resource *image[PIPE_MAX_SHADER_IMAGES];
+   struct iris_state_ref image_surface_state[PIPE_MAX_SHADER_IMAGES];
+
    struct iris_state_ref sampler_table;
    struct iris_sampler_state *samplers[IRIS_MAX_TEXTURE_SAMPLERS];
    struct iris_sampler_view *textures[IRIS_MAX_TEXTURE_SAMPLERS];
index 0f6177eb953b5073b3646147dea3455cf8d8b164..dd90d2816ed680c896ffd71003b5b904e50a0149 100644 (file)
@@ -1494,6 +1494,89 @@ iris_create_surface(struct pipe_context *ctx,
    return psurf;
 }
 
+/**
+ * The pipe->set_shader_images() driver hook.
+ */
+static void
+iris_set_shader_images(struct pipe_context *ctx,
+                       enum pipe_shader_type p_stage,
+                       unsigned start_slot, unsigned count,
+                       const struct pipe_image_view *p_images)
+{
+   struct iris_context *ice = (struct iris_context *) ctx;
+   struct iris_screen *screen = (struct iris_screen *)ctx->screen;
+   const struct gen_device_info *devinfo = &screen->devinfo;
+   gl_shader_stage stage = stage_from_pipe(p_stage);
+   struct iris_shader_state *shs = &ice->state.shaders[stage];
+
+   for (unsigned i = 0; i < count; i++) {
+      if (p_images && p_images[i].resource) {
+         const struct pipe_image_view *img = &p_images[i];
+         struct iris_resource *res = (void *) img->resource;
+         pipe_resource_reference(&shs->image[start_slot + i], &res->base);
+
+         // XXX: these are not retained forever, use a separate uploader?
+         void *map =
+            upload_state(ice->state.surface_uploader,
+                         &shs->image_surface_state[start_slot + i],
+                         4 * GENX(RENDER_SURFACE_STATE_length), 64);
+         if (!unlikely(map)) {
+            pipe_resource_reference(&shs->image[start_slot + i], NULL);
+            return;
+         }
+
+         struct iris_bo *surf_state_bo =
+            iris_resource_bo(shs->image_surface_state[start_slot + i].res);
+         shs->image_surface_state[start_slot + i].offset +=
+            iris_bo_offset_from_base_address(surf_state_bo);
+
+         isl_surf_usage_flags_t usage = ISL_SURF_USAGE_STORAGE_BIT;
+         enum isl_format isl_format =
+            iris_format_for_usage(devinfo, img->format, usage).fmt;
+         isl_format = isl_lower_storage_image_format(devinfo, isl_format);
+
+         if (res->base.target != PIPE_BUFFER) {
+            struct isl_view view = {
+               .format = isl_format,
+               .base_level = img->u.tex.level,
+               .levels = 1,
+               .base_array_layer = img->u.tex.first_layer,
+               .array_len = img->u.tex.last_layer - img->u.tex.first_layer + 1,
+               .swizzle = ISL_SWIZZLE_IDENTITY,
+               .usage = usage,
+            };
+
+            isl_surf_fill_state(&screen->isl_dev, map,
+                                .surf = &res->surf, .view = &view,
+                                .mocs = MOCS_WB,
+                                .address = res->bo->gtt_offset);
+                                // .aux_surf =
+                                // .clear_color = clear_color,
+         } else {
+            // XXX: what to do about view?  other drivers don't use it for bufs
+            const struct isl_format_layout *fmtl =
+               isl_format_get_layout(isl_format);
+            const unsigned cpp = fmtl->bpb / 8;
+
+            isl_buffer_fill_state(&screen->isl_dev, map,
+                                  .address = res->bo->gtt_offset,
+                                  // XXX: buffer_texture_range_size from i965?
+                                  .size_B = res->base.width0,
+                                  .format = isl_format,
+                                  .stride_B = cpp,
+                                  .mocs = MOCS_WB);
+         }
+      } else {
+         pipe_resource_reference(&shs->image[start_slot + i], NULL);
+         pipe_resource_reference(&shs->image_surface_state[start_slot + i].res,
+                                 NULL);
+      }
+   }
+
+   ice->state.dirty |= IRIS_DIRTY_BINDINGS_VS << stage;
+}
+
+
 /**
  * The pipe->set_sampler_views() driver hook.
  */
@@ -4600,6 +4683,7 @@ genX(init_state)(struct iris_context *ice)
    ctx->set_clip_state = iris_set_clip_state;
    ctx->set_constant_buffer = iris_set_constant_buffer;
    ctx->set_shader_buffers = iris_set_shader_buffers;
+   ctx->set_shader_images = iris_set_shader_images;
    ctx->set_sampler_views = iris_set_sampler_views;
    ctx->set_tess_state = iris_set_tess_state;
    ctx->set_framebuffer_state = iris_set_framebuffer_state;