ilo: honor surface padding requirements 23/7423/1
authorChia-I Wu <olvaffe@gmail.com>
Wed, 10 Jul 2013 04:05:37 +0000 (12:05 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 10 Jul 2013 04:40:22 +0000 (12:40 +0800)
The PRM specifies several padding requirements that we failed to honor.

src/gallium/drivers/ilo/ilo_resource.c

index 8824b97..5061f69 100644 (file)
@@ -758,6 +758,48 @@ static void
 tex_layout_validate(struct tex_layout *layout)
 {
    /*
+    * From the Sandy Bridge PRM, volume 1 part 1, page 118:
+    *
+    *     "To determine the necessary padding on the bottom and right side of
+    *      the surface, refer to the table in Section 7.18.3.4 for the i and j
+    *      parameters for the surface format in use. The surface must then be
+    *      extended to the next multiple of the alignment unit size in each
+    *      dimension, and all texels contained in this extended surface must
+    *      have valid GTT entries."
+    *
+    *     "For cube surfaces, an additional two rows of padding are required
+    *      at the bottom of the surface. This must be ensured regardless of
+    *      whether the surface is stored tiled or linear.  This is due to the
+    *      potential rotation of cache line orientation from memory to cache."
+    *
+    *     "For compressed textures (BC* and FXT1 surface formats), padding at
+    *      the bottom of the surface is to an even compressed row, which is
+    *      equal to a multiple of 8 uncompressed texel rows. Thus, for padding
+    *      purposes, these surfaces behave as if j = 8 only for surface
+    *      padding purposes. The value of 4 for j still applies for mip level
+    *      alignment and QPitch calculation."
+    */
+   if (layout->templ->bind & PIPE_BIND_SAMPLER_VIEW) {
+      layout->width = align(layout->width, layout->align_i);
+      layout->height = align(layout->height, layout->align_j);
+
+      if (layout->templ->target == PIPE_TEXTURE_CUBE)
+         layout->height += 2;
+
+      if (layout->compressed)
+         layout->height = align(layout->height, layout->align_j * 2);
+   }
+
+   /*
+    * From the Sandy Bridge PRM, volume 1 part 1, page 118:
+    *
+    *     "If the surface contains an odd number of rows of data, a final row
+    *      below the surface must be allocated."
+    */
+   if (layout->templ->bind & PIPE_BIND_RENDER_TARGET)
+      layout->height = align(layout->height, 2);
+
+   /*
     * From the Sandy Bridge PRM, volume 1 part 2, page 22:
     *
     *     "A 4KB tile is subdivided into 8-high by 8-wide array of Blocks for
@@ -1135,6 +1177,17 @@ buf_create(struct pipe_screen *screen, const struct pipe_resource *templ)
    buf->bo_size = templ->width0;
    buf->bo_flags = 0;
 
+   /*
+    * From the Sandy Bridge PRM, volume 1 part 1, page 118:
+    *
+    *     "For buffers, which have no inherent "height," padding requirements
+    *      are different. A buffer must be padded to the next multiple of 256
+    *      array elements, with an additional 16 bytes added beyond that to
+    *      account for the L1 cache line."
+    */
+   if (templ->bind & PIPE_BIND_SAMPLER_VIEW)
+      buf->bo_size = align(buf->bo_size, 256) + 16;
+
    if (!buf_create_bo(buf)) {
       FREE(buf);
       return NULL;