static void
i915_miptree_layout_cube(struct intel_mipmap_tree * mt)
{
- const GLuint dim = mt->width0;
+ const GLuint dim = mt->physical_width0;
GLuint face;
- GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;
+ GLuint lvlWidth = mt->physical_width0, lvlHeight = mt->physical_height0;
GLint level;
assert(lvlWidth == lvlHeight); /* cubemap images are square */
static void
i915_miptree_layout_3d(struct intel_mipmap_tree * mt)
{
- GLuint width = mt->width0;
- GLuint height = mt->height0;
- GLuint depth = mt->depth0;
+ GLuint width = mt->physical_width0;
+ GLuint height = mt->physical_height0;
+ GLuint depth = mt->physical_depth0;
GLuint stack_height = 0;
GLint level;
/* Calculate the size of a single slice. */
- mt->total_width = mt->width0;
+ mt->total_width = mt->physical_width0;
/* XXX: hardware expects/requires 9 levels at minimum. */
for (level = mt->first_level; level <= MAX2(8, mt->last_level); level++) {
}
/* Fixup depth image_offsets: */
- depth = mt->depth0;
+ depth = mt->physical_depth0;
for (level = mt->first_level; level <= mt->last_level; level++) {
GLuint i;
for (i = 0; i < depth; i++) {
* remarkable how wasteful of memory the i915 texture layouts
* are. They are largely fixed in the i945.
*/
- mt->total_height = stack_height * mt->depth0;
+ mt->total_height = stack_height * mt->physical_depth0;
}
static void
i915_miptree_layout_2d(struct intel_mipmap_tree * mt)
{
- GLuint width = mt->width0;
- GLuint height = mt->height0;
+ GLuint width = mt->physical_width0;
+ GLuint height = mt->physical_height0;
GLuint img_height;
GLint level;
- mt->total_width = mt->width0;
+ mt->total_width = mt->physical_width0;
mt->total_height = 0;
for (level = mt->first_level; level <= mt->last_level; level++) {
static void
i945_miptree_layout_cube(struct intel_mipmap_tree * mt)
{
- const GLuint dim = mt->width0;
+ const GLuint dim = mt->physical_width0;
GLuint face;
- GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;
+ GLuint lvlWidth = mt->physical_width0, lvlHeight = mt->physical_height0;
GLint level;
assert(lvlWidth == lvlHeight); /* cubemap images are square */
static void
i945_miptree_layout_3d(struct intel_mipmap_tree * mt)
{
- GLuint width = mt->width0;
- GLuint height = mt->height0;
- GLuint depth = mt->depth0;
+ GLuint width = mt->physical_width0;
+ GLuint height = mt->physical_height0;
+ GLuint depth = mt->physical_depth0;
GLuint pack_x_pitch, pack_x_nr;
GLuint pack_y_pitch;
GLuint level;
- mt->total_width = mt->width0;
+ mt->total_width = mt->physical_width0;
mt->total_height = 0;
- pack_y_pitch = MAX2(mt->height0, 2);
+ pack_y_pitch = MAX2(mt->physical_height0, 2);
pack_x_pitch = mt->total_width;
pack_x_nr = 1;
GLuint height0,
GLuint depth0,
bool for_region,
- GLuint num_samples,
- enum intel_msaa_layout msaa_layout)
+ GLuint num_samples)
{
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
int compress_byte = 0;
mt->format = format;
mt->first_level = first_level;
mt->last_level = last_level;
- mt->width0 = width0;
- mt->height0 = height0;
+ mt->logical_width0 = width0;
+ mt->logical_height0 = height0;
+ mt->logical_depth0 = depth0;
mt->cpp = compress_byte ? compress_byte : _mesa_get_format_bytes(mt->format);
mt->num_samples = num_samples;
mt->compressed = compress_byte ? 1 : 0;
- mt->msaa_layout = msaa_layout;
+ mt->msaa_layout = INTEL_MSAA_LAYOUT_NONE;
mt->refcount = 1;
+ if (num_samples > 1) {
+ /* Adjust width/height/depth for MSAA */
+ mt->msaa_layout = compute_msaa_layout(intel, format);
+ if (mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
+ /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
+ *
+ * "Any of the other messages (sample*, LOD, load4) used with a
+ * (4x) multisampled surface will in-effect sample a surface with
+ * double the height and width as that indicated in the surface
+ * state. Each pixel position on the original-sized surface is
+ * replaced with a 2x2 of samples with the following arrangement:
+ *
+ * sample 0 sample 2
+ * sample 1 sample 3"
+ *
+ * Thus, when sampling from a multisampled texture, it behaves as
+ * though the layout in memory for (x,y,sample) is:
+ *
+ * (0,0,0) (0,0,2) (1,0,0) (1,0,2)
+ * (0,0,1) (0,0,3) (1,0,1) (1,0,3)
+ *
+ * (0,1,0) (0,1,2) (1,1,0) (1,1,2)
+ * (0,1,1) (0,1,3) (1,1,1) (1,1,3)
+ *
+ * However, the actual layout of multisampled data in memory is:
+ *
+ * (0,0,0) (1,0,0) (0,0,1) (1,0,1)
+ * (0,1,0) (1,1,0) (0,1,1) (1,1,1)
+ *
+ * (0,0,2) (1,0,2) (0,0,3) (1,0,3)
+ * (0,1,2) (1,1,2) (0,1,3) (1,1,3)
+ *
+ * This pattern repeats for each 2x2 pixel block.
+ *
+ * As a result, when calculating the size of our 4-sample buffer for
+ * an odd width or height, we have to align before scaling up because
+ * sample 3 is in that bottom right 2x2 block.
+ */
+ switch (num_samples) {
+ case 4:
+ width0 = ALIGN(width0, 2) * 2;
+ height0 = ALIGN(height0, 2) * 2;
+ break;
+ case 8:
+ width0 = ALIGN(width0, 2) * 4;
+ height0 = ALIGN(height0, 2) * 2;
+ break;
+ default:
+ /* num_samples should already have been quantized to 0, 1, 4, or
+ * 8.
+ */
+ assert(false);
+ }
+ } else {
+ /* Non-interleaved */
+ depth0 *= num_samples;
+ }
+ }
+
/* array_spacing_lod0 is only used for non-IMS MSAA surfaces. TODO: can we
* use it elsewhere?
*/
- switch (msaa_layout) {
+ switch (mt->msaa_layout) {
case INTEL_MSAA_LAYOUT_NONE:
case INTEL_MSAA_LAYOUT_IMS:
mt->array_spacing_lod0 = false;
if (target == GL_TEXTURE_CUBE_MAP) {
assert(depth0 == 1);
- mt->depth0 = 6;
- } else {
- mt->depth0 = depth0;
+ depth0 = 6;
}
+ mt->physical_width0 = width0;
+ mt->physical_height0 = height0;
+ mt->physical_depth0 = depth0;
+
if (!for_region &&
_mesa_is_depthstencil_format(_mesa_get_format_base_format(format)) &&
(intel->must_use_separate_stencil ||
(intel->has_separate_stencil &&
intel->vtbl.is_hiz_depth_format(intel, format)))) {
- /* MSAA stencil surfaces always use IMS layout. */
- enum intel_msaa_layout msaa_layout =
- num_samples > 1 ? INTEL_MSAA_LAYOUT_IMS : INTEL_MSAA_LAYOUT_NONE;
mt->stencil_mt = intel_miptree_create(intel,
mt->target,
MESA_FORMAT_S8,
mt->first_level,
mt->last_level,
- mt->width0,
- mt->height0,
- mt->depth0,
+ mt->logical_width0,
+ mt->logical_height0,
+ mt->logical_depth0,
true,
num_samples,
- msaa_layout,
false /* force_y_tiling */);
if (!mt->stencil_mt) {
intel_miptree_release(&mt);
GLuint depth0,
bool expect_accelerated_upload,
GLuint num_samples,
- enum intel_msaa_layout msaa_layout,
bool force_y_tiling)
{
struct intel_mipmap_tree *mt;
etc_format = (format != tex_format) ? tex_format : MESA_FORMAT_NONE;
base_format = _mesa_get_format_base_format(format);
- if (msaa_layout != INTEL_MSAA_LAYOUT_NONE) {
+ if (num_samples > 1) {
/* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
* Surface"):
*
mt = intel_miptree_create_internal(intel, target, format,
first_level, last_level, width0,
height0, depth0,
- false, num_samples, msaa_layout);
+ false, num_samples);
/*
* pitch == 0 || height == 0 indicates the null texture
*/
mt = intel_miptree_create_internal(intel, target, format,
0, 0,
region->width, region->height, 1,
- true, 0 /* num_samples */,
- INTEL_MSAA_LAYOUT_NONE);
+ true, 0 /* num_samples */);
if (!mt)
return mt;
{
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) {
- /* Adjust width/height/depth for MSAA */
- msaa_layout = compute_msaa_layout(intel, format);
- if (msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
- /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
- *
- * "Any of the other messages (sample*, LOD, load4) used with a
- * (4x) multisampled surface will in-effect sample a surface with
- * double the height and width as that indicated in the surface
- * state. Each pixel position on the original-sized surface is
- * replaced with a 2x2 of samples with the following arrangement:
- *
- * sample 0 sample 2
- * sample 1 sample 3"
- *
- * Thus, when sampling from a multisampled texture, it behaves as
- * though the layout in memory for (x,y,sample) is:
- *
- * (0,0,0) (0,0,2) (1,0,0) (1,0,2)
- * (0,0,1) (0,0,3) (1,0,1) (1,0,3)
- *
- * (0,1,0) (0,1,2) (1,1,0) (1,1,2)
- * (0,1,1) (0,1,3) (1,1,1) (1,1,3)
- *
- * However, the actual layout of multisampled data in memory is:
- *
- * (0,0,0) (1,0,0) (0,0,1) (1,0,1)
- * (0,1,0) (1,1,0) (0,1,1) (1,1,1)
- *
- * (0,0,2) (1,0,2) (0,0,3) (1,0,3)
- * (0,1,2) (1,1,2) (0,1,3) (1,1,3)
- *
- * This pattern repeats for each 2x2 pixel block.
- *
- * As a result, when calculating the size of our 4-sample buffer for
- * an odd width or height, we have to align before scaling up because
- * sample 3 is in that bottom right 2x2 block.
- */
- switch (num_samples) {
- case 4:
- width = ALIGN(width, 2) * 2;
- height = ALIGN(height, 2) * 2;
- break;
- case 8:
- width = ALIGN(width, 2) * 4;
- height = ALIGN(height, 2) * 2;
- break;
- default:
- /* num_samples should already have been quantized to 0, 1, 4, or
- * 8.
- */
- assert(false);
- }
- } else {
- /* Non-interleaved */
- depth = num_samples;
- }
- }
-
mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0,
width, height, depth, true, num_samples,
- msaa_layout, false /* force_y_tiling */);
+ false /* force_y_tiling */);
if (!mt)
goto fail;
goto fail;
}
- mt->singlesample_width0 = singlesample_width;
- mt->singlesample_height0 = singlesample_height;
-
return mt;
fail:
format,
mt->first_level,
mt->last_level,
- mt->width0,
- mt->height0,
- mt->depth0,
+ mt->logical_width0,
+ mt->logical_height0,
+ mt->logical_depth0,
true,
0 /* num_samples */,
- INTEL_MSAA_LAYOUT_NONE,
true /* force_y_tiling */);
/* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
GLuint num_samples)
{
assert(mt->hiz_mt == NULL);
- /* MSAA HiZ surfaces always use IMS layout. */
mt->hiz_mt = intel_miptree_create(intel,
mt->target,
mt->format,
mt->first_level,
mt->last_level,
- mt->width0,
- mt->height0,
- mt->depth0,
+ mt->logical_width0,
+ mt->logical_height0,
+ mt->logical_depth0,
true,
num_samples,
- INTEL_MSAA_LAYOUT_IMS,
false /* force_y_tiling */);
if (!mt->hiz_mt)
return;
intel_miptree_updownsample(intel,
mt, mt->singlesample_mt,
- mt->singlesample_mt->width0,
- mt->singlesample_mt->height0);
+ mt->logical_width0,
+ mt->logical_height0);
mt->need_downsample = false;
/* Strictly speaking, after a downsample on a depth miptree, a hiz
intel_miptree_updownsample(intel,
mt->singlesample_mt, mt,
- mt->singlesample_mt->width0,
- mt->singlesample_mt->height0);
+ mt->logical_width0,
+ mt->logical_height0);
intel_miptree_slice_set_needs_hiz_resolve(mt, 0, 0);
}
mt->singlesample_mt =
intel_miptree_create_for_renderbuffer(intel,
mt->format,
- mt->singlesample_width0,
- mt->singlesample_height0,
+ mt->logical_width0,
+ mt->logical_height0,
0 /*num_samples*/);
if (!mt->singlesample_mt)
goto fail;