struct pipe_resource *prsc = &rsc->base.b;
uint32_t width = prsc->width0;
uint32_t height = prsc->height0;
+ uint32_t pot_width = util_next_power_of_two(width);
+ uint32_t pot_height = util_next_power_of_two(height);
uint32_t offset = 0;
uint32_t utile_w = vc4_utile_width(rsc->cpp);
uint32_t utile_h = vc4_utile_height(rsc->cpp);
for (int i = prsc->last_level; i >= 0; i--) {
struct vc4_resource_slice *slice = &rsc->slices[i];
- uint32_t level_width = u_minify(width, i);
- uint32_t level_height = u_minify(height, i);
+
+ uint32_t level_width, level_height;
+ if (i == 0) {
+ level_width = width;
+ level_height = height;
+ } else {
+ level_width = u_minify(pot_width, i);
+ level_height = u_minify(pot_height, i);
+ }
if (rsc->tiled == VC4_TILING_FORMAT_LINEAR) {
slice->tiling = VC4_TILING_FORMAT_LINEAR;
cso->nr_cbufs = framebuffer->nr_cbufs;
+ pipe_surface_reference(&cso->zsbuf, framebuffer->zsbuf);
+
cso->width = framebuffer->width;
cso->height = framebuffer->height;
- pipe_surface_reference(&cso->zsbuf, framebuffer->zsbuf);
+ /* Nonzero texture mipmap levels are laid out as if they were in
+ * power-of-two-sized spaces. The renderbuffer config infers its
+ * stride from the width parameter, so we need to configure our
+ * framebuffer. Note that if the z/color buffers were mismatched
+ * sizes, we wouldn't be able to do this.
+ */
+ if ((cso->cbufs[0] && cso->cbufs[0]->u.tex.level) ||
+ (cso->zsbuf && cso->zsbuf->u.tex.level)) {
+ cso->width = util_next_power_of_two(cso->width);
+ }
vc4->dirty |= VC4_DIRTY_FRAMEBUFFER;
}