From 0220a428d7e8df487e3cbd8c6cdd8ca2f39117ad Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Marchesin?= Date: Sat, 22 Nov 2014 00:08:56 -0800 Subject: [PATCH] i915g: Fix offset for level != 0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For NPOT texture layouts, we want to be able to access texture levels other than 0 directly. Since the hw doesn't support that, We do it by adding the offset directly. Signed-off-by: Stéphane Marchesin --- src/gallium/drivers/i915/i915_context.h | 2 +- src/gallium/drivers/i915/i915_resource.h | 2 +- .../drivers/i915/i915_resource_texture.c | 2 +- src/gallium/drivers/i915/i915_state_emit.c | 4 ++- src/gallium/drivers/i915/i915_state_sampler.c | 25 ++++++++++++++++--- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index ec8cbbf1f52..40abf3c577f 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -157,7 +157,7 @@ struct i915_state unsigned sampler_enable_nr; /* texture image buffers */ - unsigned texbuffer[I915_TEX_UNITS][2]; + unsigned texbuffer[I915_TEX_UNITS][3]; /** Describes the current hardware vertex layout */ struct vertex_info vertex_info; diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h index 46241c9a8e9..ef99cfb5d3c 100644 --- a/src/gallium/drivers/i915/i915_resource.h +++ b/src/gallium/drivers/i915/i915_resource.h @@ -86,7 +86,7 @@ struct i915_texture { struct i915_winsys_buffer *buffer; }; -unsigned i915_texture_offset(struct i915_texture *tex, +unsigned i915_texture_offset(const struct i915_texture *tex, unsigned level, unsigned layer); void i915_init_screen_resource_functions(struct i915_screen *is); void i915_init_resource_functions(struct i915_context *i915); diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 6430c4bfcec..8abb99f2a1f 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -143,7 +143,7 @@ i915_texture_set_level_info(struct i915_texture *tex, tex->image_offset[level][0].nblocksy = 0; } -INLINE unsigned i915_texture_offset(struct i915_texture *tex, +unsigned i915_texture_offset(const struct i915_texture *tex, unsigned level, unsigned layer) { unsigned x, y; diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 6244f489c2c..92751f3cf8b 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -326,11 +326,13 @@ emit_map(struct i915_context *i915) if (enabled & (1 << unit)) { struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture); struct i915_winsys_buffer *buf = texture->buffer; + unsigned offset = i915->current.texbuffer[unit][2]; + assert(buf); count++; - OUT_RELOC(buf, I915_USAGE_SAMPLER, 0); + OUT_RELOC(buf, I915_USAGE_SAMPLER, offset); OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */ OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */ } diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 52f8b003ab1..eb62479b975 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -63,7 +63,7 @@ static void update_map(struct i915_context *i915, const struct i915_texture *tex, const struct i915_sampler_state *sampler, const struct pipe_sampler_view* view, - uint state[2]); + uint state[3]); @@ -300,13 +300,25 @@ static void update_map(struct i915_context *i915, const struct i915_texture *tex, const struct i915_sampler_state *sampler, const struct pipe_sampler_view* view, - uint state[2]) + uint state[3]) { const struct pipe_resource *pt = &tex->b.b; - uint format, pitch; - const uint width = pt->width0, height = pt->height0, depth = pt->depth0; + uint width = pt->width0, height = pt->height0, depth = pt->depth0; const uint num_levels = pt->last_level; + uint format, pitch; unsigned max_lod = num_levels * 4; + int first_level = view->u.tex.first_level; + bool is_npot = (!util_is_power_of_two(pt->width0) || !util_is_power_of_two(pt->height0)); + + /* + * This is a bit messy. i915 doesn't support NPOT with mipmaps, but we can + * still texture from a single level. This is useful to make u_blitter work. + */ + if (is_npot) { + width = u_minify(width, first_level); + height = u_minify(height, first_level); + max_lod = 1; + } assert(tex); assert(width); @@ -341,6 +353,11 @@ static void update_map(struct i915_context *i915, | MS4_CUBE_FACE_ENA_MASK | ((max_lod) << MS4_MAX_LOD_SHIFT) | ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); + + if (is_npot) + state[2] = i915_texture_offset(tex, first_level, 0); + else + state[2] = 0; } static void update_maps(struct i915_context *i915) -- 2.30.2