OSDN Git Service

ilo: use emit_SURFACE_STATE() for render targets
[android-x86/external-mesa.git] / src / gallium / drivers / ilo / ilo_gpe_gen7.c
index 27fa124..73fbf7c 100644 (file)
@@ -59,16 +59,6 @@ gen7_emit_3DSTATE_CLEAR_PARAMS(const struct ilo_dev_info *dev,
 }
 
 static void
-gen7_emit_3DSTATE_DEPTH_BUFFER(const struct ilo_dev_info *dev,
-                               const struct pipe_surface *surface,
-                               const struct pipe_depth_stencil_alpha_state *dsa,
-                               bool hiz,
-                               struct ilo_cp *cp)
-{
-   ilo_gpe_gen6_emit_3DSTATE_DEPTH_BUFFER(dev, surface, dsa, hiz, cp);
-}
-
-static void
 gen7_emit_3dstate_pointer(const struct ilo_dev_info *dev,
                           int subop, uint32_t pointer,
                           struct ilo_cp *cp)
@@ -1130,7 +1120,7 @@ gen7_emit_3DSTATE_SO_BUFFER(const struct ilo_dev_info *dev,
 {
    const uint32_t cmd = ILO_GPE_CMD(0x3, 0x1, 0x18);
    const uint8_t cmd_len = 4;
-   struct ilo_texture *tex;
+   struct ilo_buffer *buf;
    int end;
 
    ILO_GPE_VALID_GEN(dev, 7, 7);
@@ -1145,7 +1135,7 @@ gen7_emit_3DSTATE_SO_BUFFER(const struct ilo_dev_info *dev,
       return;
    }
 
-   tex = ilo_texture(so_target->buffer);
+   buf = ilo_buffer(so_target->buffer);
 
    /* DWord-aligned */
    assert(stride % 4 == 0 && base % 4 == 0);
@@ -1159,8 +1149,8 @@ gen7_emit_3DSTATE_SO_BUFFER(const struct ilo_dev_info *dev,
    ilo_cp_write(cp, cmd | (cmd_len - 2));
    ilo_cp_write(cp, index << SO_BUFFER_INDEX_SHIFT |
                     stride);
-   ilo_cp_write_bo(cp, base, tex->bo, INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
-   ilo_cp_write_bo(cp, end, tex->bo, INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
+   ilo_cp_write_bo(cp, base, buf->bo, INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
+   ilo_cp_write_bo(cp, end, buf->bo, INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
    ilo_cp_end(cp);
 }
 
@@ -1193,14 +1183,14 @@ gen7_emit_3DPRIMITIVE(const struct ilo_dev_info *dev,
 
 static uint32_t
 gen7_emit_SF_CLIP_VIEWPORT(const struct ilo_dev_info *dev,
-                           const struct pipe_viewport_state *viewports,
-                           int num_viewports,
+                           const struct ilo_viewport_cso *viewports,
+                           unsigned num_viewports,
                            struct ilo_cp *cp)
 {
    const int state_align = 64 / 4;
    const int state_len = 16 * num_viewports;
    uint32_t state_offset, *dw;
-   int i;
+   unsigned i;
 
    ILO_GPE_VALID_GEN(dev, 7, 7);
 
@@ -1220,12 +1210,20 @@ gen7_emit_SF_CLIP_VIEWPORT(const struct ilo_dev_info *dev,
          state_len, state_align, &state_offset);
 
    for (i = 0; i < num_viewports; i++) {
-      const struct pipe_viewport_state *vp = &viewports[i];
-
-      ilo_gpe_gen6_fill_SF_VIEWPORT(dev, vp, 1, dw, 8);
-
-      ilo_gpe_gen6_fill_CLIP_VIEWPORT(dev, vp, 1, dw + 8, 4);
-
+      const struct ilo_viewport_cso *vp = &viewports[i];
+
+      dw[0] = fui(vp->m00);
+      dw[1] = fui(vp->m11);
+      dw[2] = fui(vp->m22);
+      dw[3] = fui(vp->m30);
+      dw[4] = fui(vp->m31);
+      dw[5] = fui(vp->m32);
+      dw[6] = 0;
+      dw[7] = 0;
+      dw[8] = fui(vp->min_gbx);
+      dw[9] = fui(vp->max_gbx);
+      dw[10] = fui(vp->min_gby);
+      dw[11] = fui(vp->max_gby);
       dw[12] = 0;
       dw[13] = 0;
       dw[14] = 0;
@@ -1237,14 +1235,15 @@ gen7_emit_SF_CLIP_VIEWPORT(const struct ilo_dev_info *dev,
    return state_offset;
 }
 
-static void
-gen7_fill_null_SURFACE_STATE(const struct ilo_dev_info *dev,
-                             unsigned width, unsigned height,
-                             unsigned depth, unsigned lod,
-                             uint32_t *dw, int num_dwords)
+void
+ilo_gpe_init_view_surface_null_gen7(const struct ilo_dev_info *dev,
+                                    unsigned width, unsigned height,
+                                    unsigned depth, unsigned level,
+                                    struct ilo_view_surface *surf)
 {
+   uint32_t *dw;
+
    ILO_GPE_VALID_GEN(dev, 7, 7);
-   assert(num_dwords == 8);
 
    /*
     * From the Ivy Bridge PRM, volume 4 part 1, page 62:
@@ -1277,6 +1276,9 @@ gen7_fill_null_SURFACE_STATE(const struct ilo_dev_info *dev,
     *      true"
     */
 
+   STATIC_ASSERT(Elements(surf->payload) >= 8);
+   dw = surf->payload;
+
    dw[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
            BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
            BRW_SURFACE_TILED << 13;
@@ -1289,19 +1291,22 @@ gen7_fill_null_SURFACE_STATE(const struct ilo_dev_info *dev,
    dw[3] = SET_FIELD(depth - 1, BRW_SURFACE_DEPTH);
 
    dw[4] = 0;
-   dw[5] = lod;
+   dw[5] = level;
+
    dw[6] = 0;
    dw[7] = 0;
+
+   surf->bo = NULL;
 }
 
-static void
-gen7_fill_buffer_SURFACE_STATE(const struct ilo_dev_info *dev,
-                               const struct ilo_texture *tex,
-                               unsigned offset, unsigned size,
-                               unsigned struct_size,
-                               enum pipe_format elem_format,
-                               bool is_rt, bool render_cache_rw,
-                               uint32_t *dw, int num_dwords)
+void
+ilo_gpe_init_view_surface_for_buffer_gen7(const struct ilo_dev_info *dev,
+                                          const struct ilo_buffer *buf,
+                                          unsigned offset, unsigned size,
+                                          unsigned struct_size,
+                                          enum pipe_format elem_format,
+                                          bool is_rt, bool render_cache_rw,
+                                          struct ilo_view_surface *surf)
 {
    const bool typed = (elem_format != PIPE_FORMAT_NONE);
    const bool structured = (!typed && struct_size > 1);
@@ -1309,9 +1314,9 @@ gen7_fill_buffer_SURFACE_STATE(const struct ilo_dev_info *dev,
       util_format_get_blocksize(elem_format) : 1;
    int width, height, depth, pitch;
    int surface_type, surface_format, num_entries;
+   uint32_t *dw;
 
    ILO_GPE_VALID_GEN(dev, 7, 7);
-   assert(num_dwords == 8);
 
    surface_type = (structured) ? 5 : BRW_SURFACE_BUFFER;
 
@@ -1374,14 +1379,6 @@ gen7_fill_buffer_SURFACE_STATE(const struct ilo_dev_info *dev,
 
    pitch = struct_size;
 
-   /*
-    * From the Ivy Bridge PRM, volume 4 part 1, page 65:
-    *
-    *     "If Surface Type is SURFTYPE_BUFFER, this field (Tiled Surface) must
-    *      be false (because buffers are supported only in linear memory)."
-    */
-   assert(tex->tiling == INTEL_TILING_NONE);
-
    pitch--;
    num_entries--;
    /* bits [6:0] */
@@ -1394,6 +1391,9 @@ gen7_fill_buffer_SURFACE_STATE(const struct ilo_dev_info *dev,
    if (typed || structured)
       depth &= 0x3f;
 
+   STATIC_ASSERT(Elements(surf->payload) >= 8);
+   dw = surf->payload;
+
    dw[0] = surface_type << BRW_SURFACE_TYPE_SHIFT |
            surface_format << BRW_SURFACE_FORMAT_SHIFT;
    if (render_cache_rw)
@@ -1409,29 +1409,38 @@ gen7_fill_buffer_SURFACE_STATE(const struct ilo_dev_info *dev,
 
    dw[4] = 0;
    dw[5] = 0;
+
    dw[6] = 0;
    dw[7] = 0;
+
+   /* do not increment reference count */
+   surf->bo = buf->bo;
 }
 
-static void
-gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev,
-                               struct ilo_texture *tex,
-                               enum pipe_format format,
-                               unsigned first_level, unsigned num_levels,
-                               unsigned first_layer, unsigned num_layers,
-                               bool is_rt, bool render_cache_rw,
-                               uint32_t *dw, int num_dwords)
+void
+ilo_gpe_init_view_surface_for_texture_gen7(const struct ilo_dev_info *dev,
+                                           const struct ilo_texture *tex,
+                                           enum pipe_format format,
+                                           unsigned first_level,
+                                           unsigned num_levels,
+                                           unsigned first_layer,
+                                           unsigned num_layers,
+                                           bool is_rt, bool render_cache_rw,
+                                           struct ilo_view_surface *surf)
 {
    int surface_type, surface_format;
    int width, height, depth, pitch, lod;
    unsigned layer_offset, x_offset, y_offset;
+   uint32_t *dw;
 
    ILO_GPE_VALID_GEN(dev, 7, 7);
-   assert(num_dwords == 8);
 
    surface_type = ilo_gpe_gen6_translate_texture(tex->base.target);
    assert(surface_type != BRW_SURFACE_BUFFER);
 
+   if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && tex->separate_s8)
+      format = PIPE_FORMAT_Z32_FLOAT;
+
    if (is_rt)
       surface_format = ilo_translate_render_format(format);
    else
@@ -1440,39 +1449,34 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev,
 
    width = tex->base.width0;
    height = tex->base.height0;
+   depth = (tex->base.target == PIPE_TEXTURE_3D) ?
+      tex->base.depth0 : num_layers;
    pitch = tex->bo_stride;
 
-   switch (tex->base.target) {
-   case PIPE_TEXTURE_3D:
-      depth = tex->base.depth0;
-      break;
-   case PIPE_TEXTURE_CUBE:
-   case PIPE_TEXTURE_CUBE_ARRAY:
+   if (surface_type == BRW_SURFACE_CUBE) {
       /*
        * From the Ivy Bridge PRM, volume 4 part 1, page 70:
        *
-       *     "For SURFTYPE_CUBE: For Sampling Engine Surfaces, the range of
+       *     "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of
        *      this field is [0,340], indicating the number of cube array
        *      elements (equal to the number of underlying 2D array elements
        *      divided by 6). For other surfaces, this field must be zero."
        *
-       *     "Errata: For SURFTYPE_CUBE sampling engine surfaces, the range of
-       *      this field is limited to [0,85]."
+       * When is_rt is true, we treat the texture as a 2D one to avoid the
+       * restriction.
        */
-      if (!is_rt) {
+      if (is_rt) {
+         surface_type = BRW_SURFACE_2D;
+      }
+      else {
          assert(num_layers % 6 == 0);
          depth = num_layers / 6;
-         break;
       }
-      assert(num_layers == 1);
-      /* fall through */
-   default:
-      depth = num_layers;
-      break;
    }
 
    /* sanity check the size */
    assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
+   assert(first_layer < 2048 && num_layers <= 2048);
    switch (surface_type) {
    case BRW_SURFACE_1D:
       assert(width <= 16384 && height == 1 && depth <= 2048);
@@ -1482,49 +1486,66 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev,
       break;
    case BRW_SURFACE_3D:
       assert(width <= 2048 && height <= 2048 && depth <= 2048);
+      if (!is_rt)
+         assert(first_layer == 0);
       break;
    case BRW_SURFACE_CUBE:
       assert(width <= 16384 && height <= 16384 && depth <= 86);
       assert(width == height);
+      if (is_rt)
+         assert(first_layer == 0);
       break;
    default:
       assert(!"unexpected surface type");
       break;
    }
 
-   /*
-    * Compute the offset to the layer manually.
-    *
-    * For rendering, the hardware requires LOD to be the same for all render
-    * targets and the depth buffer.  We need to compute the offset to the
-    * layer manually and always set LOD to 0.
-    */
    if (is_rt) {
-      /* we lose the capability for layered rendering */
-      assert(num_levels == 1 && num_layers == 1);
-
-      layer_offset = ilo_texture_get_slice_offset(tex,
-            first_level, first_layer, true, &x_offset, &y_offset);
-
-      assert(x_offset % 4 == 0);
-      assert(y_offset % 2 == 0);
-      x_offset /= 4;
-      y_offset /= 2;
-
-      /* derive the size for the LOD */
-      width = u_minify(tex->base.width0, first_level);
-      height = u_minify(tex->base.height0, first_level);
-      if (surface_type == BRW_SURFACE_3D)
-         depth = u_minify(tex->base.depth0, first_level);
-
-      first_level = 0;
-      first_layer = 0;
-      lod = 0;
+      /*
+       * Compute the offset to the layer manually.
+       *
+       * For rendering, the hardware requires LOD to be the same for all
+       * render targets and the depth buffer.  We need to compute the offset
+       * to the layer manually and always set LOD to 0.
+       */
+      if (true) {
+         /* we lose the capability for layered rendering */
+         assert(num_layers == 1);
+
+         layer_offset = ilo_texture_get_slice_offset(tex,
+               first_level, first_layer, &x_offset, &y_offset);
+
+         assert(x_offset % 4 == 0);
+         assert(y_offset % 2 == 0);
+         x_offset /= 4;
+         y_offset /= 2;
+
+         /* derive the size for the LOD */
+         width = u_minify(width, first_level);
+         height = u_minify(height, first_level);
+         if (surface_type == BRW_SURFACE_3D)
+            depth = u_minify(depth, first_level);
+         else
+            depth = 1;
+
+         first_level = 0;
+         first_layer = 0;
+         lod = 0;
+      }
+      else {
+         layer_offset = 0;
+         x_offset = 0;
+         y_offset = 0;
+      }
+
+      assert(num_levels == 1);
+      lod = first_level;
    }
    else {
       layer_offset = 0;
       x_offset = 0;
       y_offset = 0;
+
       lod = num_levels - 1;
    }
 
@@ -1561,6 +1582,9 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev,
       assert(!x_offset);
    }
 
+   STATIC_ASSERT(Elements(surf->payload) >= 8);
+   dw = surf->payload;
+
    dw[0] = surface_type << BRW_SURFACE_TYPE_SHIFT |
            surface_format << BRW_SURFACE_FORMAT_SHIFT |
            ilo_gpe_gen6_translate_winsys_tiling(tex->tiling) << 13;
@@ -1594,7 +1618,7 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev,
            (pitch - 1);
 
    dw[4] = first_layer << 18 |
-           (depth - 1) << 7;
+           (num_layers - 1) << 7;
 
    /*
     * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL
@@ -1623,134 +1647,9 @@ gen7_fill_normal_SURFACE_STATE(const struct ilo_dev_info *dev,
 
    dw[6] = 0;
    dw[7] = 0;
-}
-
-static uint32_t
-gen7_emit_SURFACE_STATE(const struct ilo_dev_info *dev,
-                        struct intel_bo *bo, bool for_render,
-                        const uint32_t *dw, int num_dwords,
-                        struct ilo_cp *cp)
-{
-   const int state_align = 32 / 4;
-   const int state_len = 8;
-   uint32_t state_offset;
-   uint32_t read_domains, write_domain;
-
-   ILO_GPE_VALID_GEN(dev, 7, 7);
-   assert(num_dwords == state_len);
 
-   if (for_render) {
-      read_domains = INTEL_DOMAIN_RENDER;
-      write_domain = INTEL_DOMAIN_RENDER;
-   }
-   else {
-      read_domains = INTEL_DOMAIN_SAMPLER;
-      write_domain = 0;
-   }
-
-   ilo_cp_steal(cp, "SURFACE_STATE", state_len, state_align, &state_offset);
-   ilo_cp_write(cp, dw[0]);
-   ilo_cp_write_bo(cp, dw[1], bo, read_domains, write_domain);
-   ilo_cp_write(cp, dw[2]);
-   ilo_cp_write(cp, dw[3]);
-   ilo_cp_write(cp, dw[4]);
-   ilo_cp_write(cp, dw[5]);
-   ilo_cp_write(cp, dw[6]);
-   ilo_cp_write(cp, dw[7]);
-   ilo_cp_end(cp);
-
-   return state_offset;
-}
-
-static uint32_t
-gen7_emit_surf_SURFACE_STATE(const struct ilo_dev_info *dev,
-                             const struct pipe_surface *surface,
-                             struct ilo_cp *cp)
-{
-   struct intel_bo *bo;
-   uint32_t dw[8];
-
-   ILO_GPE_VALID_GEN(dev, 7, 7);
-
-   if (surface && surface->texture) {
-      struct ilo_texture *tex = ilo_texture(surface->texture);
-
-      bo = tex->bo;
-
-      /*
-       * classic i965 sets render_cache_rw for constant buffers and sol
-       * surfaces but not render buffers.  Why?
-       */
-      gen7_fill_normal_SURFACE_STATE(dev, tex, surface->format,
-            surface->u.tex.level, 1,
-            surface->u.tex.first_layer,
-            surface->u.tex.last_layer - surface->u.tex.first_layer + 1,
-            true, true, dw, Elements(dw));
-   }
-   else {
-      bo = NULL;
-      gen7_fill_null_SURFACE_STATE(dev,
-            surface->width, surface->height, 1, 0, dw, Elements(dw));
-   }
-
-   return gen7_emit_SURFACE_STATE(dev, bo, true, dw, Elements(dw), cp);
-}
-
-static uint32_t
-gen7_emit_view_SURFACE_STATE(const struct ilo_dev_info *dev,
-                             const struct pipe_sampler_view *view,
-                             struct ilo_cp *cp)
-{
-   struct ilo_texture *tex = ilo_texture(view->texture);
-   uint32_t dw[8];
-
-   ILO_GPE_VALID_GEN(dev, 7, 7);
-
-   gen7_fill_normal_SURFACE_STATE(dev, tex, view->format,
-         view->u.tex.first_level,
-         view->u.tex.last_level - view->u.tex.first_level + 1,
-         view->u.tex.first_layer,
-         view->u.tex.last_layer - view->u.tex.first_layer + 1,
-         false, false, dw, Elements(dw));
-
-   return gen7_emit_SURFACE_STATE(dev, tex->bo, false, dw, Elements(dw), cp);
-}
-
-static uint32_t
-gen7_emit_cbuf_SURFACE_STATE(const struct ilo_dev_info *dev,
-                             const struct pipe_constant_buffer *cbuf,
-                             struct ilo_cp *cp)
-{
-   const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-   struct ilo_texture *tex = ilo_texture(cbuf->buffer);
-   uint32_t dw[8];
-
-   ILO_GPE_VALID_GEN(dev, 7, 7);
-
-   gen7_fill_buffer_SURFACE_STATE(dev, tex,
-         cbuf->buffer_offset, cbuf->buffer_size,
-         util_format_get_blocksize(elem_format), elem_format,
-         false, false, dw, Elements(dw));
-
-   return gen7_emit_SURFACE_STATE(dev, tex->bo, false, dw, Elements(dw), cp);
-}
-
-static uint32_t
-gen7_emit_SAMPLER_BORDER_COLOR_STATE(const struct ilo_dev_info *dev,
-                                     const union pipe_color_union *color,
-                                     struct ilo_cp *cp)
-{
-   const int state_align = 32 / 4;
-   const int state_len = 4;
-   uint32_t state_offset, *dw;
-
-   ILO_GPE_VALID_GEN(dev, 7, 7);
-
-   dw = ilo_cp_steal_ptr(cp, "SAMPLER_BORDER_COLOR_STATE",
-         state_len, state_align, &state_offset);
-   memcpy(dw, color->f, 4 * 4);
-
-   return state_offset;
+   /* do not increment reference count */
+   surf->bo = tex->bo;
 }
 
 static int
@@ -1911,7 +1810,7 @@ gen7_init(struct ilo_gpe_gen7 *gen7)
    GEN7_USE(gen7, MEDIA_STATE_FLUSH, gen6);
    GEN7_SET(gen7, GPGPU_WALKER);
    GEN7_SET(gen7, 3DSTATE_CLEAR_PARAMS);
-   GEN7_SET(gen7, 3DSTATE_DEPTH_BUFFER);
+   GEN7_USE(gen7, 3DSTATE_DEPTH_BUFFER, gen6);
    GEN7_USE(gen7, 3DSTATE_STENCIL_BUFFER, gen6);
    GEN7_USE(gen7, 3DSTATE_HIER_DEPTH_BUFFER, gen6);
    GEN7_USE(gen7, 3DSTATE_VERTEX_BUFFERS, gen6);
@@ -1977,11 +1876,9 @@ gen7_init(struct ilo_gpe_gen7 *gen7)
    GEN7_USE(gen7, DEPTH_STENCIL_STATE, gen6);
    GEN7_USE(gen7, SCISSOR_RECT, gen6);
    GEN7_USE(gen7, BINDING_TABLE_STATE, gen6);
-   GEN7_SET(gen7, surf_SURFACE_STATE);
-   GEN7_SET(gen7, view_SURFACE_STATE);
-   GEN7_SET(gen7, cbuf_SURFACE_STATE);
+   GEN7_USE(gen7, SURFACE_STATE, gen6);
    GEN7_USE(gen7, SAMPLER_STATE, gen6);
-   GEN7_SET(gen7, SAMPLER_BORDER_COLOR_STATE);
+   GEN7_USE(gen7, SAMPLER_BORDER_COLOR_STATE, gen6);
    GEN7_USE(gen7, push_constant_buffer, gen6);
 #undef GEN7_USE
 #undef GEN7_SET