summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorStéphane Marchesin <[email protected]>2014-11-22 00:08:56 -0800
committerStéphane Marchesin <[email protected]>2014-11-22 00:13:39 -0800
commit0220a428d7e8df487e3cbd8c6cdd8ca2f39117ad (patch)
tree082e0fa80a6729b1ddb8485798ee063bd7fd5074 /src/gallium
parenta9b07870764db617f199745573bfccddf9b378f9 (diff)
i915g: Fix offset for level != 0
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/i915/i915_context.h2
-rw-r--r--src/gallium/drivers/i915/i915_resource.h2
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c2
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c4
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c25
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)