diff options
-rw-r--r-- | src/gallium/drivers/i915simple/i915_texture.c | 269 |
1 files changed, 141 insertions, 128 deletions
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index d591b09e3c8..09518fafe76 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -42,12 +42,58 @@ #include "i915_debug.h" #include "i915_screen.h" +/* + * Helper function and arrays + */ + +/** + * Initial offset for Cube map. + */ +static const int initial_offsets[6][2] = { + {0, 0}, + {0, 2}, + {1, 0}, + {1, 2}, + {1, 1}, + {1, 3} +}; + +/** + * Step offsets for Cube map. + */ +static const int step_offsets[6][2] = { + {0, 2}, + {0, 2}, + {-1, 2}, + {-1, 2}, + {-1, 1}, + {-1, 1} +}; static unsigned minify( unsigned d ) { return MAX2(1, d>>1); } +static unsigned +power_of_two(unsigned x) +{ + unsigned value = 1; + while (value <= x) + value = value << 1; + return value; +} + +static unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +/* + * More advanced helper funcs + */ static void @@ -86,7 +132,6 @@ i915_miptree_set_level_info(struct i915_texture *tex, tex->image_offset[level][0] = 0; } - static void i915_miptree_set_image_offset(struct i915_texture *tex, unsigned level, unsigned img, unsigned x, unsigned y) @@ -97,27 +142,17 @@ i915_miptree_set_image_offset(struct i915_texture *tex, assert(img < tex->nr_images[level]); tex->image_offset[level][img] = (x + y * tex->pitch); - /* - DBG("%s level %d img %d pos %d,%d image_offset %x\n", + printf("%s level %d img %d pos %d,%d image_offset %x\n", __FUNCTION__, level, img, x, y, tex->image_offset[level][img]); */ } -static unsigned -power_of_two(unsigned x) -{ - unsigned value = 1; - while (value <= x) - value = value << 1; - return value; -} -static unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} +/* + * Layout functions + */ + /** * Special case to deal with display targets. @@ -144,11 +179,11 @@ i915_displaytarget_layout(struct i915_texture *tex) tex->total_height = tex->base.height[0]; } -/* + /* printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, tex->base.width[0], tex->base.height[0], pt->cpp, tex->pitch, tex->total_height, tex->pitch * tex->total_height * 4); -*/ + */ return 1; } @@ -221,25 +256,93 @@ i945_miptree_layout_2d( struct i915_texture *tex ) } } +static void +i945_miptree_layout_cube(struct i915_texture *tex) +{ + struct pipe_texture *pt = &tex->base; + unsigned level; -static const int initial_offsets[6][2] = { - {0, 0}, - {0, 2}, - {1, 0}, - {1, 2}, - {1, 1}, - {1, 3} -}; + const unsigned dim = pt->width[0]; + unsigned face; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; -static const int step_offsets[6][2] = { - {0, 2}, - {0, 2}, - {-1, 2}, - {-1, 2}, - {-1, 1}, - {-1, 1} -}; + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* Depending on the size of the largest images, pitch can be + * determined either by the old-style packing of cubemap faces, + * or the final row of 4x4, 2x2 and 1x1 faces below this. + */ + if (dim > 32) + tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; + else + tex->pitch = 14 * 8; + + tex->total_height = dim * 4 + 4; + + /* Set all the levels to effectively occupy the whole rectangular region. + */ + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 6, 0, 0, lvlWidth, lvlHeight, 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + for (face = 0; face < 6; face++) { + unsigned x = initial_offsets[face][0] * dim; + unsigned y = initial_offsets[face][1] * dim; + unsigned d = dim; + + if (dim == 4 && face >= 4) { + y = tex->total_height - 4; + x = (face - 4) * 8; + } + else if (dim < 4 && (face > 0)) { + y = tex->total_height - 4; + x = face * 8; + } + + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_image_offset(tex, level, face, x, y); + + d >>= 1; + + switch (d) { + case 4: + switch (face) { + case PIPE_TEX_FACE_POS_X: + case PIPE_TEX_FACE_NEG_X: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + case PIPE_TEX_FACE_POS_Y: + case PIPE_TEX_FACE_NEG_Y: + y += 12; + x -= 8; + break; + case PIPE_TEX_FACE_POS_Z: + case PIPE_TEX_FACE_NEG_Z: + y = tex->total_height - 4; + x = (face - 4) * 8; + break; + } + + case 2: + y = tex->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + } + } + } +} static boolean i915_miptree_layout(struct i915_texture * tex) @@ -372,99 +475,15 @@ i945_miptree_layout(struct i915_texture * tex) unsigned level; switch (pt->target) { - case PIPE_TEXTURE_CUBE:{ - const unsigned dim = pt->width[0]; - unsigned face; - unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; - - assert(lvlWidth == lvlHeight); /* cubemap images are square */ - - /* Depending on the size of the largest images, pitch can be - * determined either by the old-style packing of cubemap faces, - * or the final row of 4x4, 2x2 and 1x1 faces below this. - */ - if (dim > 32) - tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; - else - tex->pitch = 14 * 8; - - tex->total_height = dim * 4 + 4; - - /* Set all the levels to effectively occupy the whole rectangular region. - */ - for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 6, - 0, 0, - lvlWidth, lvlHeight, 1); - lvlWidth /= 2; - lvlHeight /= 2; - } - - - for (face = 0; face < 6; face++) { - unsigned x = initial_offsets[face][0] * dim; - unsigned y = initial_offsets[face][1] * dim; - unsigned d = dim; - - if (dim == 4 && face >= 4) { - y = tex->total_height - 4; - x = (face - 4) * 8; - } - else if (dim < 4 && (face > 0)) { - y = tex->total_height - 4; - x = face * 8; - } - - for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_image_offset(tex, level, face, x, y); - - d >>= 1; - - switch (d) { - case 4: - switch (face) { - case PIPE_TEX_FACE_POS_X: - case PIPE_TEX_FACE_NEG_X: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - case PIPE_TEX_FACE_POS_Y: - case PIPE_TEX_FACE_NEG_Y: - y += 12; - x -= 8; - break; - case PIPE_TEX_FACE_POS_Z: - case PIPE_TEX_FACE_NEG_Z: - y = tex->total_height - 4; - x = (face - 4) * 8; - break; - } - - case 2: - y = tex->total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - break; - } + case PIPE_TEXTURE_CUBE: + i945_miptree_layout_cube(tex); + break; case PIPE_TEXTURE_3D:{ unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; - unsigned level; tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; tex->total_height = 0; @@ -602,11 +621,6 @@ i915_texture_release(struct pipe_screen *screen, *pt = NULL; } - - -/* - * XXX note: same as code in sp_surface.c - */ static struct pipe_surface * i915_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, @@ -631,7 +645,7 @@ i915_get_tex_surface(struct pipe_screen *screen, assert(zslice == 0); } - ps = CALLOC_STRUCT(pipe_surface);//ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface); if (ps) { ps->refcount = 1; ps->winsys = ws; @@ -649,7 +663,6 @@ i915_get_tex_surface(struct pipe_screen *screen, return ps; } - void i915_init_texture_functions(struct i915_context *i915) { |