[Mesa-dev] [PATCH 03/25] i965/gen7: Implement surface state set-up for shader images.

Francisco Jerez currojerez at riseup.net
Mon Dec 2 11:39:11 PST 2013


---
 src/mesa/drivers/dri/i965/brw_context.h           |  10 ++
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c | 175 ++++++++++++++++++++++
 2 files changed, 185 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 3f2edcf..0816912 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -978,6 +978,11 @@ struct brw_context
 					  struct gl_renderbuffer *rb,
 					  bool layered,
 					  unsigned unit);
+      void (*update_image_surface)(struct brw_context *brw,
+                                   struct gl_image_unit *u,
+                                   GLenum access,
+                                   uint32_t *surf_offset,
+                                   struct brw_image_param *param);
       void (*update_null_renderbuffer_surface)(struct brw_context *brw,
 					       unsigned unit);
 
@@ -1643,6 +1648,11 @@ void brw_upload_abo_surfaces(struct brw_context *brw,
                              struct gl_shader_program *prog,
                              struct brw_stage_state *stage_state,
                              struct brw_stage_prog_data *prog_data);
+void brw_upload_image_surfaces(struct brw_context *brw,
+                               struct gl_shader *shader,
+                               struct brw_stage_state *stage_state,
+                               struct brw_stage_prog_data *prog_data,
+                               struct brw_image_param *params);
 
 /* brw_surface_formats.c */
 bool brw_is_hiz_depth_format(struct brw_context *ctx, gl_format format);
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index 3dc0cb7..532a18c 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -564,6 +564,180 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
    gen7_check_surface_setup(surf, true /* is_render_target */);
 }
 
+static uint32_t
+get_image_format(struct brw_context *brw, gl_format format)
+{
+   switch (format) {
+   case MESA_FORMAT_RGBA_UINT32:
+   case MESA_FORMAT_RGBA_INT32:
+   case MESA_FORMAT_RGBA_FLOAT32:
+      /* Fail...  We need to fall back to untyped surface access for
+       * all 128 bpp formats.
+       */
+      return BRW_SURFACEFORMAT_RAW;
+
+   case MESA_FORMAT_RGBA_UINT16:
+   case MESA_FORMAT_RGBA_INT16:
+   case MESA_FORMAT_RGBA_FLOAT16:
+   case MESA_FORMAT_RGBA_16:
+   case MESA_FORMAT_SIGNED_RGBA_16:
+   case MESA_FORMAT_RG_UINT32:
+   case MESA_FORMAT_RG_INT32:
+   case MESA_FORMAT_RG_FLOAT32:
+      /* HSW supports the R16G16B16A16_UINT format natively and
+       * handles the pixel packing, unpacking and type conversion in
+       * the shader for other 64 bpp formats.  IVB falls back to
+       * untyped.
+       */
+      return (brw->is_haswell ? BRW_SURFACEFORMAT_R16G16B16A16_UINT :
+              BRW_SURFACEFORMAT_RAW);
+
+   case MESA_FORMAT_RGBA_UINT8:
+   case MESA_FORMAT_RGBA_INT8:
+   case MESA_FORMAT_RGBA8888_REV:
+   case MESA_FORMAT_SIGNED_RGBA8888_REV:
+      /* HSW supports the R8G8B8A8_UINT format natively, type
+       * conversion to other formats is handled in the shader.  IVB
+       * uses R32_UINT and handles the pixel packing, unpacking and
+       * type conversion in the shader.
+       */
+      return (brw->is_haswell ? BRW_SURFACEFORMAT_R8G8B8A8_UINT :
+              BRW_SURFACEFORMAT_R32_UINT);
+
+   case MESA_FORMAT_RG_UINT16:
+   case MESA_FORMAT_RG_INT16:
+   case MESA_FORMAT_RG_FLOAT16:
+   case MESA_FORMAT_GR1616:
+   case MESA_FORMAT_SIGNED_GR1616:
+      /* HSW supports the R16G16_UINT format natively, type conversion
+       * to other formats is handled in the shader.  IVB uses R32_UINT
+       * and handles the pixel packing, unpacking and type conversion
+       * in the shader.
+       */
+      return (brw->is_haswell ? BRW_SURFACEFORMAT_R16G16_UINT :
+              BRW_SURFACEFORMAT_R32_UINT);
+
+   case MESA_FORMAT_ABGR2101010_UINT:
+   case MESA_FORMAT_ABGR2101010:
+   case MESA_FORMAT_R11_G11_B10_FLOAT:
+   case MESA_FORMAT_R_UINT32:
+      /* Neither the 2/10/10/10 nor the 11/11/10 packed formats are
+       * supported by the hardware.  Use R32_UINT and handle the pixel
+       * packing, unpacking, and type conversion in the shader.
+       */
+      return BRW_SURFACEFORMAT_R32_UINT;
+
+   case MESA_FORMAT_R_INT32:
+      return BRW_SURFACEFORMAT_R32_SINT;
+
+   case MESA_FORMAT_R_FLOAT32:
+      return BRW_SURFACEFORMAT_R32_FLOAT;
+
+   case MESA_FORMAT_RG_UINT8:
+   case MESA_FORMAT_RG_INT8:
+   case MESA_FORMAT_GR88:
+   case MESA_FORMAT_SIGNED_RG88_REV:
+      /* HSW supports the R8G8_UINT format natively, type conversion
+       * to other formats is handled in the shader.  IVB uses R16_UINT
+       * and handles the pixel packing, unpacking and type conversion
+       * in the shader.  Note that this relies on the undocumented
+       * behavior that typed reads from R16_UINT surfaces actually do
+       * a 32-bit misaligned read on IVB.  The alternative would be to
+       * use two surface state entries with different formats for each
+       * image, one for reading (using R32_UINT) and another one for
+       * writing (using R8G8_UINT), but that would complicate the
+       * shaders we generate even more.
+       */
+      return (brw->is_haswell ? BRW_SURFACEFORMAT_R8G8_UINT :
+              BRW_SURFACEFORMAT_R16_UINT);
+
+   case MESA_FORMAT_R_UINT16:
+   case MESA_FORMAT_R_FLOAT16:
+   case MESA_FORMAT_R_INT16:
+   case MESA_FORMAT_R16:
+   case MESA_FORMAT_SIGNED_R16:
+      /* HSW supports the R16_UINT format natively, type conversion to
+       * other formats is handled in the shader.  IVB relies on the
+       * same undocumented behavior described above.
+       */
+      return BRW_SURFACEFORMAT_R16_UINT;
+
+   case MESA_FORMAT_R_UINT8:
+   case MESA_FORMAT_R_INT8:
+   case MESA_FORMAT_R8:
+   case MESA_FORMAT_SIGNED_R8:
+      /* HSW supports the R8_UINT format natively, type conversion to
+       * other formats is handled in the shader.  IVB relies on the
+       * same undocumented behavior described above.
+       */
+      return BRW_SURFACEFORMAT_R8_UINT;
+
+   default:
+      unreachable();
+   }
+}
+
+static void
+gen7_update_image_surface(struct brw_context *brw,
+                          struct gl_image_unit *u,
+                          GLenum access,
+                          uint32_t *surf_offset,
+                          struct brw_image_param *param)
+{
+   struct gl_texture_object *obj = u->TexObj;
+   /* Typed surface reads support a very limited subset of the shader
+    * image formats.  Translate it into the closest format the
+    * hardware supports.
+    */
+   const unsigned format = (access == GL_WRITE_ONLY ?
+                            brw_format_for_mesa_format(u->_ActualFormat) :
+                            get_image_format(brw, u->_ActualFormat));
+
+   if (obj->Target == GL_TEXTURE_BUFFER) {
+      struct intel_buffer_object *intel_obj =
+         intel_buffer_object(obj->BufferObject);
+      const unsigned texel_size = (format == BRW_SURFACEFORMAT_RAW ? 1 :
+                                   _mesa_get_format_bytes(format));
+
+      gen7_emit_buffer_surface_state(brw,
+                                     surf_offset,
+                                     intel_obj->buffer,
+                                     0,
+                                     format,
+                                     intel_obj->Base.Size / texel_size,
+                                     texel_size,
+                                     0 /* mocs */,
+                                     access != GL_READ_ONLY);
+
+   } else {
+      struct intel_texture_object *intel_obj = intel_texture_object(obj);
+      struct intel_mipmap_tree *mt = intel_obj->mt;
+
+      if (format == BRW_SURFACEFORMAT_RAW) {
+         gen7_emit_buffer_surface_state(brw,
+                                        surf_offset,
+                                        mt->region->bo,
+                                        mt->offset,
+                                        format,
+                                        mt->region->bo->size - mt->offset,
+                                        1 /* pitch */,
+                                        0 /* mocs */,
+                                        access != GL_READ_ONLY);
+
+      } else {
+         const unsigned depth = (u->Layered ? mt->logical_depth0 : 1);
+
+         gen7_emit_texture_surface_state(brw, obj,
+                                         u->Layer, u->Layer + depth,
+                                         u->Level, u->Level + 1,
+                                         format,
+                                         surf_offset,
+                                         access != GL_READ_ONLY,
+                                         false);
+      }
+   }
+}
+
 void
 gen7_init_vtable_surface_functions(struct brw_context *brw)
 {
@@ -573,4 +747,5 @@ gen7_init_vtable_surface_functions(struct brw_context *brw)
       gen7_update_null_renderbuffer_surface;
    brw->vtbl.create_raw_surface = gen7_create_raw_surface;
    brw->vtbl.emit_buffer_surface_state = gen7_emit_buffer_surface_state;
+   brw->vtbl.update_image_surface = gen7_update_image_surface;
 }
-- 
1.8.3.4



More information about the mesa-dev mailing list