mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 14:08:05 +02:00
Checkpoint lifting of intel_mipmap_tree (intel_mipmap_tree -> pipe_mipmap_tree and move some code)
This commit is contained in:
parent
95794abec4
commit
d9605cdf7c
10 changed files with 485 additions and 149 deletions
|
|
@ -53,6 +53,7 @@
|
|||
#include "intel_blit.h"
|
||||
#include "intel_buffer_objects.h"
|
||||
#include "intel_fbo.h"
|
||||
#include "intel_mipmap_tree.h"
|
||||
|
||||
#include "state_tracker/st_public.h"
|
||||
#include "state_tracker/st_context.h"
|
||||
|
|
@ -61,6 +62,11 @@
|
|||
#include "vblank.h"
|
||||
#include "utils.h"
|
||||
#include "xmlpool.h" /* for symbolic values of enum-type options */
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
|
||||
|
||||
#ifndef INTEL_DEBUG
|
||||
int INTEL_DEBUG = (0);
|
||||
#endif
|
||||
|
|
@ -377,6 +383,26 @@ intelCreateContext(const __GLcontextModes * mesaVis,
|
|||
// intel->pipe->glctx = ctx;
|
||||
// intel_init_region_functions(intel->pipe);
|
||||
|
||||
switch (intel->intelScreen->deviceID) {
|
||||
case PCI_CHIP_I945_G:
|
||||
case PCI_CHIP_I945_GM:
|
||||
case PCI_CHIP_I945_GME:
|
||||
case PCI_CHIP_G33_G:
|
||||
case PCI_CHIP_Q33_G:
|
||||
case PCI_CHIP_Q35_G:
|
||||
intel->pipe->mipmap_tree_layout = i945_miptree_layout;
|
||||
break;
|
||||
case PCI_CHIP_I915_G:
|
||||
case PCI_CHIP_I915_GM:
|
||||
case PCI_CHIP_I830_M:
|
||||
case PCI_CHIP_I855_GM:
|
||||
case PCI_CHIP_I865_G:
|
||||
intel->pipe->mipmap_tree_layout = i915_miptree_layout;
|
||||
default:
|
||||
assert(0); /*FIX*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* memory pools
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ target_to_target(GLenum target)
|
|||
}
|
||||
}
|
||||
|
||||
struct intel_mipmap_tree *
|
||||
struct pipe_mipmap_tree *
|
||||
intel_miptree_create(struct intel_context *intel,
|
||||
GLenum target,
|
||||
GLenum internal_format,
|
||||
|
|
@ -62,7 +62,7 @@ intel_miptree_create(struct intel_context *intel,
|
|||
GLuint depth0, GLuint cpp, GLuint compress_byte)
|
||||
{
|
||||
GLboolean ok;
|
||||
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
|
||||
struct pipe_mipmap_tree *mt = calloc(sizeof(*mt), 1);
|
||||
|
||||
DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
|
|
@ -79,29 +79,7 @@ intel_miptree_create(struct intel_context *intel,
|
|||
mt->compressed = compress_byte ? 1 : 0;
|
||||
mt->refcount = 1;
|
||||
|
||||
switch (intel->intelScreen->deviceID) {
|
||||
case PCI_CHIP_I945_G:
|
||||
case PCI_CHIP_I945_GM:
|
||||
case PCI_CHIP_I945_GME:
|
||||
case PCI_CHIP_G33_G:
|
||||
case PCI_CHIP_Q33_G:
|
||||
case PCI_CHIP_Q35_G:
|
||||
// ok = i945_miptree_layout(mt);
|
||||
break;
|
||||
case PCI_CHIP_I915_G:
|
||||
case PCI_CHIP_I915_GM:
|
||||
case PCI_CHIP_I830_M:
|
||||
case PCI_CHIP_I855_GM:
|
||||
case PCI_CHIP_I865_G:
|
||||
default:
|
||||
/* All the i830 chips and the i915 use this layout:
|
||||
*/
|
||||
// ok = i915_miptree_layout(mt);
|
||||
break;
|
||||
}
|
||||
|
||||
ok = 0; /* TODO */
|
||||
|
||||
ok = intel->pipe->mipmap_tree_layout(intel->pipe, mt);
|
||||
if (ok)
|
||||
mt->region = intel->pipe->region_alloc(intel->pipe,
|
||||
mt->cpp, mt->pitch, mt->total_height);
|
||||
|
|
@ -116,8 +94,8 @@ intel_miptree_create(struct intel_context *intel,
|
|||
|
||||
|
||||
void
|
||||
intel_miptree_reference(struct intel_mipmap_tree **dst,
|
||||
struct intel_mipmap_tree *src)
|
||||
intel_miptree_reference(struct pipe_mipmap_tree **dst,
|
||||
struct pipe_mipmap_tree *src)
|
||||
{
|
||||
src->refcount++;
|
||||
*dst = src;
|
||||
|
|
@ -126,7 +104,7 @@ intel_miptree_reference(struct intel_mipmap_tree **dst,
|
|||
|
||||
void
|
||||
intel_miptree_release(struct intel_context *intel,
|
||||
struct intel_mipmap_tree **mt)
|
||||
struct pipe_mipmap_tree **mt)
|
||||
{
|
||||
if (!*mt)
|
||||
return;
|
||||
|
|
@ -157,7 +135,7 @@ intel_miptree_release(struct intel_context *intel,
|
|||
* Not sure whether I want to pass gl_texture_image here.
|
||||
*/
|
||||
GLboolean
|
||||
intel_miptree_match_image(struct intel_mipmap_tree *mt,
|
||||
intel_miptree_match_image(struct pipe_mipmap_tree *mt,
|
||||
struct gl_texture_image *image,
|
||||
GLuint face, GLuint level)
|
||||
{
|
||||
|
|
@ -184,7 +162,7 @@ intel_miptree_match_image(struct intel_mipmap_tree *mt,
|
|||
|
||||
|
||||
void
|
||||
intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
|
||||
intel_miptree_set_level_info(struct pipe_mipmap_tree *mt,
|
||||
GLuint level,
|
||||
GLuint nr_images,
|
||||
GLuint x, GLuint y, GLuint w, GLuint h, GLuint d)
|
||||
|
|
@ -215,7 +193,7 @@ intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
|
|||
|
||||
|
||||
void
|
||||
intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
|
||||
intel_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
|
||||
GLuint level, GLuint img, GLuint x, GLuint y)
|
||||
{
|
||||
if (img == 0 && level == 0)
|
||||
|
|
@ -237,7 +215,7 @@ intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
|
|||
* These functions present that view to mesa:
|
||||
*/
|
||||
const GLuint *
|
||||
intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level)
|
||||
intel_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level)
|
||||
{
|
||||
static const GLuint zero = 0;
|
||||
|
||||
|
|
@ -249,7 +227,7 @@ intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level)
|
|||
|
||||
|
||||
GLuint
|
||||
intel_miptree_image_offset(struct intel_mipmap_tree * mt,
|
||||
intel_miptree_image_offset(struct pipe_mipmap_tree * mt,
|
||||
GLuint face, GLuint level)
|
||||
{
|
||||
if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)
|
||||
|
|
@ -269,7 +247,7 @@ intel_miptree_image_offset(struct intel_mipmap_tree * mt,
|
|||
*/
|
||||
GLubyte *
|
||||
intel_miptree_image_map(struct intel_context * intel,
|
||||
struct intel_mipmap_tree * mt,
|
||||
struct pipe_mipmap_tree * mt,
|
||||
GLuint face,
|
||||
GLuint level,
|
||||
GLuint * row_stride, GLuint * image_offsets)
|
||||
|
|
@ -291,7 +269,7 @@ intel_miptree_image_map(struct intel_context * intel,
|
|||
|
||||
void
|
||||
intel_miptree_image_unmap(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt)
|
||||
struct pipe_mipmap_tree *mt)
|
||||
{
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
intel->pipe->region_unmap(intel->pipe, mt->region);
|
||||
|
|
@ -303,7 +281,7 @@ intel_miptree_image_unmap(struct intel_context *intel,
|
|||
*/
|
||||
void
|
||||
intel_miptree_image_data(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *dst,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
GLuint face,
|
||||
GLuint level,
|
||||
void *src,
|
||||
|
|
@ -336,9 +314,9 @@ intel_miptree_image_data(struct intel_context *intel,
|
|||
*/
|
||||
void
|
||||
intel_miptree_image_copy(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *dst,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
GLuint face, GLuint level,
|
||||
struct intel_mipmap_tree *src)
|
||||
struct pipe_mipmap_tree *src)
|
||||
{
|
||||
GLuint width = src->level[level].width;
|
||||
GLuint height = src->level[level].height;
|
||||
|
|
|
|||
|
|
@ -34,89 +34,7 @@
|
|||
struct pipe_region;
|
||||
|
||||
|
||||
/* A layer on top of the pipe_regions code which adds:
|
||||
*
|
||||
* - Code to size and layout a region to hold a set of mipmaps.
|
||||
* - Query to determine if a new image fits in an existing tree.
|
||||
* - More refcounting
|
||||
* - maybe able to remove refcounting from pipe_region?
|
||||
* - ?
|
||||
*
|
||||
* The fixed mipmap layout of intel hardware where one offset
|
||||
* specifies the position of all images in a mipmap hierachy
|
||||
* complicates the implementation of GL texture image commands,
|
||||
* compared to hardware where each image is specified with an
|
||||
* independent offset.
|
||||
*
|
||||
* In an ideal world, each texture object would be associated with a
|
||||
* single bufmgr buffer or 2d pipe_region, and all the images within
|
||||
* the texture object would slot into the tree as they arrive. The
|
||||
* reality can be a little messier, as images can arrive from the user
|
||||
* with sizes that don't fit in the existing tree, or in an order
|
||||
* where the tree layout cannot be guessed immediately.
|
||||
*
|
||||
* This structure encodes an idealized mipmap tree. The GL image
|
||||
* commands build these where possible, otherwise store the images in
|
||||
* temporary system buffers.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Describes the location of each texture image within a texture region.
|
||||
*/
|
||||
struct intel_mipmap_level
|
||||
{
|
||||
GLuint level_offset;
|
||||
GLuint width;
|
||||
GLuint height;
|
||||
GLuint depth;
|
||||
GLuint nr_images;
|
||||
|
||||
/* Explicitly store the offset of each image for each cube face or
|
||||
* depth value. Pretty much have to accept that hardware formats
|
||||
* are going to be so diverse that there is no unified way to
|
||||
* compute the offsets of depth/cube images within a mipmap level,
|
||||
* so have to store them as a lookup table:
|
||||
*/
|
||||
GLuint *image_offset;
|
||||
};
|
||||
|
||||
struct intel_mipmap_tree
|
||||
{
|
||||
/* Effectively the key:
|
||||
*/
|
||||
GLenum target;
|
||||
GLenum internal_format;
|
||||
|
||||
GLuint first_level;
|
||||
GLuint last_level;
|
||||
|
||||
GLuint width0, height0, depth0; /**< Level zero image dimensions */
|
||||
GLuint cpp;
|
||||
GLboolean compressed;
|
||||
|
||||
/* Derived from the above:
|
||||
*/
|
||||
GLuint pitch;
|
||||
GLuint depth_pitch; /* per-image on i945? */
|
||||
GLuint total_height;
|
||||
|
||||
/* Includes image offset tables:
|
||||
*/
|
||||
struct intel_mipmap_level level[MAX_TEXTURE_LEVELS];
|
||||
|
||||
/* The data is held here:
|
||||
*/
|
||||
struct pipe_region *region;
|
||||
|
||||
/* These are also refcounted:
|
||||
*/
|
||||
GLuint refcount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
|
||||
struct pipe_mipmap_tree *intel_miptree_create(struct intel_context *intel,
|
||||
GLenum target,
|
||||
GLenum internal_format,
|
||||
GLuint first_level,
|
||||
|
|
@ -127,15 +45,15 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
|
|||
GLuint cpp,
|
||||
GLuint compress_byte);
|
||||
|
||||
void intel_miptree_reference(struct intel_mipmap_tree **dst,
|
||||
struct intel_mipmap_tree *src);
|
||||
void intel_miptree_reference(struct pipe_mipmap_tree **dst,
|
||||
struct pipe_mipmap_tree *src);
|
||||
|
||||
void intel_miptree_release(struct intel_context *intel,
|
||||
struct intel_mipmap_tree **mt);
|
||||
struct pipe_mipmap_tree **mt);
|
||||
|
||||
/* Check if an image fits an existing mipmap tree layout
|
||||
*/
|
||||
GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt,
|
||||
GLboolean intel_miptree_match_image(struct pipe_mipmap_tree *mt,
|
||||
struct gl_texture_image *image,
|
||||
GLuint face, GLuint level);
|
||||
|
||||
|
|
@ -143,35 +61,35 @@ GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt,
|
|||
* well.
|
||||
*/
|
||||
GLubyte *intel_miptree_image_map(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt,
|
||||
struct pipe_mipmap_tree *mt,
|
||||
GLuint face,
|
||||
GLuint level,
|
||||
GLuint * row_stride, GLuint * image_stride);
|
||||
|
||||
void intel_miptree_image_unmap(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt);
|
||||
struct pipe_mipmap_tree *mt);
|
||||
|
||||
|
||||
/* Return the linear offset of an image relative to the start of the
|
||||
* tree:
|
||||
*/
|
||||
GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
|
||||
GLuint intel_miptree_image_offset(struct pipe_mipmap_tree *mt,
|
||||
GLuint face, GLuint level);
|
||||
|
||||
/* Return pointers to each 2d slice within an image. Indexed by depth
|
||||
* value.
|
||||
*/
|
||||
const GLuint *intel_miptree_depth_offsets(struct intel_mipmap_tree *mt,
|
||||
const GLuint *intel_miptree_depth_offsets(struct pipe_mipmap_tree *mt,
|
||||
GLuint level);
|
||||
|
||||
|
||||
void intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
|
||||
void intel_miptree_set_level_info(struct pipe_mipmap_tree *mt,
|
||||
GLuint level,
|
||||
GLuint nr_images,
|
||||
GLuint x, GLuint y,
|
||||
GLuint w, GLuint h, GLuint d);
|
||||
|
||||
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
|
||||
void intel_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
|
||||
GLuint level,
|
||||
GLuint img, GLuint x, GLuint y);
|
||||
|
||||
|
|
@ -179,7 +97,7 @@ void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
|
|||
/* Upload an image into a tree
|
||||
*/
|
||||
void intel_miptree_image_data(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *dst,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
GLuint face,
|
||||
GLuint level,
|
||||
void *src,
|
||||
|
|
@ -188,14 +106,14 @@ void intel_miptree_image_data(struct intel_context *intel,
|
|||
/* Copy an image between two trees
|
||||
*/
|
||||
void intel_miptree_image_copy(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *dst,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
GLuint face, GLuint level,
|
||||
struct intel_mipmap_tree *src);
|
||||
struct pipe_mipmap_tree *src);
|
||||
|
||||
/* i915_mipmap_tree.c:
|
||||
*/
|
||||
GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt);
|
||||
GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt);
|
||||
GLboolean i915_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
|
||||
GLboolean i945_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct intel_texture_object
|
|||
/* On validation any active images held in main memory or in other
|
||||
* regions will be copied to this region and the old storage freed.
|
||||
*/
|
||||
struct intel_mipmap_tree *mt;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
|
||||
GLboolean imageOverride;
|
||||
GLint depthOverride;
|
||||
|
|
@ -71,7 +71,7 @@ struct intel_texture_image
|
|||
* Else if intelImage->base.Data != NULL, image is stored there.
|
||||
* Else there is no image data.
|
||||
*/
|
||||
struct intel_mipmap_tree *mt;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@
|
|||
#include "texstore.h"
|
||||
|
||||
#include "intel_context.h"
|
||||
#include "intel_mipmap_tree.h"
|
||||
#include "intel_buffer_objects.h"
|
||||
#include "intel_batchbuffer.h"
|
||||
#include "intel_mipmap_tree.h"
|
||||
#include "intel_tex.h"
|
||||
#include "intel_ioctl.h"
|
||||
#include "intel_blit.h"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include "intel_mipmap_tree.h"
|
||||
#include "intel_tex.h"
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,17 +30,57 @@
|
|||
* Michel Dänzer <michel@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "intel_mipmap_tree.h"
|
||||
#include "intel_tex_layout.h"
|
||||
#include "macros.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "intel_mipmap_tree.h"
|
||||
|
||||
|
||||
static GLuint minify( GLuint d )
|
||||
{
|
||||
return MAX2(1, d>>1);
|
||||
}
|
||||
|
||||
static int align(int value, int alignment)
|
||||
{
|
||||
return (value + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
|
||||
|
||||
static void
|
||||
mipmaptree_set_level_info(struct pipe_mipmap_tree *mt,
|
||||
GLuint level,
|
||||
GLuint nr_images,
|
||||
GLuint x, GLuint y, GLuint w, GLuint h, GLuint d)
|
||||
{
|
||||
assert(level < MAX_TEXTURE_LEVELS);
|
||||
|
||||
mt->level[level].width = w;
|
||||
mt->level[level].height = h;
|
||||
mt->level[level].depth = d;
|
||||
mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp;
|
||||
mt->level[level].nr_images = nr_images;
|
||||
|
||||
/*
|
||||
DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
|
||||
level, w, h, d, x, y, mt->level[level].level_offset);
|
||||
*/
|
||||
|
||||
/* Not sure when this would happen, but anyway:
|
||||
*/
|
||||
if (mt->level[level].image_offset) {
|
||||
free(mt->level[level].image_offset);
|
||||
mt->level[level].image_offset = NULL;
|
||||
}
|
||||
|
||||
assert(nr_images);
|
||||
|
||||
mt->level[level].image_offset = malloc(nr_images * sizeof(GLuint));
|
||||
mt->level[level].image_offset[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i945_miptree_layout_2d( struct pipe_mipmap_tree *mt )
|
||||
{
|
||||
GLint align_h = 2, align_w = 4;
|
||||
GLuint level;
|
||||
|
|
@ -73,8 +113,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
|
|||
for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
|
||||
GLuint img_height;
|
||||
|
||||
intel_miptree_set_level_info(mt, level, 1, x, y, width,
|
||||
height, 1);
|
||||
mipmaptree_set_level_info(mt, level, 1, x, y, width, height, 1);
|
||||
|
||||
if (mt->compressed)
|
||||
img_height = MAX2(1, height/4);
|
||||
|
|
@ -100,3 +139,316 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
|
|||
height = minify(height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const GLint initial_offsets[6][2] = {
|
||||
{0, 0},
|
||||
{0, 2},
|
||||
{1, 0},
|
||||
{1, 2},
|
||||
{1, 1},
|
||||
{1, 3}
|
||||
};
|
||||
|
||||
static const GLint step_offsets[6][2] = {
|
||||
{0, 2},
|
||||
{0, 2},
|
||||
{-1, 2},
|
||||
{-1, 2},
|
||||
{-1, 1},
|
||||
{-1, 1}
|
||||
};
|
||||
|
||||
|
||||
GLboolean
|
||||
i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
|
||||
{
|
||||
GLint level;
|
||||
|
||||
switch (mt->target) {
|
||||
case GL_TEXTURE_CUBE_MAP:{
|
||||
const GLuint dim = mt->width0;
|
||||
GLuint face;
|
||||
GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;
|
||||
|
||||
assert(lvlWidth == lvlHeight); /* cubemap images are square */
|
||||
|
||||
/* double pitch for cube layouts */
|
||||
mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
|
||||
mt->total_height = dim * 4;
|
||||
|
||||
for (level = mt->first_level; level <= mt->last_level; level++) {
|
||||
intel_miptree_set_level_info(mt, level, 6,
|
||||
0, 0,
|
||||
/*OLD: mt->pitch, mt->total_height,*/
|
||||
lvlWidth, lvlHeight,
|
||||
1);
|
||||
lvlWidth /= 2;
|
||||
lvlHeight /= 2;
|
||||
}
|
||||
|
||||
for (face = 0; face < 6; face++) {
|
||||
GLuint x = initial_offsets[face][0] * dim;
|
||||
GLuint y = initial_offsets[face][1] * dim;
|
||||
GLuint d = dim;
|
||||
|
||||
for (level = mt->first_level; level <= mt->last_level; level++) {
|
||||
intel_miptree_set_image_offset(mt, level, face, x, y);
|
||||
|
||||
if (d == 0)
|
||||
_mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n",
|
||||
face, level, mt->first_level, mt->last_level);
|
||||
|
||||
d >>= 1;
|
||||
x += step_offsets[face][0] * d;
|
||||
y += step_offsets[face][1] * d;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_TEXTURE_3D:{
|
||||
GLuint width = mt->width0;
|
||||
GLuint height = mt->height0;
|
||||
GLuint depth = mt->depth0;
|
||||
GLuint stack_height = 0;
|
||||
|
||||
/* Calculate the size of a single slice.
|
||||
*/
|
||||
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
|
||||
|
||||
/* XXX: hardware expects/requires 9 levels at minimum.
|
||||
*/
|
||||
for (level = mt->first_level; level <= MAX2(8, mt->last_level);
|
||||
level++) {
|
||||
intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height,
|
||||
width, height, depth);
|
||||
|
||||
|
||||
stack_height += MAX2(2, height);
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
}
|
||||
|
||||
/* Fixup depth image_offsets:
|
||||
*/
|
||||
depth = mt->depth0;
|
||||
for (level = mt->first_level; level <= mt->last_level; level++) {
|
||||
GLuint i;
|
||||
for (i = 0; i < depth; i++)
|
||||
intel_miptree_set_image_offset(mt, level, i,
|
||||
0, i * stack_height);
|
||||
|
||||
depth = minify(depth);
|
||||
}
|
||||
|
||||
|
||||
/* Multiply slice size by texture depth for total size. It's
|
||||
* remarkable how wasteful of memory the i915 texture layouts
|
||||
* are. They are largely fixed in the i945.
|
||||
*/
|
||||
mt->total_height = stack_height * mt->depth0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:{
|
||||
GLuint width = mt->width0;
|
||||
GLuint height = mt->height0;
|
||||
GLuint img_height;
|
||||
|
||||
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
|
||||
mt->total_height = 0;
|
||||
|
||||
for (level = mt->first_level; level <= mt->last_level; level++) {
|
||||
intel_miptree_set_level_info(mt, level, 1,
|
||||
0, mt->total_height,
|
||||
width, height, 1);
|
||||
|
||||
if (mt->compressed)
|
||||
img_height = MAX2(1, height / 4);
|
||||
else
|
||||
img_height = (MAX2(2, height) + 1) & ~1;
|
||||
|
||||
mt->total_height += img_height;
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
|
||||
mt->pitch,
|
||||
mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
|
||||
*/
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
|
||||
{
|
||||
GLint level;
|
||||
|
||||
switch (mt->target) {
|
||||
case GL_TEXTURE_CUBE_MAP:{
|
||||
const GLuint dim = mt->width0;
|
||||
GLuint face;
|
||||
GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;
|
||||
|
||||
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)
|
||||
mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
|
||||
else
|
||||
mt->pitch = 14 * 8;
|
||||
|
||||
mt->total_height = dim * 4 + 4;
|
||||
|
||||
/* Set all the levels to effectively occupy the whole rectangular region.
|
||||
*/
|
||||
for (level = mt->first_level; level <= mt->last_level; level++) {
|
||||
intel_miptree_set_level_info(mt, level, 6,
|
||||
0, 0,
|
||||
lvlWidth, lvlHeight, 1);
|
||||
lvlWidth /= 2;
|
||||
lvlHeight /= 2;
|
||||
}
|
||||
|
||||
|
||||
for (face = 0; face < 6; face++) {
|
||||
GLuint x = initial_offsets[face][0] * dim;
|
||||
GLuint y = initial_offsets[face][1] * dim;
|
||||
GLuint d = dim;
|
||||
|
||||
if (dim == 4 && face >= 4) {
|
||||
y = mt->total_height - 4;
|
||||
x = (face - 4) * 8;
|
||||
}
|
||||
else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
|
||||
y = mt->total_height - 4;
|
||||
x = face * 8;
|
||||
}
|
||||
|
||||
for (level = mt->first_level; level <= mt->last_level; level++) {
|
||||
intel_miptree_set_image_offset(mt, level, face, x, y);
|
||||
|
||||
d >>= 1;
|
||||
|
||||
switch (d) {
|
||||
case 4:
|
||||
switch (face) {
|
||||
case FACE_POS_X:
|
||||
case FACE_NEG_X:
|
||||
x += step_offsets[face][0] * d;
|
||||
y += step_offsets[face][1] * d;
|
||||
break;
|
||||
case FACE_POS_Y:
|
||||
case FACE_NEG_Y:
|
||||
y += 12;
|
||||
x -= 8;
|
||||
break;
|
||||
case FACE_POS_Z:
|
||||
case FACE_NEG_Z:
|
||||
y = mt->total_height - 4;
|
||||
x = (face - 4) * 8;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
y = mt->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 GL_TEXTURE_3D:{
|
||||
GLuint width = mt->width0;
|
||||
GLuint height = mt->height0;
|
||||
GLuint depth = mt->depth0;
|
||||
GLuint pack_x_pitch, pack_x_nr;
|
||||
GLuint pack_y_pitch;
|
||||
GLuint level;
|
||||
|
||||
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
|
||||
mt->total_height = 0;
|
||||
|
||||
pack_y_pitch = MAX2(mt->height0, 2);
|
||||
pack_x_pitch = mt->pitch;
|
||||
pack_x_nr = 1;
|
||||
|
||||
for (level = mt->first_level; level <= mt->last_level; level++) {
|
||||
GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6;
|
||||
GLint x = 0;
|
||||
GLint y = 0;
|
||||
GLint q, j;
|
||||
|
||||
intel_miptree_set_level_info(mt, level, nr_images,
|
||||
0, mt->total_height,
|
||||
width, height, depth);
|
||||
|
||||
for (q = 0; q < nr_images;) {
|
||||
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
|
||||
intel_miptree_set_image_offset(mt, level, q, x, y);
|
||||
x += pack_x_pitch;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y += pack_y_pitch;
|
||||
}
|
||||
|
||||
|
||||
mt->total_height += y;
|
||||
|
||||
if (pack_x_pitch > 4) {
|
||||
pack_x_pitch >>= 1;
|
||||
pack_x_nr <<= 1;
|
||||
assert(pack_x_pitch * pack_x_nr <= mt->pitch);
|
||||
}
|
||||
|
||||
if (pack_y_pitch > 2) {
|
||||
pack_y_pitch >>= 1;
|
||||
}
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GL_TEXTURE_1D:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_RECTANGLE_ARB:
|
||||
i945_miptree_layout_2d(mt);
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()");
|
||||
}
|
||||
|
||||
/*
|
||||
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
|
||||
mt->pitch,
|
||||
mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
|
||||
*/
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,6 @@
|
|||
#include "macros.h"
|
||||
|
||||
|
||||
static GLuint minify( GLuint d )
|
||||
{
|
||||
return MAX2(1, d>>1);
|
||||
}
|
||||
extern void i915_miptree_layout_2d( struct pipe_context *, struct pipe_mipmap_tree *mt );
|
||||
|
||||
extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt );
|
||||
extern void i945_miptree_layout_2d( struct pipe_context *, struct pipe_mipmap_tree *mt );
|
||||
|
|
|
|||
|
|
@ -207,6 +207,14 @@ struct pipe_context {
|
|||
unsigned long offset,
|
||||
unsigned long size,
|
||||
void *data);
|
||||
|
||||
/*
|
||||
* Texture functions
|
||||
*/
|
||||
GLboolean (*mipmap_tree_layout)( struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *mt );
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -292,6 +292,61 @@ struct pipe_texture_object
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Describes the location of each texture image within a texture region.
|
||||
*/
|
||||
struct pipe_mipmap_level
|
||||
{
|
||||
GLuint level_offset;
|
||||
GLuint width;
|
||||
GLuint height;
|
||||
GLuint depth;
|
||||
GLuint nr_images;
|
||||
|
||||
/* Explicitly store the offset of each image for each cube face or
|
||||
* depth value. Pretty much have to accept that hardware formats
|
||||
* are going to be so diverse that there is no unified way to
|
||||
* compute the offsets of depth/cube images within a mipmap level,
|
||||
* so have to store them as a lookup table:
|
||||
*/
|
||||
GLuint *image_offset;
|
||||
};
|
||||
|
||||
struct pipe_mipmap_tree
|
||||
{
|
||||
/* Effectively the key:
|
||||
*/
|
||||
GLenum target;
|
||||
GLenum internal_format;
|
||||
|
||||
GLuint first_level;
|
||||
GLuint last_level;
|
||||
|
||||
GLuint width0, height0, depth0; /**< Level zero image dimensions */
|
||||
GLuint cpp;
|
||||
GLboolean compressed;
|
||||
|
||||
/* Derived from the above:
|
||||
*/
|
||||
GLuint pitch;
|
||||
GLuint depth_pitch; /* per-image on i945? */
|
||||
GLuint total_height;
|
||||
|
||||
/* Includes image offset tables:
|
||||
*/
|
||||
struct pipe_mipmap_level level[MAX_TEXTURE_LEVELS];
|
||||
|
||||
/* The data is held here:
|
||||
*/
|
||||
struct pipe_region *region;
|
||||
|
||||
/* These are also refcounted:
|
||||
*/
|
||||
GLuint refcount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct pipe_buffer_handle;
|
||||
|
||||
#define PIPE_BUFFER_FLAG_READ 0x1
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue