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:
parent
4c0ccc13bd
commit
e88cfbb95f
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue