summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-07-10 12:05:37 +0800
committerChia-I Wu <[email protected]>2013-07-10 12:40:22 +0800
commit045bf0db5215789bdaa9043c9a3075d3c3a71d64 (patch)
tree7b338e687fc3e6a8d587c82f4300c8defeb75b96
parent63386b2f66a6d450889cd5368bc599beb7f1efbf (diff)
ilo: honor surface padding requirements
The PRM specifies several padding requirements that we failed to honor.
-rw-r--r--src/gallium/drivers/ilo/ilo_resource.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/gallium/drivers/ilo/ilo_resource.c b/src/gallium/drivers/ilo/ilo_resource.c
index 8824b97ebc6..5061f694d86 100644
--- a/src/gallium/drivers/ilo/ilo_resource.c
+++ b/src/gallium/drivers/ilo/ilo_resource.c
@@ -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;