intel: Support mapping multisample miptrees

Add two new functions: intel_miptree_{map,unmap}_multisample, to which
intel_miptree_{map,unmap} dispatch. Only mapping flat, renderbuffer-like
miptrees are supported.

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
This commit is contained in:
Chad Versace 2012-07-27 20:42:31 -07:00
parent 4c0ccc13bd
commit e88cfbb95f
2 changed files with 126 additions and 6 deletions

View File

@ -397,6 +397,8 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,
struct intel_mipmap_tree *mt;
uint32_t depth = 1;
enum intel_msaa_layout msaa_layout = INTEL_MSAA_LAYOUT_NONE;
const uint32_t singlesample_width = width;
const uint32_t singlesample_height = height;
bool ok;
if (num_samples > 1) {
@ -476,6 +478,9 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,
goto fail;
}
mt->singlesample_width0 = singlesample_width;
mt->singlesample_height0 = singlesample_height;
return mt;
fail:
@ -1576,6 +1581,93 @@ intel_miptree_unmap_singlesample(struct intel_context *intel,
intel_miptree_release_map(mt, level, slice);
}
static void
intel_miptree_map_multisample(struct intel_context *intel,
struct intel_mipmap_tree *mt,
unsigned int level,
unsigned int slice,
unsigned int x,
unsigned int y,
unsigned int w,
unsigned int h,
GLbitfield mode,
void **out_ptr,
int *out_stride)
{
struct intel_miptree_map *map;
assert(mt->num_samples > 1);
/* Only flat, renderbuffer-like miptrees are supported. */
if (mt->target != GL_TEXTURE_2D ||
mt->first_level != 0 ||
mt->last_level != 0) {
_mesa_problem(&intel->ctx, "attempt to map a multisample miptree for "
"which (target, first_level, last_level != "
"(GL_TEXTURE_2D, 0, 0)");
goto fail;
}
map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
if (!map)
goto fail;
if (!mt->singlesample_mt) {
mt->singlesample_mt =
intel_miptree_create_for_renderbuffer(intel,
mt->format,
mt->singlesample_width0,
mt->singlesample_height0,
0 /*num_samples*/);
if (!mt->singlesample_mt)
goto fail;
map->singlesample_mt_is_tmp = true;
mt->need_downsample = true;
}
if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
mt->need_downsample = false;
intel_miptree_downsample(intel, mt);
intel_miptree_map_singlesample(intel, mt->singlesample_mt,
level, slice,
x, y, w, h,
mode,
out_ptr, out_stride);
return;
fail:
intel_miptree_release_map(mt, level, slice);
*out_ptr = NULL;
*out_stride = 0;
}
static void
intel_miptree_unmap_multisample(struct intel_context *intel,
struct intel_mipmap_tree *mt,
unsigned int level,
unsigned int slice)
{
struct intel_miptree_map *map = mt->level[level].slice[slice].map;
assert(mt->num_samples > 1);
if (!map)
return;
intel_miptree_unmap_singlesample(intel, mt->singlesample_mt, level, slice);
mt->need_downsample = false;
if (map->mode & GL_MAP_WRITE_BIT)
intel_miptree_upsample(intel, mt);
if (map->singlesample_mt_is_tmp)
intel_miptree_release(&mt->singlesample_mt);
intel_miptree_release_map(mt, level, slice);
}
void
intel_miptree_map(struct intel_context *intel,
struct intel_mipmap_tree *mt,
@ -1589,11 +1681,18 @@ intel_miptree_map(struct intel_context *intel,
void **out_ptr,
int *out_stride)
{
intel_miptree_map_singlesample(intel, mt,
level, slice,
x, y, w, h,
mode,
out_ptr, out_stride);
if (mt->num_samples <= 1)
intel_miptree_map_singlesample(intel, mt,
level, slice,
x, y, w, h,
mode,
out_ptr, out_stride);
else
intel_miptree_map_multisample(intel, mt,
level, slice,
x, y, w, h,
mode,
out_ptr, out_stride);
}
void
@ -1602,5 +1701,8 @@ intel_miptree_unmap(struct intel_context *intel,
unsigned int level,
unsigned int slice)
{
intel_miptree_unmap_singlesample(intel, mt, level, slice);
if (mt->num_samples <= 1)
intel_miptree_unmap_singlesample(intel, mt, level, slice);
else
intel_miptree_unmap_multisample(intel, mt, level, slice);
}

View File

@ -79,6 +79,12 @@ struct intel_miptree_map {
void *ptr;
/** Stride of the mapping. */
int stride;
/**
* intel_mipmap_tree::singlesample_mt is temporary storage that persists
* only for the duration of the map.
*/
bool singlesample_mt_is_tmp;
};
/**
@ -211,6 +217,18 @@ struct intel_mipmap_tree
GLuint num_samples;
bool compressed;
/**
* If num_samples > 0, then singlesample_width0 is the value that width0
* would have if instead a singlesample miptree were created. Note that,
* for non-interleaved msaa layouts, the two values are the same.
*
* If num_samples == 0, then singlesample_width0 is undefined.
*/
uint32_t singlesample_width0;
/** \see singlesample_width0 */
uint32_t singlesample_height0;
/**
* For 1D array, 2D array, cube, and 2D multisampled surfaces on Gen7: true
* if the surface only contains LOD 0, and hence no space is for LOD's