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) {
goto fail;
}
+ mt->singlesample_width0 = singlesample_width;
+ mt->singlesample_height0 = singlesample_height;
+
return mt;
fail:
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,
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
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);
}
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;
};
/**
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